diff options
| author | John W. Linville <linville@tuxdriver.com> | 2013-04-24 10:54:20 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2013-04-24 10:54:20 -0400 |
| commit | 6ed0e321a0aef14a894e26658108bf7e895c36a6 (patch) | |
| tree | f49428d68ebcb1beb757296ea1559079210babbe | |
| parent | 3dec2246c2ff11beb24ca1950f074b2bcbc85953 (diff) | |
| parent | b006ed545cbadf1ebd4683719554742d20dbcede (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
257 files changed, 9897 insertions, 5629 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 6aab00ef4379..11f467c00d0a 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
| @@ -90,6 +90,7 @@ static struct usb_device_id ath3k_table[] = { | |||
| 90 | { USB_DEVICE(0x13d3, 0x3393) }, | 90 | { USB_DEVICE(0x13d3, 0x3393) }, |
| 91 | { USB_DEVICE(0x0489, 0xe04e) }, | 91 | { USB_DEVICE(0x0489, 0xe04e) }, |
| 92 | { USB_DEVICE(0x0489, 0xe056) }, | 92 | { USB_DEVICE(0x0489, 0xe056) }, |
| 93 | { USB_DEVICE(0x0489, 0xe04d) }, | ||
| 93 | 94 | ||
| 94 | /* Atheros AR5BBU12 with sflash firmware */ | 95 | /* Atheros AR5BBU12 with sflash firmware */ |
| 95 | { USB_DEVICE(0x0489, 0xE02C) }, | 96 | { USB_DEVICE(0x0489, 0xE02C) }, |
| @@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
| 126 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | 127 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, |
| 127 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | 128 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, |
| 128 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | 129 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, |
| 130 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, | ||
| 129 | 131 | ||
| 130 | /* Atheros AR5BBU22 with sflash firmware */ | 132 | /* Atheros AR5BBU22 with sflash firmware */ |
| 131 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 133 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2cc5f774a29c..3d684d20b584 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -148,6 +148,7 @@ static struct usb_device_id blacklist_table[] = { | |||
| 148 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | 148 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, |
| 149 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | 149 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, |
| 150 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | 150 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, |
| 151 | { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, | ||
| 151 | 152 | ||
| 152 | /* Atheros AR5BBU12 with sflash firmware */ | 153 | /* Atheros AR5BBU12 with sflash firmware */ |
| 153 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 154 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
| @@ -926,6 +927,22 @@ static void btusb_waker(struct work_struct *work) | |||
| 926 | usb_autopm_put_interface(data->intf); | 927 | usb_autopm_put_interface(data->intf); |
| 927 | } | 928 | } |
| 928 | 929 | ||
| 930 | static int btusb_setup_bcm92035(struct hci_dev *hdev) | ||
| 931 | { | ||
| 932 | struct sk_buff *skb; | ||
| 933 | u8 val = 0x00; | ||
| 934 | |||
| 935 | BT_DBG("%s", hdev->name); | ||
| 936 | |||
| 937 | skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT); | ||
| 938 | if (IS_ERR(skb)) | ||
| 939 | BT_ERR("BCM92035 command failed (%ld)", -PTR_ERR(skb)); | ||
| 940 | else | ||
| 941 | kfree_skb(skb); | ||
| 942 | |||
| 943 | return 0; | ||
| 944 | } | ||
| 945 | |||
| 929 | static int btusb_probe(struct usb_interface *intf, | 946 | static int btusb_probe(struct usb_interface *intf, |
| 930 | const struct usb_device_id *id) | 947 | const struct usb_device_id *id) |
| 931 | { | 948 | { |
| @@ -1022,11 +1039,14 @@ static int btusb_probe(struct usb_interface *intf, | |||
| 1022 | 1039 | ||
| 1023 | SET_HCIDEV_DEV(hdev, &intf->dev); | 1040 | SET_HCIDEV_DEV(hdev, &intf->dev); |
| 1024 | 1041 | ||
| 1025 | hdev->open = btusb_open; | 1042 | hdev->open = btusb_open; |
| 1026 | hdev->close = btusb_close; | 1043 | hdev->close = btusb_close; |
| 1027 | hdev->flush = btusb_flush; | 1044 | hdev->flush = btusb_flush; |
| 1028 | hdev->send = btusb_send_frame; | 1045 | hdev->send = btusb_send_frame; |
| 1029 | hdev->notify = btusb_notify; | 1046 | hdev->notify = btusb_notify; |
| 1047 | |||
| 1048 | if (id->driver_info & BTUSB_BCM92035) | ||
| 1049 | hdev->setup = btusb_setup_bcm92035; | ||
| 1030 | 1050 | ||
| 1031 | /* Interface numbers are hardcoded in the specification */ | 1051 | /* Interface numbers are hardcoded in the specification */ |
| 1032 | data->isoc = usb_ifnum_to_if(data->udev, 1); | 1052 | data->isoc = usb_ifnum_to_if(data->udev, 1); |
| @@ -1065,17 +1085,6 @@ static int btusb_probe(struct usb_interface *intf, | |||
| 1065 | data->isoc = NULL; | 1085 | data->isoc = NULL; |
| 1066 | } | 1086 | } |
| 1067 | 1087 | ||
| 1068 | if (id->driver_info & BTUSB_BCM92035) { | ||
| 1069 | unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 }; | ||
| 1070 | struct sk_buff *skb; | ||
| 1071 | |||
| 1072 | skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); | ||
| 1073 | if (skb) { | ||
| 1074 | memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd)); | ||
| 1075 | skb_queue_tail(&hdev->driver_init, skb); | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | if (data->isoc) { | 1088 | if (data->isoc) { |
| 1080 | err = usb_driver_claim_interface(&btusb_driver, | 1089 | err = usb_driver_claim_interface(&btusb_driver, |
| 1081 | data->isoc, data); | 1090 | data->isoc, data); |
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index c60623f206d4..8ae9f1ea2bb5 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c | |||
| @@ -153,6 +153,9 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) | |||
| 153 | { | 153 | { |
| 154 | int ret; | 154 | int ret; |
| 155 | 155 | ||
| 156 | if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) | ||
| 157 | return -EUNATCH; | ||
| 158 | |||
| 156 | ret = hci_recv_stream_fragment(hu->hdev, data, count); | 159 | ret = hci_recv_stream_fragment(hu->hdev, data, count); |
| 157 | if (ret < 0) { | 160 | if (ret < 0) { |
| 158 | BT_ERR("Frame Reassembly Failed"); | 161 | BT_ERR("Frame Reassembly Failed"); |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index ed0fade46aed..bc68a440d432 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
| @@ -260,12 +260,12 @@ static int hci_uart_send_frame(struct sk_buff *skb) | |||
| 260 | 260 | ||
| 261 | /* ------ LDISC part ------ */ | 261 | /* ------ LDISC part ------ */ |
| 262 | /* hci_uart_tty_open | 262 | /* hci_uart_tty_open |
| 263 | * | 263 | * |
| 264 | * Called when line discipline changed to HCI_UART. | 264 | * Called when line discipline changed to HCI_UART. |
| 265 | * | 265 | * |
| 266 | * Arguments: | 266 | * Arguments: |
| 267 | * tty pointer to tty info structure | 267 | * tty pointer to tty info structure |
| 268 | * Return Value: | 268 | * Return Value: |
| 269 | * 0 if success, otherwise error code | 269 | * 0 if success, otherwise error code |
| 270 | */ | 270 | */ |
| 271 | static int hci_uart_tty_open(struct tty_struct *tty) | 271 | static int hci_uart_tty_open(struct tty_struct *tty) |
| @@ -365,15 +365,15 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | /* hci_uart_tty_receive() | 367 | /* hci_uart_tty_receive() |
| 368 | * | 368 | * |
| 369 | * Called by tty low level driver when receive data is | 369 | * Called by tty low level driver when receive data is |
| 370 | * available. | 370 | * available. |
| 371 | * | 371 | * |
| 372 | * Arguments: tty pointer to tty isntance data | 372 | * Arguments: tty pointer to tty isntance data |
| 373 | * data pointer to received data | 373 | * data pointer to received data |
| 374 | * flags pointer to flags for data | 374 | * flags pointer to flags for data |
| 375 | * count count of received data in bytes | 375 | * count count of received data in bytes |
| 376 | * | 376 | * |
| 377 | * Return Value: None | 377 | * Return Value: None |
| 378 | */ | 378 | */ |
| 379 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) | 379 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) |
| @@ -388,7 +388,10 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f | |||
| 388 | 388 | ||
| 389 | spin_lock(&hu->rx_lock); | 389 | spin_lock(&hu->rx_lock); |
| 390 | hu->proto->recv(hu, (void *) data, count); | 390 | hu->proto->recv(hu, (void *) data, count); |
| 391 | hu->hdev->stat.byte_rx += count; | 391 | |
| 392 | if (hu->hdev) | ||
| 393 | hu->hdev->stat.byte_rx += count; | ||
| 394 | |||
| 392 | spin_unlock(&hu->rx_lock); | 395 | spin_unlock(&hu->rx_lock); |
| 393 | 396 | ||
| 394 | tty_unthrottle(tty); | 397 | tty_unthrottle(tty); |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 3d339e04efb7..f9a24e599dee 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
| @@ -1293,7 +1293,8 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed) | |||
| 1293 | { | 1293 | { |
| 1294 | struct adm8211_priv *priv = dev->priv; | 1294 | struct adm8211_priv *priv = dev->priv; |
| 1295 | struct ieee80211_conf *conf = &dev->conf; | 1295 | struct ieee80211_conf *conf = &dev->conf; |
| 1296 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 1296 | int channel = |
| 1297 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
| 1297 | 1298 | ||
| 1298 | if (channel != priv->channel) { | 1299 | if (channel != priv->channel) { |
| 1299 | priv->channel = channel; | 1300 | priv->channel = channel; |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 5ac5f7ae2721..34c8a33cac06 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
| @@ -1943,12 +1943,12 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1943 | struct at76_priv *priv = hw->priv; | 1943 | struct at76_priv *priv = hw->priv; |
| 1944 | 1944 | ||
| 1945 | at76_dbg(DBG_MAC80211, "%s(): channel %d", | 1945 | at76_dbg(DBG_MAC80211, "%s(): channel %d", |
| 1946 | __func__, hw->conf.channel->hw_value); | 1946 | __func__, hw->conf.chandef.chan->hw_value); |
| 1947 | at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); | 1947 | at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); |
| 1948 | 1948 | ||
| 1949 | mutex_lock(&priv->mtx); | 1949 | mutex_lock(&priv->mtx); |
| 1950 | 1950 | ||
| 1951 | priv->channel = hw->conf.channel->hw_value; | 1951 | priv->channel = hw->conf.chandef.chan->hw_value; |
| 1952 | 1952 | ||
| 1953 | if (is_valid_ether_addr(priv->bssid)) | 1953 | if (is_valid_ether_addr(priv->bssid)) |
| 1954 | at76_join(priv); | 1954 | at76_join(priv); |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index afd1e36d308f..17d7fece35d2 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
| @@ -457,14 +457,14 @@ static int ar5523_set_chan(struct ar5523 *ar) | |||
| 457 | memset(&reset, 0, sizeof(reset)); | 457 | memset(&reset, 0, sizeof(reset)); |
| 458 | reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); | 458 | reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); |
| 459 | reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); | 459 | reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); |
| 460 | reset.freq = cpu_to_be32(conf->channel->center_freq); | 460 | reset.freq = cpu_to_be32(conf->chandef.chan->center_freq); |
| 461 | reset.maxrdpower = cpu_to_be32(50); /* XXX */ | 461 | reset.maxrdpower = cpu_to_be32(50); /* XXX */ |
| 462 | reset.channelchange = cpu_to_be32(1); | 462 | reset.channelchange = cpu_to_be32(1); |
| 463 | reset.keeprccontent = cpu_to_be32(0); | 463 | reset.keeprccontent = cpu_to_be32(0); |
| 464 | 464 | ||
| 465 | ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", | 465 | ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", |
| 466 | be32_to_cpu(reset.flags), | 466 | be32_to_cpu(reset.flags), |
| 467 | conf->channel->center_freq); | 467 | conf->chandef.chan->center_freq); |
| 468 | return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0); | 468 | return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| @@ -594,7 +594,7 @@ static void ar5523_data_rx_cb(struct urb *urb) | |||
| 594 | rx_status = IEEE80211_SKB_RXCB(data->skb); | 594 | rx_status = IEEE80211_SKB_RXCB(data->skb); |
| 595 | memset(rx_status, 0, sizeof(*rx_status)); | 595 | memset(rx_status, 0, sizeof(*rx_status)); |
| 596 | rx_status->freq = be32_to_cpu(desc->channel); | 596 | rx_status->freq = be32_to_cpu(desc->channel); |
| 597 | rx_status->band = hw->conf.channel->band; | 597 | rx_status->band = hw->conf.chandef.chan->band; |
| 598 | rx_status->signal = -95 + be32_to_cpu(desc->rssi); | 598 | rx_status->signal = -95 + be32_to_cpu(desc->rssi); |
| 599 | 599 | ||
| 600 | ieee80211_rx_irqsafe(hw, data->skb); | 600 | ieee80211_rx_irqsafe(hw, data->skb); |
| @@ -1153,13 +1153,13 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar, | |||
| 1153 | struct ieee80211_sta *sta; | 1153 | struct ieee80211_sta *sta; |
| 1154 | u32 sta_rate_set; | 1154 | u32 sta_rate_set; |
| 1155 | 1155 | ||
| 1156 | band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; | 1156 | band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; |
| 1157 | sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); | 1157 | sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); |
| 1158 | if (!sta) { | 1158 | if (!sta) { |
| 1159 | ar5523_info(ar, "STA not found!\n"); | 1159 | ar5523_info(ar, "STA not found!\n"); |
| 1160 | return WLAN_MODE_11b; | 1160 | return WLAN_MODE_11b; |
| 1161 | } | 1161 | } |
| 1162 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; | 1162 | sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; |
| 1163 | 1163 | ||
| 1164 | for (bit = 0; bit < band->n_bitrates; bit++) { | 1164 | for (bit = 0; bit < band->n_bitrates; bit++) { |
| 1165 | if (sta_rate_set & 1) { | 1165 | if (sta_rate_set & 1) { |
| @@ -1197,11 +1197,11 @@ static void ar5523_create_rateset(struct ar5523 *ar, | |||
| 1197 | ar5523_info(ar, "STA not found. Cannot set rates\n"); | 1197 | ar5523_info(ar, "STA not found. Cannot set rates\n"); |
| 1198 | sta_rate_set = bss_conf->basic_rates; | 1198 | sta_rate_set = bss_conf->basic_rates; |
| 1199 | } else | 1199 | } else |
| 1200 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; | 1200 | sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; |
| 1201 | 1201 | ||
| 1202 | ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); | 1202 | ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); |
| 1203 | 1203 | ||
| 1204 | band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; | 1204 | band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; |
| 1205 | for (bit = 0; bit < band->n_bitrates; bit++) { | 1205 | for (bit = 0; bit < band->n_bitrates; bit++) { |
| 1206 | BUG_ON(i >= AR5523_MAX_NRATES); | 1206 | BUG_ON(i >= AR5523_MAX_NRATES); |
| 1207 | ar5523_dbg(ar, "Considering rate %d : %d\n", | 1207 | ar5523_dbg(ar, "Considering rate %d : %d\n", |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index f60b3899afc4..1b3a34f7f224 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
| @@ -10,6 +10,7 @@ ath5k-y += phy.o | |||
| 10 | ath5k-y += reset.o | 10 | ath5k-y += reset.o |
| 11 | ath5k-y += attach.o | 11 | ath5k-y += attach.o |
| 12 | ath5k-y += base.o | 12 | ath5k-y += base.o |
| 13 | CFLAGS_base.o += -I$(src) | ||
| 13 | ath5k-y += led.o | 14 | ath5k-y += led.o |
| 14 | ath5k-y += rfkill.o | 15 | ath5k-y += rfkill.o |
| 15 | ath5k-y += ani.o | 16 | ath5k-y += ani.o |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1d264c0f5a9b..9b20d9ee2719 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -2639,7 +2639,7 @@ int ath5k_start(struct ieee80211_hw *hw) | |||
| 2639 | * be followed by initialization of the appropriate bits | 2639 | * be followed by initialization of the appropriate bits |
| 2640 | * and then setup of the interrupt mask. | 2640 | * and then setup of the interrupt mask. |
| 2641 | */ | 2641 | */ |
| 2642 | ah->curchan = ah->hw->conf.channel; | 2642 | ah->curchan = ah->hw->conf.chandef.chan; |
| 2643 | ah->imask = AR5K_INT_RXOK | 2643 | ah->imask = AR5K_INT_RXOK |
| 2644 | | AR5K_INT_RXERR | 2644 | | AR5K_INT_RXERR |
| 2645 | | AR5K_INT_RXEOL | 2645 | | AR5K_INT_RXEOL |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 4264341533ea..06f86f435711 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
| @@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 202 | mutex_lock(&ah->lock); | 202 | mutex_lock(&ah->lock); |
| 203 | 203 | ||
| 204 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 204 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 205 | ret = ath5k_chan_set(ah, conf->channel); | 205 | ret = ath5k_chan_set(ah, conf->chandef.chan); |
| 206 | if (ret < 0) | 206 | if (ret < 0) |
| 207 | goto unlock; | 207 | goto unlock; |
| 208 | } | 208 | } |
| @@ -678,7 +678,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) | |||
| 678 | 678 | ||
| 679 | memcpy(survey, &ah->survey, sizeof(*survey)); | 679 | memcpy(survey, &ah->survey, sizeof(*survey)); |
| 680 | 680 | ||
| 681 | survey->channel = conf->channel; | 681 | survey->channel = conf->chandef.chan; |
| 682 | survey->noise = ah->ah_noise_floor; | 682 | survey->noise = ah->ah_noise_floor; |
| 683 | survey->filled = SURVEY_INFO_NOISE_DBM | | 683 | survey->filled = SURVEY_INFO_NOISE_DBM | |
| 684 | SURVEY_INFO_CHANNEL_TIME | | 684 | SURVEY_INFO_CHANNEL_TIME | |
diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h index 00f015819344..c6eef519bb61 100644 --- a/drivers/net/wireless/ath/ath5k/trace.h +++ b/drivers/net/wireless/ath/ath5k/trace.h | |||
| @@ -97,7 +97,7 @@ TRACE_EVENT(ath5k_tx_complete, | |||
| 97 | #if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) | 97 | #if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) |
| 98 | 98 | ||
| 99 | #undef TRACE_INCLUDE_PATH | 99 | #undef TRACE_INCLUDE_PATH |
| 100 | #define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k | 100 | #define TRACE_INCLUDE_PATH . |
| 101 | #undef TRACE_INCLUDE_FILE | 101 | #undef TRACE_INCLUDE_FILE |
| 102 | #define TRACE_INCLUDE_FILE trace | 102 | #define TRACE_INCLUDE_FILE trace |
| 103 | 103 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index fd69376ecc83..391da5ad6a99 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "hw-ops.h" | 18 | #include "hw-ops.h" |
| 19 | #include "../regd.h" | 19 | #include "../regd.h" |
| 20 | #include "ar9002_phy.h" | 20 | #include "ar9002_phy.h" |
| 21 | #include "ar5008_initvals.h" | ||
| 21 | 22 | ||
| 22 | /* All code below is for AR5008, AR9001, AR9002 */ | 23 | /* All code below is for AR5008, AR9001, AR9002 */ |
| 23 | 24 | ||
| @@ -43,23 +44,16 @@ static const int m2ThreshLowExt_off = 127; | |||
| 43 | static const int m1ThreshExt_off = 127; | 44 | static const int m1ThreshExt_off = 127; |
| 44 | static const int m2ThreshExt_off = 127; | 45 | static const int m2ThreshExt_off = 127; |
| 45 | 46 | ||
| 47 | static const struct ar5416IniArray bank0 = STATIC_INI_ARRAY(ar5416Bank0); | ||
| 48 | static const struct ar5416IniArray bank1 = STATIC_INI_ARRAY(ar5416Bank1); | ||
| 49 | static const struct ar5416IniArray bank2 = STATIC_INI_ARRAY(ar5416Bank2); | ||
| 50 | static const struct ar5416IniArray bank3 = STATIC_INI_ARRAY(ar5416Bank3); | ||
| 51 | static const struct ar5416IniArray bank7 = STATIC_INI_ARRAY(ar5416Bank7); | ||
| 46 | 52 | ||
| 47 | static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array, | 53 | static void ar5008_write_bank6(struct ath_hw *ah, unsigned int *writecnt) |
| 48 | int col) | ||
| 49 | { | ||
| 50 | int i; | ||
| 51 | |||
| 52 | for (i = 0; i < array->ia_rows; i++) | ||
| 53 | bank[i] = INI_RA(array, i, col); | ||
| 54 | } | ||
| 55 | |||
| 56 | |||
| 57 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \ | ||
| 58 | ar5008_write_rf_array(ah, iniarray, regData, &(regWr)) | ||
| 59 | |||
| 60 | static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array, | ||
| 61 | u32 *data, unsigned int *writecnt) | ||
| 62 | { | 54 | { |
| 55 | struct ar5416IniArray *array = &ah->iniBank6; | ||
| 56 | u32 *data = ah->analogBank6Data; | ||
| 63 | int r; | 57 | int r; |
| 64 | 58 | ||
| 65 | ENABLE_REGWRITE_BUFFER(ah); | 59 | ENABLE_REGWRITE_BUFFER(ah); |
| @@ -165,7 +159,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | |||
| 165 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); | 159 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); |
| 166 | 160 | ||
| 167 | /* write Bank 6 with new params */ | 161 | /* write Bank 6 with new params */ |
| 168 | REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); | 162 | ar5008_write_bank6(ah, ®_writes); |
| 169 | } | 163 | } |
| 170 | 164 | ||
| 171 | /** | 165 | /** |
| @@ -469,31 +463,16 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, | |||
| 469 | */ | 463 | */ |
| 470 | static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) | 464 | static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) |
| 471 | { | 465 | { |
| 472 | #define ATH_ALLOC_BANK(bank, size) do { \ | 466 | int size = ah->iniBank6.ia_rows * sizeof(u32); |
| 473 | bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \ | ||
| 474 | if (!bank) \ | ||
| 475 | goto error; \ | ||
| 476 | } while (0); | ||
| 477 | |||
| 478 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 479 | 467 | ||
| 480 | if (AR_SREV_9280_20_OR_LATER(ah)) | 468 | if (AR_SREV_9280_20_OR_LATER(ah)) |
| 481 | return 0; | 469 | return 0; |
| 482 | 470 | ||
| 483 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); | 471 | ah->analogBank6Data = devm_kzalloc(ah->dev, size, GFP_KERNEL); |
| 484 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); | 472 | if (!ah->analogBank6Data) |
| 485 | ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); | 473 | return -ENOMEM; |
| 486 | ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); | ||
| 487 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); | ||
| 488 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); | ||
| 489 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); | ||
| 490 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); | ||
| 491 | 474 | ||
| 492 | return 0; | 475 | return 0; |
| 493 | #undef ATH_ALLOC_BANK | ||
| 494 | error: | ||
| 495 | ath_err(common, "Cannot allocate RF banks\n"); | ||
| 496 | return -ENOMEM; | ||
| 497 | } | 476 | } |
| 498 | 477 | ||
| 499 | 478 | ||
| @@ -517,6 +496,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | |||
| 517 | u32 ob5GHz = 0, db5GHz = 0; | 496 | u32 ob5GHz = 0, db5GHz = 0; |
| 518 | u32 ob2GHz = 0, db2GHz = 0; | 497 | u32 ob2GHz = 0, db2GHz = 0; |
| 519 | int regWrites = 0; | 498 | int regWrites = 0; |
| 499 | int i; | ||
| 520 | 500 | ||
| 521 | /* | 501 | /* |
| 522 | * Software does not need to program bank data | 502 | * Software does not need to program bank data |
| @@ -529,25 +509,8 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | |||
| 529 | /* Setup rf parameters */ | 509 | /* Setup rf parameters */ |
| 530 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | 510 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); |
| 531 | 511 | ||
| 532 | /* Setup Bank 0 Write */ | 512 | for (i = 0; i < ah->iniBank6.ia_rows; i++) |
| 533 | ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1); | 513 | ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex); |
| 534 | |||
| 535 | /* Setup Bank 1 Write */ | ||
| 536 | ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1); | ||
| 537 | |||
| 538 | /* Setup Bank 2 Write */ | ||
| 539 | ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1); | ||
| 540 | |||
| 541 | /* Setup Bank 6 Write */ | ||
| 542 | ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3, | ||
| 543 | modesIndex); | ||
| 544 | { | ||
| 545 | int i; | ||
| 546 | for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { | ||
| 547 | ah->analogBank6Data[i] = | ||
| 548 | INI_RA(&ah->iniBank6TPC, i, modesIndex); | ||
| 549 | } | ||
| 550 | } | ||
| 551 | 514 | ||
| 552 | /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ | 515 | /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ |
| 553 | if (eepMinorRev >= 2) { | 516 | if (eepMinorRev >= 2) { |
| @@ -568,22 +531,13 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | |||
| 568 | } | 531 | } |
| 569 | } | 532 | } |
| 570 | 533 | ||
| 571 | /* Setup Bank 7 Setup */ | ||
| 572 | ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1); | ||
| 573 | |||
| 574 | /* Write Analog registers */ | 534 | /* Write Analog registers */ |
| 575 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | 535 | REG_WRITE_ARRAY(&bank0, 1, regWrites); |
| 576 | regWrites); | 536 | REG_WRITE_ARRAY(&bank1, 1, regWrites); |
| 577 | REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, | 537 | REG_WRITE_ARRAY(&bank2, 1, regWrites); |
| 578 | regWrites); | 538 | REG_WRITE_ARRAY(&bank3, modesIndex, regWrites); |
| 579 | REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, | 539 | ar5008_write_bank6(ah, ®Writes); |
| 580 | regWrites); | 540 | REG_WRITE_ARRAY(&bank7, 1, regWrites); |
| 581 | REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, | ||
| 582 | regWrites); | ||
| 583 | REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, | ||
| 584 | regWrites); | ||
| 585 | REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, | ||
| 586 | regWrites); | ||
| 587 | 541 | ||
| 588 | return true; | 542 | return true; |
| 589 | } | 543 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f053d978540e..830daa12feb6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
| @@ -67,12 +67,10 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
| 67 | } else if (AR_SREV_9100_OR_LATER(ah)) { | 67 | } else if (AR_SREV_9100_OR_LATER(ah)) { |
| 68 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100); | 68 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100); |
| 69 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100); | 69 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100); |
| 70 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100); | ||
| 71 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100); | 70 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100); |
| 72 | } else { | 71 | } else { |
| 73 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes); | 72 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes); |
| 74 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common); | 73 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common); |
| 75 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC); | ||
| 76 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac); | 74 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac); |
| 77 | } | 75 | } |
| 78 | 76 | ||
| @@ -80,20 +78,11 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
| 80 | /* Common for AR5416, AR913x, AR9160 */ | 78 | /* Common for AR5416, AR913x, AR9160 */ |
| 81 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain); | 79 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain); |
| 82 | 80 | ||
| 83 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0); | ||
| 84 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1); | ||
| 85 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2); | ||
| 86 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3); | ||
| 87 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7); | ||
| 88 | |||
| 89 | /* Common for AR5416, AR9160 */ | ||
| 90 | if (!AR_SREV_9100(ah)) | ||
| 91 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6); | ||
| 92 | |||
| 93 | /* Common for AR913x, AR9160 */ | 81 | /* Common for AR913x, AR9160 */ |
| 94 | if (!AR_SREV_5416(ah)) | 82 | if (!AR_SREV_5416(ah)) |
| 95 | INIT_INI_ARRAY(&ah->iniBank6TPC, | 83 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC_9100); |
| 96 | ar5416Bank6TPC_9100); | 84 | else |
| 85 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC); | ||
| 97 | } | 86 | } |
| 98 | 87 | ||
| 99 | /* iniAddac needs to be modified for these chips */ | 88 | /* iniAddac needs to be modified for these chips */ |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a56b2416e2f9..8a1888d02070 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -234,6 +234,7 @@ struct ath_buf { | |||
| 234 | dma_addr_t bf_daddr; /* physical addr of desc */ | 234 | dma_addr_t bf_daddr; /* physical addr of desc */ |
| 235 | dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ | 235 | dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ |
| 236 | bool bf_stale; | 236 | bool bf_stale; |
| 237 | struct ieee80211_tx_rate rates[4]; | ||
| 237 | struct ath_buf_state bf_state; | 238 | struct ath_buf_state bf_state; |
| 238 | }; | 239 | }; |
| 239 | 240 | ||
| @@ -311,6 +312,7 @@ struct ath_rx_edma { | |||
| 311 | struct ath_rx { | 312 | struct ath_rx { |
| 312 | u8 defant; | 313 | u8 defant; |
| 313 | u8 rxotherant; | 314 | u8 rxotherant; |
| 315 | bool discard_next; | ||
| 314 | u32 *rxlink; | 316 | u32 *rxlink; |
| 315 | u32 num_pkts; | 317 | u32 num_pkts; |
| 316 | unsigned int rxfilter; | 318 | unsigned int rxfilter; |
| @@ -657,11 +659,10 @@ enum sc_op_flags { | |||
| 657 | struct ath_rate_table; | 659 | struct ath_rate_table; |
| 658 | 660 | ||
| 659 | struct ath9k_vif_iter_data { | 661 | struct ath9k_vif_iter_data { |
| 660 | const u8 *hw_macaddr; /* phy's hardware address, set | 662 | u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */ |
| 661 | * before starting iteration for | ||
| 662 | * valid bssid mask. | ||
| 663 | */ | ||
| 664 | u8 mask[ETH_ALEN]; /* bssid mask */ | 663 | u8 mask[ETH_ALEN]; /* bssid mask */ |
| 664 | bool has_hw_macaddr; | ||
| 665 | |||
| 665 | int naps; /* number of AP vifs */ | 666 | int naps; /* number of AP vifs */ |
| 666 | int nmeshes; /* number of mesh vifs */ | 667 | int nmeshes; /* number of mesh vifs */ |
| 667 | int nstations; /* number of station vifs */ | 668 | int nstations; /* number of station vifs */ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 5f05c26d1ec4..2ff570f7f8ff 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
| @@ -79,7 +79,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
| 79 | u8 chainmask = ah->txchainmask; | 79 | u8 chainmask = ah->txchainmask; |
| 80 | u8 rate = 0; | 80 | u8 rate = 0; |
| 81 | 81 | ||
| 82 | sband = &sc->sbands[common->hw->conf.channel->band]; | 82 | sband = &sc->sbands[common->hw->conf.chandef.chan->band]; |
| 83 | rate = sband->bitrates[rateidx].hw_value; | 83 | rate = sband->bitrates[rateidx].hw_value; |
| 84 | if (vif->bss_conf.use_short_preamble) | 84 | if (vif->bss_conf.use_short_preamble) |
| 85 | rate |= sband->bitrates[rateidx].hw_value_short; | 85 | rate |= sband->bitrates[rateidx].hw_value_short; |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 7bdd726c7a8f..7304e7585009 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
| @@ -208,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
| 208 | return true; | 208 | return true; |
| 209 | 209 | ||
| 210 | ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", | 210 | ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", |
| 211 | currCal->calData->calType, conf->channel->center_freq); | 211 | currCal->calData->calType, conf->chandef.chan->center_freq); |
| 212 | 212 | ||
| 213 | ah->caldata->CalValid &= ~currCal->calData->calType; | 213 | ah->caldata->CalValid &= ~currCal->calData->calType; |
| 214 | currCal->calState = CAL_WAITING; | 214 | currCal->calState = CAL_WAITING; |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 60dcb6c22db9..3d70b8c2bcdd 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
| @@ -33,6 +33,12 @@ struct ar5416IniArray { | |||
| 33 | u32 ia_columns; | 33 | u32 ia_columns; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | #define STATIC_INI_ARRAY(array) { \ | ||
| 37 | .ia_array = (u32 *)(array), \ | ||
| 38 | .ia_rows = ARRAY_SIZE(array), \ | ||
| 39 | .ia_columns = ARRAY_SIZE(array[0]), \ | ||
| 40 | } | ||
| 41 | |||
| 36 | #define INIT_INI_ARRAY(iniarray, array) do { \ | 42 | #define INIT_INI_ARRAY(iniarray, array) do { \ |
| 37 | (iniarray)->ia_array = (u32 *)(array); \ | 43 | (iniarray)->ia_array = (u32 *)(array); \ |
| 38 | (iniarray)->ia_rows = ARRAY_SIZE(array); \ | 44 | (iniarray)->ia_rows = ARRAY_SIZE(array); \ |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 905f1b313961..344fdde1d7a3 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
| @@ -27,20 +27,6 @@ MODULE_AUTHOR("Atheros Communications"); | |||
| 27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); | 27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); |
| 28 | MODULE_LICENSE("Dual BSD/GPL"); | 28 | MODULE_LICENSE("Dual BSD/GPL"); |
| 29 | 29 | ||
| 30 | int ath9k_cmn_padpos(__le16 frame_control) | ||
| 31 | { | ||
| 32 | int padpos = 24; | ||
| 33 | if (ieee80211_has_a4(frame_control)) { | ||
| 34 | padpos += ETH_ALEN; | ||
| 35 | } | ||
| 36 | if (ieee80211_is_data_qos(frame_control)) { | ||
| 37 | padpos += IEEE80211_QOS_CTL_LEN; | ||
| 38 | } | ||
| 39 | |||
| 40 | return padpos; | ||
| 41 | } | ||
| 42 | EXPORT_SYMBOL(ath9k_cmn_padpos); | ||
| 43 | |||
| 44 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) | 30 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) |
| 45 | { | 31 | { |
| 46 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 32 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
| @@ -133,13 +119,14 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel); | |||
| 133 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, | 119 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, |
| 134 | struct ath_hw *ah) | 120 | struct ath_hw *ah) |
| 135 | { | 121 | { |
| 136 | struct ieee80211_channel *curchan = hw->conf.channel; | 122 | struct ieee80211_channel *curchan = hw->conf.chandef.chan; |
| 137 | struct ath9k_channel *channel; | 123 | struct ath9k_channel *channel; |
| 138 | u8 chan_idx; | 124 | u8 chan_idx; |
| 139 | 125 | ||
| 140 | chan_idx = curchan->hw_value; | 126 | chan_idx = curchan->hw_value; |
| 141 | channel = &ah->channels[chan_idx]; | 127 | channel = &ah->channels[chan_idx]; |
| 142 | ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); | 128 | ath9k_cmn_update_ichannel(channel, curchan, |
| 129 | cfg80211_get_chandef_type(&hw->conf.chandef)); | ||
| 143 | 130 | ||
| 144 | return channel; | 131 | return channel; |
| 145 | } | 132 | } |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 6102476a65de..207d06995b15 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
| @@ -42,7 +42,6 @@ | |||
| 42 | #define ATH_EP_RND(x, mul) \ | 42 | #define ATH_EP_RND(x, mul) \ |
| 43 | (((x) + ((mul)/2)) / (mul)) | 43 | (((x) + ((mul)/2)) / (mul)) |
| 44 | 44 | ||
| 45 | int ath9k_cmn_padpos(__le16 frame_control); | ||
| 46 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | 45 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); |
| 47 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, | 46 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, |
| 48 | struct ieee80211_channel *chan, | 47 | struct ieee80211_channel *chan, |
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c index 508f8b33f0ef..7187d3671512 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.c +++ b/drivers/net/wireless/ath/ath9k/dfs.c | |||
| @@ -55,12 +55,6 @@ ath9k_postprocess_radar_event(struct ath_softc *sc, | |||
| 55 | u8 rssi; | 55 | u8 rssi; |
| 56 | u16 dur; | 56 | u16 dur; |
| 57 | 57 | ||
| 58 | ath_dbg(ath9k_hw_common(sc->sc_ah), DFS, | ||
| 59 | "pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n", | ||
| 60 | ard->pulse_bw_info, | ||
| 61 | ard->pulse_length_pri, ard->rssi, | ||
| 62 | ard->pulse_length_ext, ard->ext_rssi); | ||
| 63 | |||
| 64 | /* | 58 | /* |
| 65 | * Only the last 2 bits of the BW info are relevant, they indicate | 59 | * Only the last 2 bits of the BW info are relevant, they indicate |
| 66 | * which channel the radar was detected in. | 60 | * which channel the radar was detected in. |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 73fe8d6db566..491305c81fce 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include "dfs_pattern_detector.h" | 20 | #include "dfs_pattern_detector.h" |
| 21 | #include "dfs_pri_detector.h" | 21 | #include "dfs_pri_detector.h" |
| 22 | #include "ath9k.h" | ||
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| 24 | * tolerated deviation of radar time stamp in usecs on both sides | 25 | * tolerated deviation of radar time stamp in usecs on both sides |
| @@ -142,6 +143,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) | |||
| 142 | { | 143 | { |
| 143 | u32 sz, i; | 144 | u32 sz, i; |
| 144 | struct channel_detector *cd; | 145 | struct channel_detector *cd; |
| 146 | struct ath_common *common = ath9k_hw_common(dpd->ah); | ||
| 145 | 147 | ||
| 146 | cd = kmalloc(sizeof(*cd), GFP_ATOMIC); | 148 | cd = kmalloc(sizeof(*cd), GFP_ATOMIC); |
| 147 | if (cd == NULL) | 149 | if (cd == NULL) |
| @@ -165,7 +167,8 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) | |||
| 165 | return cd; | 167 | return cd; |
| 166 | 168 | ||
| 167 | fail: | 169 | fail: |
| 168 | pr_err("failed to allocate channel_detector for freq=%d\n", freq); | 170 | ath_dbg(common, DFS, |
| 171 | "failed to allocate channel_detector for freq=%d\n", freq); | ||
| 169 | channel_detector_exit(dpd, cd); | 172 | channel_detector_exit(dpd, cd); |
| 170 | return NULL; | 173 | return NULL; |
| 171 | } | 174 | } |
| @@ -216,34 +219,34 @@ static bool | |||
| 216 | dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) | 219 | dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) |
| 217 | { | 220 | { |
| 218 | u32 i; | 221 | u32 i; |
| 219 | bool ts_wraparound; | ||
| 220 | struct channel_detector *cd; | 222 | struct channel_detector *cd; |
| 221 | 223 | ||
| 222 | if (dpd->region == NL80211_DFS_UNSET) { | 224 | /* |
| 223 | /* | 225 | * pulses received for a non-supported or un-initialized |
| 224 | * pulses received for a non-supported or un-initialized | 226 | * domain are treated as detected radars for fail-safety |
| 225 | * domain are treated as detected radars | 227 | */ |
| 226 | */ | 228 | if (dpd->region == NL80211_DFS_UNSET) |
| 227 | return true; | 229 | return true; |
| 228 | } | ||
| 229 | 230 | ||
| 230 | cd = channel_detector_get(dpd, event->freq); | 231 | cd = channel_detector_get(dpd, event->freq); |
| 231 | if (cd == NULL) | 232 | if (cd == NULL) |
| 232 | return false; | 233 | return false; |
| 233 | 234 | ||
| 234 | ts_wraparound = (event->ts < dpd->last_pulse_ts); | ||
| 235 | dpd->last_pulse_ts = event->ts; | 235 | dpd->last_pulse_ts = event->ts; |
| 236 | if (ts_wraparound) { | 236 | /* reset detector on time stamp wraparound, caused by TSF reset */ |
| 237 | /* | 237 | if (event->ts < dpd->last_pulse_ts) |
| 238 | * reset detector on time stamp wraparound | ||
| 239 | * with monotonic time stamps, this should never happen | ||
| 240 | */ | ||
| 241 | pr_warn("DFS: time stamp wraparound detected, resetting\n"); | ||
| 242 | dpd_reset(dpd); | 238 | dpd_reset(dpd); |
| 243 | } | 239 | |
| 244 | /* do type individual pattern matching */ | 240 | /* do type individual pattern matching */ |
| 245 | for (i = 0; i < dpd->num_radar_types; i++) { | 241 | for (i = 0; i < dpd->num_radar_types; i++) { |
| 246 | if (cd->detectors[i]->add_pulse(cd->detectors[i], event) != 0) { | 242 | struct pri_detector *pd = cd->detectors[i]; |
| 243 | struct pri_sequence *ps = pd->add_pulse(pd, event); | ||
| 244 | if (ps != NULL) { | ||
| 245 | ath_dbg(ath9k_hw_common(dpd->ah), DFS, | ||
| 246 | "DFS: radar found on freq=%d: id=%d, pri=%d, " | ||
| 247 | "count=%d, count_false=%d\n", | ||
| 248 | event->freq, pd->rs->type_id, | ||
| 249 | ps->pri, ps->count, ps->count_falses); | ||
| 247 | channel_detector_reset(dpd, cd); | 250 | channel_detector_reset(dpd, cd); |
| 248 | return true; | 251 | return true; |
| 249 | } | 252 | } |
| @@ -285,9 +288,10 @@ static struct dfs_pattern_detector default_dpd = { | |||
| 285 | }; | 288 | }; |
| 286 | 289 | ||
| 287 | struct dfs_pattern_detector * | 290 | struct dfs_pattern_detector * |
| 288 | dfs_pattern_detector_init(enum nl80211_dfs_regions region) | 291 | dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) |
| 289 | { | 292 | { |
| 290 | struct dfs_pattern_detector *dpd; | 293 | struct dfs_pattern_detector *dpd; |
| 294 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 291 | 295 | ||
| 292 | dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); | 296 | dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); |
| 293 | if (dpd == NULL) | 297 | if (dpd == NULL) |
| @@ -296,10 +300,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) | |||
| 296 | *dpd = default_dpd; | 300 | *dpd = default_dpd; |
| 297 | INIT_LIST_HEAD(&dpd->channel_detectors); | 301 | INIT_LIST_HEAD(&dpd->channel_detectors); |
| 298 | 302 | ||
| 303 | dpd->ah = ah; | ||
| 299 | if (dpd->set_dfs_domain(dpd, region)) | 304 | if (dpd->set_dfs_domain(dpd, region)) |
| 300 | return dpd; | 305 | return dpd; |
| 301 | 306 | ||
| 302 | pr_err("Could not set DFS domain to %d. ", region); | 307 | ath_dbg(common, DFS,"Could not set DFS domain to %d", region); |
| 303 | kfree(dpd); | 308 | kfree(dpd); |
| 304 | return NULL; | 309 | return NULL; |
| 305 | } | 310 | } |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h index cda52f39f28a..90a5abcc4265 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h | |||
| @@ -80,6 +80,8 @@ struct dfs_pattern_detector { | |||
| 80 | enum nl80211_dfs_regions region; | 80 | enum nl80211_dfs_regions region; |
| 81 | u8 num_radar_types; | 81 | u8 num_radar_types; |
| 82 | u64 last_pulse_ts; | 82 | u64 last_pulse_ts; |
| 83 | /* needed for ath_dbg() */ | ||
| 84 | struct ath_hw *ah; | ||
| 83 | 85 | ||
| 84 | const struct radar_detector_specs *radar_spec; | 86 | const struct radar_detector_specs *radar_spec; |
| 85 | struct list_head channel_detectors; | 87 | struct list_head channel_detectors; |
| @@ -92,10 +94,10 @@ struct dfs_pattern_detector { | |||
| 92 | */ | 94 | */ |
| 93 | #if defined(CONFIG_ATH9K_DFS_CERTIFIED) | 95 | #if defined(CONFIG_ATH9K_DFS_CERTIFIED) |
| 94 | extern struct dfs_pattern_detector * | 96 | extern struct dfs_pattern_detector * |
| 95 | dfs_pattern_detector_init(enum nl80211_dfs_regions region); | 97 | dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region); |
| 96 | #else | 98 | #else |
| 97 | static inline struct dfs_pattern_detector * | 99 | static inline struct dfs_pattern_detector * |
| 98 | dfs_pattern_detector_init(enum nl80211_dfs_regions region) | 100 | dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) |
| 99 | { | 101 | { |
| 100 | return NULL; | 102 | return NULL; |
| 101 | } | 103 | } |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 5e48c5515b8c..5ba4b6fe37c0 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c | |||
| @@ -23,28 +23,6 @@ | |||
| 23 | #include "dfs_debug.h" | 23 | #include "dfs_debug.h" |
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * struct pri_sequence - sequence of pulses matching one PRI | ||
| 27 | * @head: list_head | ||
| 28 | * @pri: pulse repetition interval (PRI) in usecs | ||
| 29 | * @dur: duration of sequence in usecs | ||
| 30 | * @count: number of pulses in this sequence | ||
| 31 | * @count_falses: number of not matching pulses in this sequence | ||
| 32 | * @first_ts: time stamp of first pulse in usecs | ||
| 33 | * @last_ts: time stamp of last pulse in usecs | ||
| 34 | * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) | ||
| 35 | */ | ||
| 36 | struct pri_sequence { | ||
| 37 | struct list_head head; | ||
| 38 | u32 pri; | ||
| 39 | u32 dur; | ||
| 40 | u32 count; | ||
| 41 | u32 count_falses; | ||
| 42 | u64 first_ts; | ||
| 43 | u64 last_ts; | ||
| 44 | u64 deadline_ts; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * struct pulse_elem - elements in pulse queue | 26 | * struct pulse_elem - elements in pulse queue |
| 49 | * @ts: time stamp in usecs | 27 | * @ts: time stamp in usecs |
| 50 | */ | 28 | */ |
| @@ -393,8 +371,8 @@ static void pri_detector_exit(struct pri_detector *de) | |||
| 393 | kfree(de); | 371 | kfree(de); |
| 394 | } | 372 | } |
| 395 | 373 | ||
| 396 | static bool pri_detector_add_pulse(struct pri_detector *de, | 374 | static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de, |
| 397 | struct pulse_event *event) | 375 | struct pulse_event *event) |
| 398 | { | 376 | { |
| 399 | u32 max_updated_seq; | 377 | u32 max_updated_seq; |
| 400 | struct pri_sequence *ps; | 378 | struct pri_sequence *ps; |
| @@ -403,38 +381,33 @@ static bool pri_detector_add_pulse(struct pri_detector *de, | |||
| 403 | 381 | ||
| 404 | /* ignore pulses not within width range */ | 382 | /* ignore pulses not within width range */ |
| 405 | if ((rs->width_min > event->width) || (rs->width_max < event->width)) | 383 | if ((rs->width_min > event->width) || (rs->width_max < event->width)) |
| 406 | return false; | 384 | return NULL; |
| 407 | 385 | ||
| 408 | if ((ts - de->last_ts) < rs->max_pri_tolerance) | 386 | if ((ts - de->last_ts) < rs->max_pri_tolerance) |
| 409 | /* if delta to last pulse is too short, don't use this pulse */ | 387 | /* if delta to last pulse is too short, don't use this pulse */ |
| 410 | return false; | 388 | return NULL; |
| 411 | de->last_ts = ts; | 389 | de->last_ts = ts; |
| 412 | 390 | ||
| 413 | max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts); | 391 | max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts); |
| 414 | 392 | ||
| 415 | if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) { | 393 | if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) { |
| 416 | pr_err("failed to create pulse sequences\n"); | ||
| 417 | pri_detector_reset(de, ts); | 394 | pri_detector_reset(de, ts); |
| 418 | return false; | 395 | return false; |
| 419 | } | 396 | } |
| 420 | 397 | ||
| 421 | ps = pseq_handler_check_detection(de); | 398 | ps = pseq_handler_check_detection(de); |
| 422 | 399 | ||
| 423 | if (ps != NULL) { | 400 | if (ps == NULL) |
| 424 | pr_info("DFS: radar found: pri=%d, count=%d, count_false=%d\n", | 401 | pulse_queue_enqueue(de, ts); |
| 425 | ps->pri, ps->count, ps->count_falses); | 402 | |
| 426 | pri_detector_reset(de, ts); | 403 | return ps; |
| 427 | return true; | ||
| 428 | } | ||
| 429 | pulse_queue_enqueue(de, ts); | ||
| 430 | return false; | ||
| 431 | } | 404 | } |
| 432 | 405 | ||
| 433 | struct pri_detector * | 406 | struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs) |
| 434 | pri_detector_init(const struct radar_detector_specs *rs) | ||
| 435 | { | 407 | { |
| 436 | struct pri_detector *de; | 408 | struct pri_detector *de; |
| 437 | de = kzalloc(sizeof(*de), GFP_KERNEL); | 409 | |
| 410 | de = kzalloc(sizeof(*de), GFP_ATOMIC); | ||
| 438 | if (de == NULL) | 411 | if (de == NULL) |
| 439 | return NULL; | 412 | return NULL; |
| 440 | de->exit = pri_detector_exit; | 413 | de->exit = pri_detector_exit; |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h index 81cde9f28e44..723962d1abc6 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h | |||
| @@ -20,9 +20,31 @@ | |||
| 20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * struct pri_sequence - sequence of pulses matching one PRI | ||
| 24 | * @head: list_head | ||
| 25 | * @pri: pulse repetition interval (PRI) in usecs | ||
| 26 | * @dur: duration of sequence in usecs | ||
| 27 | * @count: number of pulses in this sequence | ||
| 28 | * @count_falses: number of not matching pulses in this sequence | ||
| 29 | * @first_ts: time stamp of first pulse in usecs | ||
| 30 | * @last_ts: time stamp of last pulse in usecs | ||
| 31 | * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) | ||
| 32 | */ | ||
| 33 | struct pri_sequence { | ||
| 34 | struct list_head head; | ||
| 35 | u32 pri; | ||
| 36 | u32 dur; | ||
| 37 | u32 count; | ||
| 38 | u32 count_falses; | ||
| 39 | u64 first_ts; | ||
| 40 | u64 last_ts; | ||
| 41 | u64 deadline_ts; | ||
| 42 | }; | ||
| 43 | |||
| 44 | /** | ||
| 23 | * struct pri_detector - PRI detector element for a dedicated radar type | 45 | * struct pri_detector - PRI detector element for a dedicated radar type |
| 24 | * @exit(): destructor | 46 | * @exit(): destructor |
| 25 | * @add_pulse(): add pulse event, returns true if pattern was detected | 47 | * @add_pulse(): add pulse event, returns pri_sequence if pattern was detected |
| 26 | * @reset(): clear states and reset to given time stamp | 48 | * @reset(): clear states and reset to given time stamp |
| 27 | * @rs: detector specs for this detector element | 49 | * @rs: detector specs for this detector element |
| 28 | * @last_ts: last pulse time stamp considered for this element in usecs | 50 | * @last_ts: last pulse time stamp considered for this element in usecs |
| @@ -34,7 +56,8 @@ | |||
| 34 | */ | 56 | */ |
| 35 | struct pri_detector { | 57 | struct pri_detector { |
| 36 | void (*exit) (struct pri_detector *de); | 58 | void (*exit) (struct pri_detector *de); |
| 37 | bool (*add_pulse)(struct pri_detector *de, struct pulse_event *e); | 59 | struct pri_sequence * |
| 60 | (*add_pulse)(struct pri_detector *de, struct pulse_event *e); | ||
| 38 | void (*reset) (struct pri_detector *de, u64 ts); | 61 | void (*reset) (struct pri_detector *de, u64 ts); |
| 39 | 62 | ||
| 40 | /* private: internal use only */ | 63 | /* private: internal use only */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index d0ce1f5bba10..f13f458dd656 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
| @@ -308,7 +308,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, | |||
| 308 | while(skb) { | 308 | while(skb) { |
| 309 | hdr = (struct ieee80211_hdr *) skb->data; | 309 | hdr = (struct ieee80211_hdr *) skb->data; |
| 310 | 310 | ||
| 311 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 311 | padpos = ieee80211_hdrlen(hdr->frame_control); |
| 312 | padsize = padpos & 3; | 312 | padsize = padpos & 3; |
| 313 | if (padsize && skb->len > padpos) { | 313 | if (padsize && skb->len > padpos) { |
| 314 | if (skb_headroom(skb) < padsize) { | 314 | if (skb_headroom(skb) < padsize) { |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index a8016d70088a..0743a47cef8f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -190,7 +190,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
| 190 | { | 190 | { |
| 191 | struct ath_hw *ah = priv->ah; | 191 | struct ath_hw *ah = priv->ah; |
| 192 | struct ath_common *common = ath9k_hw_common(ah); | 192 | struct ath_common *common = ath9k_hw_common(ah); |
| 193 | struct ieee80211_channel *channel = priv->hw->conf.channel; | 193 | struct ieee80211_channel *channel = priv->hw->conf.chandef.chan; |
| 194 | struct ath9k_hw_cal_data *caldata = NULL; | 194 | struct ath9k_hw_cal_data *caldata = NULL; |
| 195 | enum htc_phymode mode; | 195 | enum htc_phymode mode; |
| 196 | __be16 htc_mode; | 196 | __be16 htc_mode; |
| @@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 250 | struct ath_common *common = ath9k_hw_common(ah); | 250 | struct ath_common *common = ath9k_hw_common(ah); |
| 251 | struct ieee80211_conf *conf = &common->hw->conf; | 251 | struct ieee80211_conf *conf = &common->hw->conf; |
| 252 | bool fastcc; | 252 | bool fastcc; |
| 253 | struct ieee80211_channel *channel = hw->conf.channel; | 253 | struct ieee80211_channel *channel = hw->conf.chandef.chan; |
| 254 | struct ath9k_hw_cal_data *caldata = NULL; | 254 | struct ath9k_hw_cal_data *caldata = NULL; |
| 255 | enum htc_phymode mode; | 255 | enum htc_phymode mode; |
| 256 | __be16 htc_mode; | 256 | __be16 htc_mode; |
| @@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, | |||
| 602 | u32 caps = 0; | 602 | u32 caps = 0; |
| 603 | int i, j; | 603 | int i, j; |
| 604 | 604 | ||
| 605 | sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band]; | 605 | sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band]; |
| 606 | 606 | ||
| 607 | for (i = 0, j = 0; i < sband->n_bitrates; i++) { | 607 | for (i = 0, j = 0; i < sband->n_bitrates; i++) { |
| 608 | if (sta->supp_rates[sband->band] & BIT(i)) { | 608 | if (sta->supp_rates[sband->band] & BIT(i)) { |
| @@ -866,7 +866,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, | |||
| 866 | hdr = (struct ieee80211_hdr *) skb->data; | 866 | hdr = (struct ieee80211_hdr *) skb->data; |
| 867 | 867 | ||
| 868 | /* Add the padding after the header if this is not already done */ | 868 | /* Add the padding after the header if this is not already done */ |
| 869 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 869 | padpos = ieee80211_hdrlen(hdr->frame_control); |
| 870 | padsize = padpos & 3; | 870 | padsize = padpos & 3; |
| 871 | if (padsize && skb->len > padpos) { | 871 | if (padsize && skb->len > padpos) { |
| 872 | if (skb_headroom(skb) < padsize) { | 872 | if (skb_headroom(skb) < padsize) { |
| @@ -904,7 +904,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
| 904 | struct ath9k_htc_priv *priv = hw->priv; | 904 | struct ath9k_htc_priv *priv = hw->priv; |
| 905 | struct ath_hw *ah = priv->ah; | 905 | struct ath_hw *ah = priv->ah; |
| 906 | struct ath_common *common = ath9k_hw_common(ah); | 906 | struct ath_common *common = ath9k_hw_common(ah); |
| 907 | struct ieee80211_channel *curchan = hw->conf.channel; | 907 | struct ieee80211_channel *curchan = hw->conf.chandef.chan; |
| 908 | struct ath9k_channel *init_channel; | 908 | struct ath9k_channel *init_channel; |
| 909 | int ret = 0; | 909 | int ret = 0; |
| 910 | enum htc_phymode mode; | 910 | enum htc_phymode mode; |
| @@ -1193,15 +1193,17 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1193 | } | 1193 | } |
| 1194 | 1194 | ||
| 1195 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { | 1195 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { |
| 1196 | struct ieee80211_channel *curchan = hw->conf.channel; | 1196 | struct ieee80211_channel *curchan = hw->conf.chandef.chan; |
| 1197 | enum nl80211_channel_type channel_type = | ||
| 1198 | cfg80211_get_chandef_type(&hw->conf.chandef); | ||
| 1197 | int pos = curchan->hw_value; | 1199 | int pos = curchan->hw_value; |
| 1198 | 1200 | ||
| 1199 | ath_dbg(common, CONFIG, "Set channel: %d MHz\n", | 1201 | ath_dbg(common, CONFIG, "Set channel: %d MHz\n", |
| 1200 | curchan->center_freq); | 1202 | curchan->center_freq); |
| 1201 | 1203 | ||
| 1202 | ath9k_cmn_update_ichannel(&priv->ah->channels[pos], | 1204 | ath9k_cmn_update_ichannel(&priv->ah->channels[pos], |
| 1203 | hw->conf.channel, | 1205 | hw->conf.chandef.chan, |
| 1204 | hw->conf.channel_type); | 1206 | channel_type); |
| 1205 | 1207 | ||
| 1206 | if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { | 1208 | if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { |
| 1207 | ath_err(common, "Unable to set channel\n"); | 1209 | ath_err(common, "Unable to set channel\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index bd8251c1c749..6bd0e92ea2aa 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
| @@ -490,7 +490,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, | |||
| 490 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) | 490 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) |
| 491 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | 491 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; |
| 492 | } else { | 492 | } else { |
| 493 | if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) | 493 | if (cur_conf->chandef.chan->band == IEEE80211_BAND_5GHZ) |
| 494 | rate->idx += 4; /* No CCK rates */ | 494 | rate->idx += 4; /* No CCK rates */ |
| 495 | } | 495 | } |
| 496 | 496 | ||
| @@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw, | |||
| 939 | return; | 939 | return; |
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | band = hw->conf.channel->band; | 942 | band = hw->conf.chandef.chan->band; |
| 943 | sband = hw->wiphy->bands[band]; | 943 | sband = hw->wiphy->bands[band]; |
| 944 | 944 | ||
| 945 | for (i = 0; i < sband->n_bitrates; i++) { | 945 | for (i = 0; i < sband->n_bitrates; i++) { |
| @@ -966,7 +966,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
| 966 | struct sk_buff *skb = rxbuf->skb; | 966 | struct sk_buff *skb = rxbuf->skb; |
| 967 | struct ath_common *common = ath9k_hw_common(priv->ah); | 967 | struct ath_common *common = ath9k_hw_common(priv->ah); |
| 968 | struct ath_htc_rx_status *rxstatus; | 968 | struct ath_htc_rx_status *rxstatus; |
| 969 | int hdrlen, padpos, padsize; | 969 | int hdrlen, padsize; |
| 970 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 970 | int last_rssi = ATH_RSSI_DUMMY_MARKER; |
| 971 | __le16 fc; | 971 | __le16 fc; |
| 972 | 972 | ||
| @@ -996,11 +996,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
| 996 | fc = hdr->frame_control; | 996 | fc = hdr->frame_control; |
| 997 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 997 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
| 998 | 998 | ||
| 999 | padpos = ath9k_cmn_padpos(fc); | 999 | padsize = hdrlen & 3; |
| 1000 | 1000 | if (padsize && skb->len >= hdrlen+padsize+FCS_LEN) { | |
| 1001 | padsize = padpos & 3; | 1001 | memmove(skb->data + padsize, skb->data, hdrlen); |
| 1002 | if (padsize && skb->len >= padpos+padsize+FCS_LEN) { | ||
| 1003 | memmove(skb->data + padsize, skb->data, padpos); | ||
| 1004 | skb_pull(skb, padsize); | 1002 | skb_pull(skb, padsize); |
| 1005 | } | 1003 | } |
| 1006 | 1004 | ||
| @@ -1082,8 +1080,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
| 1082 | } | 1080 | } |
| 1083 | 1081 | ||
| 1084 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); | 1082 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); |
| 1085 | rx_status->band = hw->conf.channel->band; | 1083 | rx_status->band = hw->conf.chandef.chan->band; |
| 1086 | rx_status->freq = hw->conf.channel->center_freq; | 1084 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 1087 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | 1085 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; |
| 1088 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; | 1086 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; |
| 1089 | rx_status->flag |= RX_FLAG_MACTIME_END; | 1087 | rx_status->flag |= RX_FLAG_MACTIME_END; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 3473a797651a..7f25da8444fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -139,7 +139,7 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah) | |||
| 139 | clockrate = 117; | 139 | clockrate = 117; |
| 140 | else if (!ah->curchan) /* should really check for CCK instead */ | 140 | else if (!ah->curchan) /* should really check for CCK instead */ |
| 141 | clockrate = ATH9K_CLOCK_RATE_CCK; | 141 | clockrate = ATH9K_CLOCK_RATE_CCK; |
| 142 | else if (conf->channel->band == IEEE80211_BAND_2GHZ) | 142 | else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 143 | clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; | 143 | clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; |
| 144 | else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) | 144 | else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) |
| 145 | clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; | 145 | clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; |
| @@ -1100,7 +1100,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
| 1100 | } | 1100 | } |
| 1101 | 1101 | ||
| 1102 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ | 1102 | /* As defined by IEEE 802.11-2007 17.3.8.6 */ |
| 1103 | acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset; | 1103 | slottime += 3 * ah->coverage_class; |
| 1104 | acktimeout = slottime + sifstime + ack_offset; | ||
| 1104 | ctstimeout = acktimeout; | 1105 | ctstimeout = acktimeout; |
| 1105 | 1106 | ||
| 1106 | /* | 1107 | /* |
| @@ -1110,7 +1111,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
| 1110 | * BA frames in some implementations, but it has been found to fix ACK | 1111 | * BA frames in some implementations, but it has been found to fix ACK |
| 1111 | * timeout issues in other cases as well. | 1112 | * timeout issues in other cases as well. |
| 1112 | */ | 1113 | */ |
| 1113 | if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ && | 1114 | if (conf->chandef.chan && |
| 1115 | conf->chandef.chan->band == IEEE80211_BAND_2GHZ && | ||
| 1114 | !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { | 1116 | !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { |
| 1115 | acktimeout += 64 - sifstime - ah->slottime; | 1117 | acktimeout += 64 - sifstime - ah->slottime; |
| 1116 | ctstimeout += 48 - sifstime - ah->slottime; | 1118 | ctstimeout += 48 - sifstime - ah->slottime; |
| @@ -1697,12 +1699,11 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah, | |||
| 1697 | 1699 | ||
| 1698 | ENABLE_REGWRITE_BUFFER(ah); | 1700 | ENABLE_REGWRITE_BUFFER(ah); |
| 1699 | 1701 | ||
| 1700 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 1702 | REG_RMW(ah, AR_STA_ID1, macStaId1 |
| 1701 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) | ||
| 1702 | | macStaId1 | ||
| 1703 | | AR_STA_ID1_RTS_USE_DEF | 1703 | | AR_STA_ID1_RTS_USE_DEF |
| 1704 | | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | 1704 | | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) |
| 1705 | | ah->sta_id1_defaults); | 1705 | | ah->sta_id1_defaults, |
| 1706 | ~AR_STA_ID1_SADH_MASK); | ||
| 1706 | ath_hw_setbssidmask(common); | 1707 | ath_hw_setbssidmask(common); |
| 1707 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); | 1708 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); |
| 1708 | ath9k_hw_write_associd(ah); | 1709 | ath9k_hw_write_associd(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 30e62d92d46d..ae3034374bc4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
| @@ -847,14 +847,7 @@ struct ath_hw { | |||
| 847 | struct ath_hw_ops ops; | 847 | struct ath_hw_ops ops; |
| 848 | 848 | ||
| 849 | /* Used to program the radio on non single-chip devices */ | 849 | /* Used to program the radio on non single-chip devices */ |
| 850 | u32 *analogBank0Data; | ||
| 851 | u32 *analogBank1Data; | ||
| 852 | u32 *analogBank2Data; | ||
| 853 | u32 *analogBank3Data; | ||
| 854 | u32 *analogBank6Data; | 850 | u32 *analogBank6Data; |
| 855 | u32 *analogBank6TPCData; | ||
| 856 | u32 *analogBank7Data; | ||
| 857 | u32 *bank6Temp; | ||
| 858 | 851 | ||
| 859 | int coverage_class; | 852 | int coverage_class; |
| 860 | u32 slottime; | 853 | u32 slottime; |
| @@ -885,14 +878,8 @@ struct ath_hw { | |||
| 885 | 878 | ||
| 886 | struct ar5416IniArray iniModes; | 879 | struct ar5416IniArray iniModes; |
| 887 | struct ar5416IniArray iniCommon; | 880 | struct ar5416IniArray iniCommon; |
| 888 | struct ar5416IniArray iniBank0; | ||
| 889 | struct ar5416IniArray iniBB_RfGain; | 881 | struct ar5416IniArray iniBB_RfGain; |
| 890 | struct ar5416IniArray iniBank1; | ||
| 891 | struct ar5416IniArray iniBank2; | ||
| 892 | struct ar5416IniArray iniBank3; | ||
| 893 | struct ar5416IniArray iniBank6; | 882 | struct ar5416IniArray iniBank6; |
| 894 | struct ar5416IniArray iniBank6TPC; | ||
| 895 | struct ar5416IniArray iniBank7; | ||
| 896 | struct ar5416IniArray iniAddac; | 883 | struct ar5416IniArray iniAddac; |
| 897 | struct ar5416IniArray iniPcieSerdes; | 884 | struct ar5416IniArray iniPcieSerdes; |
| 898 | #ifdef CONFIG_PM_SLEEP | 885 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 3be2eb0da84a..0237b2868961 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -577,7 +577,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
| 577 | atomic_set(&ah->intr_ref_cnt, -1); | 577 | atomic_set(&ah->intr_ref_cnt, -1); |
| 578 | sc->sc_ah = ah; | 578 | sc->sc_ah = ah; |
| 579 | 579 | ||
| 580 | sc->dfs_detector = dfs_pattern_detector_init(NL80211_DFS_UNSET); | 580 | sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET); |
| 581 | 581 | ||
| 582 | if (!pdata) { | 582 | if (!pdata) { |
| 583 | ah->ah_flags |= AH_USE_EEPROM; | 583 | ah->ah_flags |= AH_USE_EEPROM; |
| @@ -766,7 +766,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 766 | IEEE80211_HW_SUPPORTS_PS | | 766 | IEEE80211_HW_SUPPORTS_PS | |
| 767 | IEEE80211_HW_PS_NULLFUNC_STACK | | 767 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 768 | IEEE80211_HW_SPECTRUM_MGMT | | 768 | IEEE80211_HW_SPECTRUM_MGMT | |
| 769 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | 769 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 770 | IEEE80211_HW_SUPPORTS_RC_TABLE; | ||
| 770 | 771 | ||
| 771 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 772 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
| 772 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 773 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 7fdac6c7b3ea..849259b07370 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
| @@ -214,7 +214,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
| 214 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; | 214 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
| 215 | 215 | ||
| 216 | memset(tx_info, 0, sizeof(*tx_info)); | 216 | memset(tx_info, 0, sizeof(*tx_info)); |
| 217 | tx_info->band = hw->conf.channel->band; | 217 | tx_info->band = hw->conf.chandef.chan->band; |
| 218 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | 218 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; |
| 219 | tx_info->control.rates[0].idx = 0; | 219 | tx_info->control.rates[0].idx = 0; |
| 220 | tx_info->control.rates[0].count = 1; | 220 | tx_info->control.rates[0].count = 1; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 811007ec07a7..498fee04afa0 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
| @@ -615,6 +615,14 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
| 615 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 615 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
| 616 | else if (ads.ds_rxstatus8 & AR_MichaelErr) | 616 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
| 617 | rs->rs_status |= ATH9K_RXERR_MIC; | 617 | rs->rs_status |= ATH9K_RXERR_MIC; |
| 618 | } else { | ||
| 619 | if (ads.ds_rxstatus8 & | ||
| 620 | (AR_CRCErr | AR_PHYErr | AR_DecryptCRCErr | AR_MichaelErr)) | ||
| 621 | rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; | ||
| 622 | |||
| 623 | /* Only up to MCS16 supported, everything above is invalid */ | ||
| 624 | if (rs->rs_rate >= 0x90) | ||
| 625 | rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; | ||
| 618 | } | 626 | } |
| 619 | 627 | ||
| 620 | if (ads.ds_rxstatus8 & AR_KeyMiss) | 628 | if (ads.ds_rxstatus8 & AR_KeyMiss) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 1ff817061ebc..5865f92998e1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
| @@ -183,6 +183,7 @@ struct ath_htc_rx_status { | |||
| 183 | #define ATH9K_RXERR_DECRYPT 0x08 | 183 | #define ATH9K_RXERR_DECRYPT 0x08 |
| 184 | #define ATH9K_RXERR_MIC 0x10 | 184 | #define ATH9K_RXERR_MIC 0x10 |
| 185 | #define ATH9K_RXERR_KEYMISS 0x20 | 185 | #define ATH9K_RXERR_KEYMISS 0x20 |
| 186 | #define ATH9K_RXERR_CORRUPT_DESC 0x40 | ||
| 186 | 187 | ||
| 187 | #define ATH9K_RX_MORE 0x01 | 188 | #define ATH9K_RX_MORE 0x01 |
| 188 | #define ATH9K_RX_MORE_AGGR 0x02 | 189 | #define ATH9K_RX_MORE_AGGR 0x02 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1bf52c88004a..6963862a1872 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -589,7 +589,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 589 | struct ath_softc *sc = hw->priv; | 589 | struct ath_softc *sc = hw->priv; |
| 590 | struct ath_hw *ah = sc->sc_ah; | 590 | struct ath_hw *ah = sc->sc_ah; |
| 591 | struct ath_common *common = ath9k_hw_common(ah); | 591 | struct ath_common *common = ath9k_hw_common(ah); |
| 592 | struct ieee80211_channel *curchan = hw->conf.channel; | 592 | struct ieee80211_channel *curchan = hw->conf.chandef.chan; |
| 593 | struct ath9k_channel *init_channel; | 593 | struct ath9k_channel *init_channel; |
| 594 | int r; | 594 | int r; |
| 595 | 595 | ||
| @@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
| 839 | struct ath9k_vif_iter_data *iter_data = data; | 839 | struct ath9k_vif_iter_data *iter_data = data; |
| 840 | int i; | 840 | int i; |
| 841 | 841 | ||
| 842 | if (iter_data->hw_macaddr) | 842 | if (iter_data->has_hw_macaddr) { |
| 843 | for (i = 0; i < ETH_ALEN; i++) | 843 | for (i = 0; i < ETH_ALEN; i++) |
| 844 | iter_data->mask[i] &= | 844 | iter_data->mask[i] &= |
| 845 | ~(iter_data->hw_macaddr[i] ^ mac[i]); | 845 | ~(iter_data->hw_macaddr[i] ^ mac[i]); |
| 846 | } else { | ||
| 847 | memcpy(iter_data->hw_macaddr, mac, ETH_ALEN); | ||
| 848 | iter_data->has_hw_macaddr = true; | ||
| 849 | } | ||
| 846 | 850 | ||
| 847 | switch (vif->type) { | 851 | switch (vif->type) { |
| 848 | case NL80211_IFTYPE_AP: | 852 | case NL80211_IFTYPE_AP: |
| @@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
| 891 | * together with the BSSID mask when matching addresses. | 895 | * together with the BSSID mask when matching addresses. |
| 892 | */ | 896 | */ |
| 893 | memset(iter_data, 0, sizeof(*iter_data)); | 897 | memset(iter_data, 0, sizeof(*iter_data)); |
| 894 | iter_data->hw_macaddr = common->macaddr; | ||
| 895 | memset(&iter_data->mask, 0xff, ETH_ALEN); | 898 | memset(&iter_data->mask, 0xff, ETH_ALEN); |
| 896 | 899 | ||
| 897 | if (vif) | 900 | if (vif) |
| @@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
| 901 | ieee80211_iterate_active_interfaces_atomic( | 904 | ieee80211_iterate_active_interfaces_atomic( |
| 902 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, | 905 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
| 903 | ath9k_vif_iter, iter_data); | 906 | ath9k_vif_iter, iter_data); |
| 907 | |||
| 908 | memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN); | ||
| 904 | } | 909 | } |
| 905 | 910 | ||
| 906 | /* Called with sc->mutex held. */ | 911 | /* Called with sc->mutex held. */ |
| @@ -1188,7 +1193,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1188 | } | 1193 | } |
| 1189 | 1194 | ||
| 1190 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { | 1195 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { |
| 1191 | struct ieee80211_channel *curchan = hw->conf.channel; | 1196 | struct ieee80211_channel *curchan = hw->conf.chandef.chan; |
| 1197 | enum nl80211_channel_type channel_type = | ||
| 1198 | cfg80211_get_chandef_type(&conf->chandef); | ||
| 1192 | int pos = curchan->hw_value; | 1199 | int pos = curchan->hw_value; |
| 1193 | int old_pos = -1; | 1200 | int old_pos = -1; |
| 1194 | unsigned long flags; | 1201 | unsigned long flags; |
| @@ -1197,7 +1204,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1197 | old_pos = ah->curchan - &ah->channels[0]; | 1204 | old_pos = ah->curchan - &ah->channels[0]; |
| 1198 | 1205 | ||
| 1199 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", | 1206 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", |
| 1200 | curchan->center_freq, conf->channel_type); | 1207 | curchan->center_freq, channel_type); |
| 1201 | 1208 | ||
| 1202 | /* update survey stats for the old channel before switching */ | 1209 | /* update survey stats for the old channel before switching */ |
| 1203 | spin_lock_irqsave(&common->cc_lock, flags); | 1210 | spin_lock_irqsave(&common->cc_lock, flags); |
| @@ -1212,7 +1219,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1212 | ath9k_hw_getnf(ah, ah->curchan); | 1219 | ath9k_hw_getnf(ah, ah->curchan); |
| 1213 | 1220 | ||
| 1214 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], | 1221 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
| 1215 | curchan, conf->channel_type); | 1222 | curchan, channel_type); |
| 1216 | 1223 | ||
| 1217 | /* | 1224 | /* |
| 1218 | * If the operating channel changes, change the survey in-use flags | 1225 | * If the operating channel changes, change the survey in-use flags |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 96ac433ba7f6..aa4d368d8d3d 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
| @@ -814,7 +814,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
| 814 | * So, set fourth rate in series to be same as third one for | 814 | * So, set fourth rate in series to be same as third one for |
| 815 | * above conditions. | 815 | * above conditions. |
| 816 | */ | 816 | */ |
| 817 | if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && | 817 | if ((sc->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) && |
| 818 | (conf_is_ht(&sc->hw->conf))) { | 818 | (conf_is_ht(&sc->hw->conf))) { |
| 819 | u8 dot11rate = rate_table->info[rix].dot11rate; | 819 | u8 dot11rate = rate_table->info[rix].dot11rate; |
| 820 | u8 phy = rate_table->info[rix].phy; | 820 | u8 phy = rate_table->info[rix].phy; |
| @@ -1328,7 +1328,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
| 1328 | 1328 | ||
| 1329 | ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, | 1329 | ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, |
| 1330 | "Operating HT Bandwidth changed to: %d\n", | 1330 | "Operating HT Bandwidth changed to: %d\n", |
| 1331 | sc->hw->conf.channel_type); | 1331 | cfg80211_get_chandef_type(&sc->hw->conf.chandef)); |
| 1332 | } | 1332 | } |
| 1333 | } | 1333 | } |
| 1334 | 1334 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ee7ca5aecdb0..8be2b5d8c155 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -124,13 +124,13 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc, | |||
| 124 | 124 | ||
| 125 | SKB_CB_ATHBUF(skb) = bf; | 125 | SKB_CB_ATHBUF(skb) = bf; |
| 126 | ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype); | 126 | ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype); |
| 127 | skb_queue_tail(&rx_edma->rx_fifo, skb); | 127 | __skb_queue_tail(&rx_edma->rx_fifo, skb); |
| 128 | 128 | ||
| 129 | return true; | 129 | return true; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static void ath_rx_addbuffer_edma(struct ath_softc *sc, | 132 | static void ath_rx_addbuffer_edma(struct ath_softc *sc, |
| 133 | enum ath9k_rx_qtype qtype, int size) | 133 | enum ath9k_rx_qtype qtype) |
| 134 | { | 134 | { |
| 135 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 135 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 136 | struct ath_buf *bf, *tbf; | 136 | struct ath_buf *bf, *tbf; |
| @@ -155,7 +155,7 @@ static void ath_rx_remove_buffer(struct ath_softc *sc, | |||
| 155 | 155 | ||
| 156 | rx_edma = &sc->rx.rx_edma[qtype]; | 156 | rx_edma = &sc->rx.rx_edma[qtype]; |
| 157 | 157 | ||
| 158 | while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) { | 158 | while ((skb = __skb_dequeue(&rx_edma->rx_fifo)) != NULL) { |
| 159 | bf = SKB_CB_ATHBUF(skb); | 159 | bf = SKB_CB_ATHBUF(skb); |
| 160 | BUG_ON(!bf); | 160 | BUG_ON(!bf); |
| 161 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 161 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
| @@ -250,15 +250,9 @@ rx_init_fail: | |||
| 250 | static void ath_edma_start_recv(struct ath_softc *sc) | 250 | static void ath_edma_start_recv(struct ath_softc *sc) |
| 251 | { | 251 | { |
| 252 | ath9k_hw_rxena(sc->sc_ah); | 252 | ath9k_hw_rxena(sc->sc_ah); |
| 253 | 253 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP); | |
| 254 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, | 254 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP); |
| 255 | sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize); | ||
| 256 | |||
| 257 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, | ||
| 258 | sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); | ||
| 259 | |||
| 260 | ath_opmode_init(sc); | 255 | ath_opmode_init(sc); |
| 261 | |||
| 262 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 256 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
| 263 | } | 257 | } |
| 264 | 258 | ||
| @@ -280,49 +274,47 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
| 280 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 274 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
| 281 | sc->sc_ah->caps.rx_status_len; | 275 | sc->sc_ah->caps.rx_status_len; |
| 282 | 276 | ||
| 283 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 277 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
| 284 | return ath_rx_edma_init(sc, nbufs); | 278 | return ath_rx_edma_init(sc, nbufs); |
| 285 | } else { | ||
| 286 | ath_dbg(common, CONFIG, "cachelsz %u rxbufsize %u\n", | ||
| 287 | common->cachelsz, common->rx_bufsize); | ||
| 288 | 279 | ||
| 289 | /* Initialize rx descriptors */ | 280 | ath_dbg(common, CONFIG, "cachelsz %u rxbufsize %u\n", |
| 281 | common->cachelsz, common->rx_bufsize); | ||
| 290 | 282 | ||
| 291 | error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, | 283 | /* Initialize rx descriptors */ |
| 292 | "rx", nbufs, 1, 0); | 284 | |
| 293 | if (error != 0) { | 285 | error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, |
| 294 | ath_err(common, | 286 | "rx", nbufs, 1, 0); |
| 295 | "failed to allocate rx descriptors: %d\n", | 287 | if (error != 0) { |
| 296 | error); | 288 | ath_err(common, |
| 289 | "failed to allocate rx descriptors: %d\n", | ||
| 290 | error); | ||
| 291 | goto err; | ||
| 292 | } | ||
| 293 | |||
| 294 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | ||
| 295 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, | ||
| 296 | GFP_KERNEL); | ||
| 297 | if (skb == NULL) { | ||
| 298 | error = -ENOMEM; | ||
| 297 | goto err; | 299 | goto err; |
| 298 | } | 300 | } |
| 299 | 301 | ||
| 300 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | 302 | bf->bf_mpdu = skb; |
| 301 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, | 303 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
| 302 | GFP_KERNEL); | 304 | common->rx_bufsize, |
| 303 | if (skb == NULL) { | 305 | DMA_FROM_DEVICE); |
| 304 | error = -ENOMEM; | 306 | if (unlikely(dma_mapping_error(sc->dev, |
| 305 | goto err; | 307 | bf->bf_buf_addr))) { |
| 306 | } | 308 | dev_kfree_skb_any(skb); |
| 307 | 309 | bf->bf_mpdu = NULL; | |
| 308 | bf->bf_mpdu = skb; | 310 | bf->bf_buf_addr = 0; |
| 309 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 311 | ath_err(common, |
| 310 | common->rx_bufsize, | 312 | "dma_mapping_error() on RX init\n"); |
| 311 | DMA_FROM_DEVICE); | 313 | error = -ENOMEM; |
| 312 | if (unlikely(dma_mapping_error(sc->dev, | 314 | goto err; |
| 313 | bf->bf_buf_addr))) { | ||
| 314 | dev_kfree_skb_any(skb); | ||
| 315 | bf->bf_mpdu = NULL; | ||
| 316 | bf->bf_buf_addr = 0; | ||
| 317 | ath_err(common, | ||
| 318 | "dma_mapping_error() on RX init\n"); | ||
| 319 | error = -ENOMEM; | ||
| 320 | goto err; | ||
| 321 | } | ||
| 322 | } | 315 | } |
| 323 | sc->rx.rxlink = NULL; | ||
| 324 | } | 316 | } |
| 325 | 317 | sc->rx.rxlink = NULL; | |
| 326 | err: | 318 | err: |
| 327 | if (error) | 319 | if (error) |
| 328 | ath_rx_cleanup(sc); | 320 | ath_rx_cleanup(sc); |
| @@ -340,17 +332,17 @@ void ath_rx_cleanup(struct ath_softc *sc) | |||
| 340 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 332 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
| 341 | ath_rx_edma_cleanup(sc); | 333 | ath_rx_edma_cleanup(sc); |
| 342 | return; | 334 | return; |
| 343 | } else { | 335 | } |
| 344 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | 336 | |
| 345 | skb = bf->bf_mpdu; | 337 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { |
| 346 | if (skb) { | 338 | skb = bf->bf_mpdu; |
| 347 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 339 | if (skb) { |
| 348 | common->rx_bufsize, | 340 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
| 349 | DMA_FROM_DEVICE); | 341 | common->rx_bufsize, |
| 350 | dev_kfree_skb(skb); | 342 | DMA_FROM_DEVICE); |
| 351 | bf->bf_buf_addr = 0; | 343 | dev_kfree_skb(skb); |
| 352 | bf->bf_mpdu = NULL; | 344 | bf->bf_buf_addr = 0; |
| 353 | } | 345 | bf->bf_mpdu = NULL; |
| 354 | } | 346 | } |
| 355 | } | 347 | } |
| 356 | } | 348 | } |
| @@ -727,6 +719,13 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
| 727 | ret = ath9k_hw_rxprocdesc(ah, tds, &trs); | 719 | ret = ath9k_hw_rxprocdesc(ah, tds, &trs); |
| 728 | if (ret == -EINPROGRESS) | 720 | if (ret == -EINPROGRESS) |
| 729 | return NULL; | 721 | return NULL; |
| 722 | |||
| 723 | /* | ||
| 724 | * mark descriptor as zero-length and set the 'more' | ||
| 725 | * flag to ensure that both buffers get discarded | ||
| 726 | */ | ||
| 727 | rs->rs_datalen = 0; | ||
| 728 | rs->rs_more = true; | ||
| 730 | } | 729 | } |
| 731 | 730 | ||
| 732 | list_del(&bf->list); | 731 | list_del(&bf->list); |
| @@ -863,7 +862,7 @@ static int ath9k_process_rate(struct ath_common *common, | |||
| 863 | unsigned int i = 0; | 862 | unsigned int i = 0; |
| 864 | struct ath_softc __maybe_unused *sc = common->priv; | 863 | struct ath_softc __maybe_unused *sc = common->priv; |
| 865 | 864 | ||
| 866 | band = hw->conf.channel->band; | 865 | band = hw->conf.chandef.chan->band; |
| 867 | sband = hw->wiphy->bands[band]; | 866 | sband = hw->wiphy->bands[band]; |
| 868 | 867 | ||
| 869 | if (rx_stats->rs_rate & 0x80) { | 868 | if (rx_stats->rs_rate & 0x80) { |
| @@ -933,14 +932,20 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
| 933 | * up the frame up to let mac80211 handle the actual error case, be it no | 932 | * up the frame up to let mac80211 handle the actual error case, be it no |
| 934 | * decryption key or real decryption error. This let us keep statistics there. | 933 | * decryption key or real decryption error. This let us keep statistics there. |
| 935 | */ | 934 | */ |
| 936 | static int ath9k_rx_skb_preprocess(struct ath_common *common, | 935 | static int ath9k_rx_skb_preprocess(struct ath_softc *sc, |
| 937 | struct ieee80211_hw *hw, | ||
| 938 | struct ieee80211_hdr *hdr, | 936 | struct ieee80211_hdr *hdr, |
| 939 | struct ath_rx_status *rx_stats, | 937 | struct ath_rx_status *rx_stats, |
| 940 | struct ieee80211_rx_status *rx_status, | 938 | struct ieee80211_rx_status *rx_status, |
| 941 | bool *decrypt_error) | 939 | bool *decrypt_error) |
| 942 | { | 940 | { |
| 943 | struct ath_hw *ah = common->ah; | 941 | struct ieee80211_hw *hw = sc->hw; |
| 942 | struct ath_hw *ah = sc->sc_ah; | ||
| 943 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 944 | bool discard_current = sc->rx.discard_next; | ||
| 945 | |||
| 946 | sc->rx.discard_next = rx_stats->rs_more; | ||
| 947 | if (discard_current) | ||
| 948 | return -EINVAL; | ||
| 944 | 949 | ||
| 945 | /* | 950 | /* |
| 946 | * everything but the rate is checked here, the rate check is done | 951 | * everything but the rate is checked here, the rate check is done |
| @@ -958,14 +963,15 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
| 958 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) | 963 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
| 959 | return -EINVAL; | 964 | return -EINVAL; |
| 960 | 965 | ||
| 961 | rx_status->band = hw->conf.channel->band; | 966 | rx_status->band = hw->conf.chandef.chan->band; |
| 962 | rx_status->freq = hw->conf.channel->center_freq; | 967 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 963 | rx_status->signal = ah->noise + rx_stats->rs_rssi; | 968 | rx_status->signal = ah->noise + rx_stats->rs_rssi; |
| 964 | rx_status->antenna = rx_stats->rs_antenna; | 969 | rx_status->antenna = rx_stats->rs_antenna; |
| 965 | rx_status->flag |= RX_FLAG_MACTIME_END; | 970 | rx_status->flag |= RX_FLAG_MACTIME_END; |
| 966 | if (rx_stats->rs_moreaggr) | 971 | if (rx_stats->rs_moreaggr) |
| 967 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | 972 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; |
| 968 | 973 | ||
| 974 | sc->rx.discard_next = false; | ||
| 969 | return 0; | 975 | return 0; |
| 970 | } | 976 | } |
| 971 | 977 | ||
| @@ -985,7 +991,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, | |||
| 985 | hdr = (struct ieee80211_hdr *) skb->data; | 991 | hdr = (struct ieee80211_hdr *) skb->data; |
| 986 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 992 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
| 987 | fc = hdr->frame_control; | 993 | fc = hdr->frame_control; |
| 988 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 994 | padpos = ieee80211_hdrlen(fc); |
| 989 | 995 | ||
| 990 | /* The MAC header is padded to have 32-bit boundary if the | 996 | /* The MAC header is padded to have 32-bit boundary if the |
| 991 | * packet payload is non-zero. The general calculation for | 997 | * packet payload is non-zero. The general calculation for |
| @@ -1166,6 +1172,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1166 | u64 tsf = 0; | 1172 | u64 tsf = 0; |
| 1167 | u32 tsf_lower = 0; | 1173 | u32 tsf_lower = 0; |
| 1168 | unsigned long flags; | 1174 | unsigned long flags; |
| 1175 | dma_addr_t new_buf_addr; | ||
| 1169 | 1176 | ||
| 1170 | if (edma) | 1177 | if (edma) |
| 1171 | dma_type = DMA_BIDIRECTIONAL; | 1178 | dma_type = DMA_BIDIRECTIONAL; |
| @@ -1242,8 +1249,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1242 | } | 1249 | } |
| 1243 | } | 1250 | } |
| 1244 | 1251 | ||
| 1245 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, | 1252 | retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs, |
| 1246 | rxs, &decrypt_error); | 1253 | &decrypt_error); |
| 1247 | if (retval) | 1254 | if (retval) |
| 1248 | goto requeue_drop_frag; | 1255 | goto requeue_drop_frag; |
| 1249 | 1256 | ||
| @@ -1264,10 +1271,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1264 | goto requeue_drop_frag; | 1271 | goto requeue_drop_frag; |
| 1265 | } | 1272 | } |
| 1266 | 1273 | ||
| 1274 | /* We will now give hardware our shiny new allocated skb */ | ||
| 1275 | new_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | ||
| 1276 | common->rx_bufsize, dma_type); | ||
| 1277 | if (unlikely(dma_mapping_error(sc->dev, new_buf_addr))) { | ||
| 1278 | dev_kfree_skb_any(requeue_skb); | ||
| 1279 | goto requeue_drop_frag; | ||
| 1280 | } | ||
| 1281 | |||
| 1267 | /* Unmap the frame */ | 1282 | /* Unmap the frame */ |
| 1268 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 1283 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
| 1269 | common->rx_bufsize, | 1284 | common->rx_bufsize, dma_type); |
| 1270 | dma_type); | 1285 | |
| 1286 | bf->bf_mpdu = requeue_skb; | ||
| 1287 | bf->bf_buf_addr = new_buf_addr; | ||
| 1271 | 1288 | ||
| 1272 | skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); | 1289 | skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); |
| 1273 | if (ah->caps.rx_status_len) | 1290 | if (ah->caps.rx_status_len) |
| @@ -1277,21 +1294,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1277 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, | 1294 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, |
| 1278 | rxs, decrypt_error); | 1295 | rxs, decrypt_error); |
| 1279 | 1296 | ||
| 1280 | /* We will now give hardware our shiny new allocated skb */ | ||
| 1281 | bf->bf_mpdu = requeue_skb; | ||
| 1282 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | ||
| 1283 | common->rx_bufsize, | ||
| 1284 | dma_type); | ||
| 1285 | if (unlikely(dma_mapping_error(sc->dev, | ||
| 1286 | bf->bf_buf_addr))) { | ||
| 1287 | dev_kfree_skb_any(requeue_skb); | ||
| 1288 | bf->bf_mpdu = NULL; | ||
| 1289 | bf->bf_buf_addr = 0; | ||
| 1290 | ath_err(common, "dma_mapping_error() on RX\n"); | ||
| 1291 | ieee80211_rx(hw, skb); | ||
| 1292 | break; | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | if (rs.rs_more) { | 1297 | if (rs.rs_more) { |
| 1296 | RX_STAT_INC(rx_frags); | 1298 | RX_STAT_INC(rx_frags); |
| 1297 | /* | 1299 | /* |
| @@ -1309,6 +1311,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1309 | sc->rx.frag = skb; | 1311 | sc->rx.frag = skb; |
| 1310 | goto requeue; | 1312 | goto requeue; |
| 1311 | } | 1313 | } |
| 1314 | if (rs.rs_status & ATH9K_RXERR_CORRUPT_DESC) | ||
| 1315 | goto requeue_drop_frag; | ||
| 1312 | 1316 | ||
| 1313 | if (sc->rx.frag) { | 1317 | if (sc->rx.frag) { |
| 1314 | int space = skb->len - skb_tailroom(hdr_skb); | 1318 | int space = skb->len - skb_tailroom(hdr_skb); |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 5929850649f0..5c4ab5026dca 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
| @@ -1493,9 +1493,6 @@ enum { | |||
| 1493 | #define AR9271_RADIO_RF_RST 0x20 | 1493 | #define AR9271_RADIO_RF_RST 0x20 |
| 1494 | #define AR9271_GATE_MAC_CTL 0x4000 | 1494 | #define AR9271_GATE_MAC_CTL 0x4000 |
| 1495 | 1495 | ||
| 1496 | #define AR_STA_ID0 0x8000 | ||
| 1497 | #define AR_STA_ID1 0x8004 | ||
| 1498 | #define AR_STA_ID1_SADH_MASK 0x0000FFFF | ||
| 1499 | #define AR_STA_ID1_STA_AP 0x00010000 | 1496 | #define AR_STA_ID1_STA_AP 0x00010000 |
| 1500 | #define AR_STA_ID1_ADHOC 0x00020000 | 1497 | #define AR_STA_ID1_ADHOC 0x00020000 |
| 1501 | #define AR_STA_ID1_PWR_SAV 0x00040000 | 1498 | #define AR_STA_ID1_PWR_SAV 0x00040000 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 89a64411b82e..eab0fcb7ded6 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -157,6 +157,13 @@ static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) | |||
| 157 | seqno << IEEE80211_SEQ_SEQ_SHIFT); | 157 | seqno << IEEE80211_SEQ_SEQ_SHIFT); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, | ||
| 161 | struct ath_buf *bf) | ||
| 162 | { | ||
| 163 | ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, | ||
| 164 | ARRAY_SIZE(bf->rates)); | ||
| 165 | } | ||
| 166 | |||
| 160 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 167 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
| 161 | { | 168 | { |
| 162 | struct ath_txq *txq = tid->ac->txq; | 169 | struct ath_txq *txq = tid->ac->txq; |
| @@ -189,6 +196,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
| 189 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); | 196 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); |
| 190 | sendbar = true; | 197 | sendbar = true; |
| 191 | } else { | 198 | } else { |
| 199 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | ||
| 192 | ath_tx_send_normal(sc, txq, NULL, skb); | 200 | ath_tx_send_normal(sc, txq, NULL, skb); |
| 193 | } | 201 | } |
| 194 | } | 202 | } |
| @@ -407,7 +415,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 407 | 415 | ||
| 408 | tx_info = IEEE80211_SKB_CB(skb); | 416 | tx_info = IEEE80211_SKB_CB(skb); |
| 409 | 417 | ||
| 410 | memcpy(rates, tx_info->control.rates, sizeof(rates)); | 418 | memcpy(rates, bf->rates, sizeof(rates)); |
| 411 | 419 | ||
| 412 | retries = ts->ts_longretry + 1; | 420 | retries = ts->ts_longretry + 1; |
| 413 | for (i = 0; i < ts->ts_rateindex; i++) | 421 | for (i = 0; i < ts->ts_rateindex; i++) |
| @@ -516,8 +524,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 516 | * not a holding desc. | 524 | * not a holding desc. |
| 517 | */ | 525 | */ |
| 518 | INIT_LIST_HEAD(&bf_head); | 526 | INIT_LIST_HEAD(&bf_head); |
| 519 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || | 527 | if (bf_next != NULL || !bf_last->bf_stale) |
| 520 | bf_next != NULL || !bf_last->bf_stale) | ||
| 521 | list_move_tail(&bf->list, &bf_head); | 528 | list_move_tail(&bf->list, &bf_head); |
| 522 | 529 | ||
| 523 | if (!txpending || (tid->state & AGGR_CLEANUP)) { | 530 | if (!txpending || (tid->state & AGGR_CLEANUP)) { |
| @@ -537,8 +544,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 537 | !txfail); | 544 | !txfail); |
| 538 | } else { | 545 | } else { |
| 539 | /* retry the un-acked ones */ | 546 | /* retry the un-acked ones */ |
| 540 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 547 | if (bf->bf_next == NULL && bf_last->bf_stale) { |
| 541 | bf->bf_next == NULL && bf_last->bf_stale) { | ||
| 542 | struct ath_buf *tbf; | 548 | struct ath_buf *tbf; |
| 543 | 549 | ||
| 544 | tbf = ath_clone_txbuf(sc, bf_last); | 550 | tbf = ath_clone_txbuf(sc, bf_last); |
| @@ -738,8 +744,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
| 738 | bool first_subfrm) | 744 | bool first_subfrm) |
| 739 | { | 745 | { |
| 740 | #define FIRST_DESC_NDELIMS 60 | 746 | #define FIRST_DESC_NDELIMS 60 |
| 741 | struct sk_buff *skb = bf->bf_mpdu; | ||
| 742 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
| 743 | u32 nsymbits, nsymbols; | 747 | u32 nsymbits, nsymbols; |
| 744 | u16 minlen; | 748 | u16 minlen; |
| 745 | u8 flags, rix; | 749 | u8 flags, rix; |
| @@ -780,8 +784,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
| 780 | if (tid->an->mpdudensity == 0) | 784 | if (tid->an->mpdudensity == 0) |
| 781 | return ndelim; | 785 | return ndelim; |
| 782 | 786 | ||
| 783 | rix = tx_info->control.rates[0].idx; | 787 | rix = bf->rates[0].idx; |
| 784 | flags = tx_info->control.rates[0].flags; | 788 | flags = bf->rates[0].flags; |
| 785 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; | 789 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; |
| 786 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; | 790 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; |
| 787 | 791 | ||
| @@ -860,6 +864,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
| 860 | bf_first = bf; | 864 | bf_first = bf; |
| 861 | 865 | ||
| 862 | if (!rl) { | 866 | if (!rl) { |
| 867 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | ||
| 863 | aggr_limit = ath_lookup_rate(sc, bf, tid); | 868 | aggr_limit = ath_lookup_rate(sc, bf, tid); |
| 864 | rl = 1; | 869 | rl = 1; |
| 865 | } | 870 | } |
| @@ -1000,14 +1005,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1000 | 1005 | ||
| 1001 | skb = bf->bf_mpdu; | 1006 | skb = bf->bf_mpdu; |
| 1002 | tx_info = IEEE80211_SKB_CB(skb); | 1007 | tx_info = IEEE80211_SKB_CB(skb); |
| 1003 | rates = tx_info->control.rates; | 1008 | rates = bf->rates; |
| 1004 | hdr = (struct ieee80211_hdr *)skb->data; | 1009 | hdr = (struct ieee80211_hdr *)skb->data; |
| 1005 | 1010 | ||
| 1006 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | 1011 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ |
| 1007 | info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); | 1012 | info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); |
| 1008 | info->rtscts_rate = fi->rtscts_rate; | 1013 | info->rtscts_rate = fi->rtscts_rate; |
| 1009 | 1014 | ||
| 1010 | for (i = 0; i < 4; i++) { | 1015 | for (i = 0; i < ARRAY_SIZE(bf->rates); i++) { |
| 1011 | bool is_40, is_sgi, is_sp; | 1016 | bool is_40, is_sgi, is_sp; |
| 1012 | int phy; | 1017 | int phy; |
| 1013 | 1018 | ||
| @@ -1745,6 +1750,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
| 1745 | return; | 1750 | return; |
| 1746 | } | 1751 | } |
| 1747 | 1752 | ||
| 1753 | ath_set_rates(tid->an->vif, tid->an->sta, bf); | ||
| 1748 | bf->bf_state.bf_type = BUF_AMPDU; | 1754 | bf->bf_state.bf_type = BUF_AMPDU; |
| 1749 | INIT_LIST_HEAD(&bf_head); | 1755 | INIT_LIST_HEAD(&bf_head); |
| 1750 | list_add(&bf->list, &bf_head); | 1756 | list_add(&bf->list, &bf_head); |
| @@ -1894,49 +1900,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
| 1894 | return bf; | 1900 | return bf; |
| 1895 | } | 1901 | } |
| 1896 | 1902 | ||
| 1897 | /* FIXME: tx power */ | ||
| 1898 | static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, | ||
| 1899 | struct ath_tx_control *txctl) | ||
| 1900 | { | ||
| 1901 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
| 1902 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
| 1903 | struct ath_atx_tid *tid = NULL; | ||
| 1904 | struct ath_buf *bf; | ||
| 1905 | u8 tidno; | ||
| 1906 | |||
| 1907 | if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { | ||
| 1908 | tidno = ieee80211_get_qos_ctl(hdr)[0] & | ||
| 1909 | IEEE80211_QOS_CTL_TID_MASK; | ||
| 1910 | tid = ATH_AN_2_TID(txctl->an, tidno); | ||
| 1911 | |||
| 1912 | WARN_ON(tid->ac->txq != txctl->txq); | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { | ||
| 1916 | /* | ||
| 1917 | * Try aggregation if it's a unicast data frame | ||
| 1918 | * and the destination is HT capable. | ||
| 1919 | */ | ||
| 1920 | ath_tx_send_ampdu(sc, tid, skb, txctl); | ||
| 1921 | } else { | ||
| 1922 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); | ||
| 1923 | if (!bf) { | ||
| 1924 | if (txctl->paprd) | ||
| 1925 | dev_kfree_skb_any(skb); | ||
| 1926 | else | ||
| 1927 | ieee80211_free_txskb(sc->hw, skb); | ||
| 1928 | return; | ||
| 1929 | } | ||
| 1930 | |||
| 1931 | bf->bf_state.bfs_paprd = txctl->paprd; | ||
| 1932 | |||
| 1933 | if (txctl->paprd) | ||
| 1934 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
| 1935 | |||
| 1936 | ath_tx_send_normal(sc, txctl->txq, tid, skb); | ||
| 1937 | } | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | /* Upon failure caller should free skb */ | 1903 | /* Upon failure caller should free skb */ |
| 1941 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | 1904 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, |
| 1942 | struct ath_tx_control *txctl) | 1905 | struct ath_tx_control *txctl) |
| @@ -1947,8 +1910,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1947 | struct ieee80211_vif *vif = info->control.vif; | 1910 | struct ieee80211_vif *vif = info->control.vif; |
| 1948 | struct ath_softc *sc = hw->priv; | 1911 | struct ath_softc *sc = hw->priv; |
| 1949 | struct ath_txq *txq = txctl->txq; | 1912 | struct ath_txq *txq = txctl->txq; |
| 1913 | struct ath_atx_tid *tid = NULL; | ||
| 1914 | struct ath_buf *bf; | ||
| 1950 | int padpos, padsize; | 1915 | int padpos, padsize; |
| 1951 | int frmlen = skb->len + FCS_LEN; | 1916 | int frmlen = skb->len + FCS_LEN; |
| 1917 | u8 tidno; | ||
| 1952 | int q; | 1918 | int q; |
| 1953 | 1919 | ||
| 1954 | /* NOTE: sta can be NULL according to net/mac80211.h */ | 1920 | /* NOTE: sta can be NULL according to net/mac80211.h */ |
| @@ -1971,7 +1937,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1971 | } | 1937 | } |
| 1972 | 1938 | ||
| 1973 | /* Add the padding after the header if this is not already done */ | 1939 | /* Add the padding after the header if this is not already done */ |
| 1974 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 1940 | padpos = ieee80211_hdrlen(hdr->frame_control); |
| 1975 | padsize = padpos & 3; | 1941 | padsize = padpos & 3; |
| 1976 | if (padsize && skb->len > padpos) { | 1942 | if (padsize && skb->len > padpos) { |
| 1977 | if (skb_headroom(skb) < padsize) | 1943 | if (skb_headroom(skb) < padsize) |
| @@ -2004,8 +1970,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2004 | txq->stopped = true; | 1970 | txq->stopped = true; |
| 2005 | } | 1971 | } |
| 2006 | 1972 | ||
| 2007 | ath_tx_start_dma(sc, skb, txctl); | 1973 | if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { |
| 1974 | tidno = ieee80211_get_qos_ctl(hdr)[0] & | ||
| 1975 | IEEE80211_QOS_CTL_TID_MASK; | ||
| 1976 | tid = ATH_AN_2_TID(txctl->an, tidno); | ||
| 1977 | |||
| 1978 | WARN_ON(tid->ac->txq != txctl->txq); | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { | ||
| 1982 | /* | ||
| 1983 | * Try aggregation if it's a unicast data frame | ||
| 1984 | * and the destination is HT capable. | ||
| 1985 | */ | ||
| 1986 | ath_tx_send_ampdu(sc, tid, skb, txctl); | ||
| 1987 | goto out; | ||
| 1988 | } | ||
| 2008 | 1989 | ||
| 1990 | bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); | ||
| 1991 | if (!bf) { | ||
| 1992 | if (txctl->paprd) | ||
| 1993 | dev_kfree_skb_any(skb); | ||
| 1994 | else | ||
| 1995 | ieee80211_free_txskb(sc->hw, skb); | ||
| 1996 | goto out; | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | bf->bf_state.bfs_paprd = txctl->paprd; | ||
| 2000 | |||
| 2001 | if (txctl->paprd) | ||
| 2002 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
| 2003 | |||
| 2004 | ath_set_rates(vif, sta, bf); | ||
| 2005 | ath_tx_send_normal(sc, txctl->txq, tid, skb); | ||
| 2006 | |||
| 2007 | out: | ||
| 2009 | ath_txq_unlock(sc, txq); | 2008 | ath_txq_unlock(sc, txq); |
| 2010 | 2009 | ||
| 2011 | return 0; | 2010 | return 0; |
| @@ -2033,7 +2032,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
| 2033 | /* Frame was ACKed */ | 2032 | /* Frame was ACKed */ |
| 2034 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 2033 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
| 2035 | 2034 | ||
| 2036 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 2035 | padpos = ieee80211_hdrlen(hdr->frame_control); |
| 2037 | padsize = padpos & 3; | 2036 | padsize = padpos & 3; |
| 2038 | if (padsize && skb->len>padpos+padsize) { | 2037 | if (padsize && skb->len>padpos+padsize) { |
| 2039 | /* | 2038 | /* |
| @@ -2264,6 +2263,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2264 | struct ath_txq *txq; | 2263 | struct ath_txq *txq; |
| 2265 | struct ath_buf *bf, *lastbf; | 2264 | struct ath_buf *bf, *lastbf; |
| 2266 | struct list_head bf_head; | 2265 | struct list_head bf_head; |
| 2266 | struct list_head *fifo_list; | ||
| 2267 | int status; | 2267 | int status; |
| 2268 | 2268 | ||
| 2269 | for (;;) { | 2269 | for (;;) { |
| @@ -2291,20 +2291,24 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2291 | 2291 | ||
| 2292 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | 2292 | TX_STAT_INC(txq->axq_qnum, txprocdesc); |
| 2293 | 2293 | ||
| 2294 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 2294 | fifo_list = &txq->txq_fifo[txq->txq_tailidx]; |
| 2295 | if (list_empty(fifo_list)) { | ||
| 2295 | ath_txq_unlock(sc, txq); | 2296 | ath_txq_unlock(sc, txq); |
| 2296 | return; | 2297 | return; |
| 2297 | } | 2298 | } |
| 2298 | 2299 | ||
| 2299 | bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], | 2300 | bf = list_first_entry(fifo_list, struct ath_buf, list); |
| 2300 | struct ath_buf, list); | 2301 | if (bf->bf_stale) { |
| 2302 | list_del(&bf->list); | ||
| 2303 | ath_tx_return_buffer(sc, bf); | ||
| 2304 | bf = list_first_entry(fifo_list, struct ath_buf, list); | ||
| 2305 | } | ||
| 2306 | |||
| 2301 | lastbf = bf->bf_lastbf; | 2307 | lastbf = bf->bf_lastbf; |
| 2302 | 2308 | ||
| 2303 | INIT_LIST_HEAD(&bf_head); | 2309 | INIT_LIST_HEAD(&bf_head); |
| 2304 | list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], | 2310 | if (list_is_last(&lastbf->list, fifo_list)) { |
| 2305 | &lastbf->list); | 2311 | list_splice_tail_init(fifo_list, &bf_head); |
| 2306 | |||
| 2307 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | ||
| 2308 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | 2312 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); |
| 2309 | 2313 | ||
| 2310 | if (!list_empty(&txq->axq_q)) { | 2314 | if (!list_empty(&txq->axq_q)) { |
| @@ -2315,6 +2319,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2315 | list_splice_tail_init(&txq->axq_q, &bf_q); | 2319 | list_splice_tail_init(&txq->axq_q, &bf_q); |
| 2316 | ath_tx_txqaddbuf(sc, txq, &bf_q, true); | 2320 | ath_tx_txqaddbuf(sc, txq, &bf_q, true); |
| 2317 | } | 2321 | } |
| 2322 | } else { | ||
| 2323 | lastbf->bf_stale = true; | ||
| 2324 | if (bf != lastbf) | ||
| 2325 | list_cut_position(&bf_head, fifo_list, | ||
| 2326 | lastbf->list.prev); | ||
| 2318 | } | 2327 | } |
| 2319 | 2328 | ||
| 2320 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); | 2329 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); |
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 40109be81f7c..3d70cd277fd7 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c | |||
| @@ -654,8 +654,8 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf, | |||
| 654 | goto out; | 654 | goto out; |
| 655 | 655 | ||
| 656 | case 'P': | 656 | case 'P': |
| 657 | err = carl9170_set_channel(ar, ar->hw->conf.channel, | 657 | err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan, |
| 658 | ar->hw->conf.channel_type); | 658 | cfg80211_get_chandef_type(&ar->hw->conf.chandef)); |
| 659 | if (err < 0) | 659 | if (err < 0) |
| 660 | count = err; | 660 | count = err; |
| 661 | 661 | ||
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index 24d75ab94f0d..a2f005703c04 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c | |||
| @@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) | |||
| 48 | if (conf_is_ht40(&ar->hw->conf)) | 48 | if (conf_is_ht40(&ar->hw->conf)) |
| 49 | val = 0x010a; | 49 | val = 0x010a; |
| 50 | else { | 50 | else { |
| 51 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) | 51 | if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 52 | val = 0x105; | 52 | val = 0x105; |
| 53 | else | 53 | else |
| 54 | val = 0x104; | 54 | val = 0x104; |
| @@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar) | |||
| 66 | rts_rate = 0x1da; | 66 | rts_rate = 0x1da; |
| 67 | cts_rate = 0x10a; | 67 | cts_rate = 0x10a; |
| 68 | } else { | 68 | } else { |
| 69 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { | 69 | if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { |
| 70 | /* 11 mbit CCK */ | 70 | /* 11 mbit CCK */ |
| 71 | rts_rate = 033; | 71 | rts_rate = 033; |
| 72 | cts_rate = 003; | 72 | cts_rate = 003; |
| @@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar) | |||
| 93 | return 0; | 93 | return 0; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || | 96 | if ((ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) || |
| 97 | vif->bss_conf.use_short_slot) | 97 | vif->bss_conf.use_short_slot) |
| 98 | slottime = 9; | 98 | slottime = 9; |
| 99 | 99 | ||
| @@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar) | |||
| 120 | basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; | 120 | basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; |
| 121 | rcu_read_unlock(); | 121 | rcu_read_unlock(); |
| 122 | 122 | ||
| 123 | if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) | 123 | if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) |
| 124 | mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ | 124 | mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ |
| 125 | else | 125 | else |
| 126 | mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ | 126 | mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 699c557bc2c7..e9010a481dfd 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
| @@ -929,6 +929,9 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 929 | } | 929 | } |
| 930 | 930 | ||
| 931 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 931 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 932 | enum nl80211_channel_type channel_type = | ||
| 933 | cfg80211_get_chandef_type(&hw->conf.chandef); | ||
| 934 | |||
| 932 | /* adjust slot time for 5 GHz */ | 935 | /* adjust slot time for 5 GHz */ |
| 933 | err = carl9170_set_slot_time(ar); | 936 | err = carl9170_set_slot_time(ar); |
| 934 | if (err) | 937 | if (err) |
| @@ -938,8 +941,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 938 | if (err) | 941 | if (err) |
| 939 | goto out; | 942 | goto out; |
| 940 | 943 | ||
| 941 | err = carl9170_set_channel(ar, hw->conf.channel, | 944 | err = carl9170_set_channel(ar, hw->conf.chandef.chan, |
| 942 | hw->conf.channel_type); | 945 | channel_type); |
| 943 | if (err) | 946 | if (err) |
| 944 | goto out; | 947 | goto out; |
| 945 | 948 | ||
| @@ -957,7 +960,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 957 | } | 960 | } |
| 958 | 961 | ||
| 959 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 962 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
| 960 | err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); | 963 | err = carl9170_set_mac_tpc(ar, ar->hw->conf.chandef.chan); |
| 961 | if (err) | 964 | if (err) |
| 962 | goto out; | 965 | goto out; |
| 963 | } | 966 | } |
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 07f82234c860..ab4ee7d39ad3 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c | |||
| @@ -1331,7 +1331,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) | |||
| 1331 | * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. | 1331 | * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. |
| 1332 | */ | 1332 | */ |
| 1333 | ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, | 1333 | ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, |
| 1334 | ar->hw->conf.channel->band); | 1334 | ar->hw->conf.chandef.chan->band); |
| 1335 | 1335 | ||
| 1336 | /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ | 1336 | /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ |
| 1337 | if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) | 1337 | if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) |
| @@ -1341,7 +1341,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) | |||
| 1341 | /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ | 1341 | /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ |
| 1342 | return; | 1342 | return; |
| 1343 | 1343 | ||
| 1344 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { | 1344 | if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { |
| 1345 | modes = mode_list_2ghz; | 1345 | modes = mode_list_2ghz; |
| 1346 | nr_modes = ARRAY_SIZE(mode_list_2ghz); | 1346 | nr_modes = ARRAY_SIZE(mode_list_2ghz); |
| 1347 | } else { | 1347 | } else { |
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index 39e8a590d7fc..eae9abf540a7 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c | |||
| @@ -118,6 +118,12 @@ | |||
| 118 | void ath_hw_setbssidmask(struct ath_common *common) | 118 | void ath_hw_setbssidmask(struct ath_common *common) |
| 119 | { | 119 | { |
| 120 | void *ah = common->ah; | 120 | void *ah = common->ah; |
| 121 | u32 id1; | ||
| 122 | |||
| 123 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | ||
| 124 | id1 = REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_SADH_MASK; | ||
| 125 | id1 |= get_unaligned_le16(common->macaddr + 4); | ||
| 126 | REG_WRITE(ah, AR_STA_ID1, id1); | ||
| 121 | 127 | ||
| 122 | REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); | 128 | REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); |
| 123 | REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); | 129 | REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); |
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h index 298e53f3fa48..3ad4c774bd22 100644 --- a/drivers/net/wireless/ath/reg.h +++ b/drivers/net/wireless/ath/reg.h | |||
| @@ -23,6 +23,10 @@ | |||
| 23 | #define AR_MIBC_CMC 0x00000004 | 23 | #define AR_MIBC_CMC 0x00000004 |
| 24 | #define AR_MIBC_MCS 0x00000008 | 24 | #define AR_MIBC_MCS 0x00000008 |
| 25 | 25 | ||
| 26 | #define AR_STA_ID0 0x8000 | ||
| 27 | #define AR_STA_ID1 0x8004 | ||
| 28 | #define AR_STA_ID1_SADH_MASK 0x0000ffff | ||
| 29 | |||
| 26 | /* | 30 | /* |
| 27 | * BSSID mask registers. See ath_hw_set_bssid_mask() | 31 | * BSSID mask registers. See ath_hw_set_bssid_mask() |
| 28 | * for detailed documentation about these registers. | 32 | * for detailed documentation about these registers. |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 79d4e3271b00..797024507c71 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
| @@ -191,8 +191,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, | |||
| 191 | * - Phy info | 191 | * - Phy info |
| 192 | */ | 192 | */ |
| 193 | static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, | 193 | static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, |
| 194 | struct sk_buff *skb, | 194 | struct sk_buff *skb) |
| 195 | volatile struct vring_rx_desc *d) | ||
| 196 | { | 195 | { |
| 197 | struct wireless_dev *wdev = wil->wdev; | 196 | struct wireless_dev *wdev = wil->wdev; |
| 198 | struct wil6210_rtap { | 197 | struct wil6210_rtap { |
| @@ -216,6 +215,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, | |||
| 216 | __le16 vendor_skip; | 215 | __le16 vendor_skip; |
| 217 | u8 vendor_data[0]; | 216 | u8 vendor_data[0]; |
| 218 | } __packed; | 217 | } __packed; |
| 218 | struct vring_rx_desc *d = wil_skb_rxdesc(skb); | ||
| 219 | struct wil6210_rtap_vendor *rtap_vendor; | 219 | struct wil6210_rtap_vendor *rtap_vendor; |
| 220 | int rtap_len = sizeof(struct wil6210_rtap); | 220 | int rtap_len = sizeof(struct wil6210_rtap); |
| 221 | int phy_length = 0; /* phy info header size, bytes */ | 221 | int phy_length = 0; /* phy info header size, bytes */ |
| @@ -312,6 +312,8 @@ static void wil_swap_ethaddr(void *data) | |||
| 312 | /** | 312 | /** |
| 313 | * reap 1 frame from @swhead | 313 | * reap 1 frame from @swhead |
| 314 | * | 314 | * |
| 315 | * Rx descriptor copied to skb->cb | ||
| 316 | * | ||
| 315 | * Safe to call from IRQ | 317 | * Safe to call from IRQ |
| 316 | */ | 318 | */ |
| 317 | static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | 319 | static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, |
| @@ -320,12 +322,15 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
| 320 | struct device *dev = wil_to_dev(wil); | 322 | struct device *dev = wil_to_dev(wil); |
| 321 | struct net_device *ndev = wil_to_ndev(wil); | 323 | struct net_device *ndev = wil_to_ndev(wil); |
| 322 | volatile struct vring_rx_desc *d; | 324 | volatile struct vring_rx_desc *d; |
| 325 | struct vring_rx_desc *d1; | ||
| 323 | struct sk_buff *skb; | 326 | struct sk_buff *skb; |
| 324 | dma_addr_t pa; | 327 | dma_addr_t pa; |
| 325 | unsigned int sz = RX_BUF_LEN; | 328 | unsigned int sz = RX_BUF_LEN; |
| 326 | u8 ftype; | 329 | u8 ftype; |
| 327 | u8 ds_bits; | 330 | u8 ds_bits; |
| 328 | 331 | ||
| 332 | BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); | ||
| 333 | |||
| 329 | if (wil_vring_is_empty(vring)) | 334 | if (wil_vring_is_empty(vring)) |
| 330 | return NULL; | 335 | return NULL; |
| 331 | 336 | ||
| @@ -340,11 +345,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
| 340 | dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); | 345 | dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); |
| 341 | skb_trim(skb, d->dma.length); | 346 | skb_trim(skb, d->dma.length); |
| 342 | 347 | ||
| 343 | wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); | 348 | d1 = wil_skb_rxdesc(skb); |
| 349 | *d1 = *d; | ||
| 350 | |||
| 351 | wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1); | ||
| 344 | 352 | ||
| 345 | /* use radiotap header only if required */ | 353 | /* use radiotap header only if required */ |
| 346 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) | 354 | if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) |
| 347 | wil_rx_add_radiotap_header(wil, skb, d); | 355 | wil_rx_add_radiotap_header(wil, skb); |
| 348 | 356 | ||
| 349 | wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); | 357 | wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); |
| 350 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, | 358 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, |
| @@ -360,7 +368,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
| 360 | * Driver should recognize it by frame type, that is found | 368 | * Driver should recognize it by frame type, that is found |
| 361 | * in Rx descriptor. If type is not data, it is 802.11 frame as is | 369 | * in Rx descriptor. If type is not data, it is 802.11 frame as is |
| 362 | */ | 370 | */ |
| 363 | ftype = wil_rxdesc_ftype(d) << 2; | 371 | ftype = wil_rxdesc_ftype(d1) << 2; |
| 364 | if (ftype != IEEE80211_FTYPE_DATA) { | 372 | if (ftype != IEEE80211_FTYPE_DATA) { |
| 365 | wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); | 373 | wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); |
| 366 | /* TODO: process it */ | 374 | /* TODO: process it */ |
| @@ -375,7 +383,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
| 375 | return NULL; | 383 | return NULL; |
| 376 | } | 384 | } |
| 377 | 385 | ||
| 378 | ds_bits = wil_rxdesc_ds_bits(d); | 386 | ds_bits = wil_rxdesc_ds_bits(d1); |
| 379 | if (ds_bits == 1) { | 387 | if (ds_bits == 1) { |
| 380 | /* | 388 | /* |
| 381 | * HW bug - in ToDS mode, i.e. Rx on AP side, | 389 | * HW bug - in ToDS mode, i.e. Rx on AP side, |
| @@ -517,6 +525,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
| 517 | .vring_cfg = { | 525 | .vring_cfg = { |
| 518 | .tx_sw_ring = { | 526 | .tx_sw_ring = { |
| 519 | .max_mpdu_size = cpu_to_le16(TX_BUF_LEN), | 527 | .max_mpdu_size = cpu_to_le16(TX_BUF_LEN), |
| 528 | .ring_size = cpu_to_le16(size), | ||
| 520 | }, | 529 | }, |
| 521 | .ringid = id, | 530 | .ringid = id, |
| 522 | .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), | 531 | .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), |
| @@ -548,7 +557,6 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
| 548 | goto out; | 557 | goto out; |
| 549 | 558 | ||
| 550 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); | 559 | cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); |
| 551 | cmd.vring_cfg.tx_sw_ring.ring_size = cpu_to_le16(vring->size); | ||
| 552 | 560 | ||
| 553 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), | 561 | rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), |
| 554 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); | 562 | WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); |
| @@ -779,9 +787,14 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid) | |||
| 779 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); | 787 | wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); |
| 780 | 788 | ||
| 781 | while (!wil_vring_is_empty(vring)) { | 789 | while (!wil_vring_is_empty(vring)) { |
| 782 | volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx; | 790 | volatile struct vring_tx_desc *d1 = |
| 791 | &vring->va[vring->swtail].tx; | ||
| 792 | struct vring_tx_desc dd, *d = ⅆ | ||
| 783 | dma_addr_t pa; | 793 | dma_addr_t pa; |
| 784 | struct sk_buff *skb; | 794 | struct sk_buff *skb; |
| 795 | |||
| 796 | dd = *d1; | ||
| 797 | |||
| 785 | if (!(d->dma.status & TX_DMA_STATUS_DU)) | 798 | if (!(d->dma.status & TX_DMA_STATUS_DU)) |
| 786 | break; | 799 | break; |
| 787 | 800 | ||
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index 45a61f597c5c..adef12fb2aee 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h | |||
| @@ -339,24 +339,59 @@ union vring_desc { | |||
| 339 | struct vring_rx_desc rx; | 339 | struct vring_rx_desc rx; |
| 340 | } __packed; | 340 | } __packed; |
| 341 | 341 | ||
| 342 | static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) | 342 | static inline int wil_rxdesc_tid(struct vring_rx_desc *d) |
| 343 | { | 343 | { |
| 344 | return WIL_GET_BITS(d->dma.d0, 16, 29); | 344 | return WIL_GET_BITS(d->mac.d0, 0, 3); |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) | 347 | static inline int wil_rxdesc_cid(struct vring_rx_desc *d) |
| 348 | { | 348 | { |
| 349 | return WIL_GET_BITS(d->mac.d1, 21, 24); | 349 | return WIL_GET_BITS(d->mac.d0, 4, 6); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) | 352 | static inline int wil_rxdesc_mid(struct vring_rx_desc *d) |
| 353 | { | 353 | { |
| 354 | return WIL_GET_BITS(d->mac.d1, 8, 9); | 354 | return WIL_GET_BITS(d->mac.d0, 8, 9); |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) | 357 | static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) |
| 358 | { | 358 | { |
| 359 | return WIL_GET_BITS(d->mac.d0, 10, 11); | 359 | return WIL_GET_BITS(d->mac.d0, 10, 11); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | static inline int wil_rxdesc_subtype(struct vring_rx_desc *d) | ||
| 363 | { | ||
| 364 | return WIL_GET_BITS(d->mac.d0, 12, 15); | ||
| 365 | } | ||
| 366 | |||
| 367 | static inline int wil_rxdesc_seq(struct vring_rx_desc *d) | ||
| 368 | { | ||
| 369 | return WIL_GET_BITS(d->mac.d0, 16, 27); | ||
| 370 | } | ||
| 371 | |||
| 372 | static inline int wil_rxdesc_ext_subtype(struct vring_rx_desc *d) | ||
| 373 | { | ||
| 374 | return WIL_GET_BITS(d->mac.d0, 28, 31); | ||
| 375 | } | ||
| 376 | |||
| 377 | static inline int wil_rxdesc_ds_bits(struct vring_rx_desc *d) | ||
| 378 | { | ||
| 379 | return WIL_GET_BITS(d->mac.d1, 8, 9); | ||
| 380 | } | ||
| 381 | |||
| 382 | static inline int wil_rxdesc_mcs(struct vring_rx_desc *d) | ||
| 383 | { | ||
| 384 | return WIL_GET_BITS(d->mac.d1, 21, 24); | ||
| 385 | } | ||
| 386 | |||
| 387 | static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d) | ||
| 388 | { | ||
| 389 | return WIL_GET_BITS(d->dma.d0, 16, 29); | ||
| 390 | } | ||
| 391 | |||
| 392 | static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb) | ||
| 393 | { | ||
| 394 | return (void *)skb->cb; | ||
| 395 | } | ||
| 396 | |||
| 362 | #endif /* WIL6210_TXRX_H */ | 397 | #endif /* WIL6210_TXRX_H */ |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f5e840104f4b..7f3d461f7e8d 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
| @@ -980,7 +980,7 @@ static inline int b43_is_mode(struct b43_wl *wl, int type) | |||
| 980 | */ | 980 | */ |
| 981 | static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) | 981 | static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) |
| 982 | { | 982 | { |
| 983 | return wl->hw->conf.channel->band; | 983 | return wl->hw->conf.chandef.chan->band; |
| 984 | } | 984 | } |
| 985 | 985 | ||
| 986 | static inline int b43_bus_may_powerdown(struct b43_wldev *wldev) | 986 | static inline int b43_bus_may_powerdown(struct b43_wldev *wldev) |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4ac73d2f8605..d377f77d30b5 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
| @@ -3852,7 +3852,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 3852 | dev = wl->current_dev; | 3852 | dev = wl->current_dev; |
| 3853 | 3853 | ||
| 3854 | /* Switch the band (if necessary). This might change the active core. */ | 3854 | /* Switch the band (if necessary). This might change the active core. */ |
| 3855 | err = b43_switch_band(wl, conf->channel); | 3855 | err = b43_switch_band(wl, conf->chandef.chan); |
| 3856 | if (err) | 3856 | if (err) |
| 3857 | goto out_unlock_mutex; | 3857 | goto out_unlock_mutex; |
| 3858 | 3858 | ||
| @@ -3882,8 +3882,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 3882 | 3882 | ||
| 3883 | /* Switch to the requested channel. | 3883 | /* Switch to the requested channel. |
| 3884 | * The firmware takes care of races with the TX handler. */ | 3884 | * The firmware takes care of races with the TX handler. */ |
| 3885 | if (conf->channel->hw_value != phy->channel) | 3885 | if (conf->chandef.chan->hw_value != phy->channel) |
| 3886 | b43_switch_channel(dev, conf->channel->hw_value); | 3886 | b43_switch_channel(dev, conf->chandef.chan->hw_value); |
| 3887 | 3887 | ||
| 3888 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); | 3888 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); |
| 3889 | 3889 | ||
| @@ -5006,7 +5006,7 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 5006 | if (idx != 0) | 5006 | if (idx != 0) |
| 5007 | return -ENOENT; | 5007 | return -ENOENT; |
| 5008 | 5008 | ||
| 5009 | survey->channel = conf->channel; | 5009 | survey->channel = conf->chandef.chan; |
| 5010 | survey->filled = SURVEY_INFO_NOISE_DBM; | 5010 | survey->filled = SURVEY_INFO_NOISE_DBM; |
| 5011 | survey->noise = dev->stats.link_noise; | 5011 | survey->noise = dev->stats.link_noise; |
| 5012 | 5012 | ||
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index b8667706fc27..5d6833f18498 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c | |||
| @@ -30,6 +30,17 @@ | |||
| 30 | #include "radio_2059.h" | 30 | #include "radio_2059.h" |
| 31 | #include "main.h" | 31 | #include "main.h" |
| 32 | 32 | ||
| 33 | /* Force values to keep compatibility with wl */ | ||
| 34 | enum ht_rssi_type { | ||
| 35 | HT_RSSI_W1 = 0, | ||
| 36 | HT_RSSI_W2 = 1, | ||
| 37 | HT_RSSI_NB = 2, | ||
| 38 | HT_RSSI_IQ = 3, | ||
| 39 | HT_RSSI_TSSI_2G = 4, | ||
| 40 | HT_RSSI_TSSI_5G = 5, | ||
| 41 | HT_RSSI_TBD = 6, | ||
| 42 | }; | ||
| 43 | |||
| 33 | /************************************************** | 44 | /************************************************** |
| 34 | * Radio 2059. | 45 | * Radio 2059. |
| 35 | **************************************************/ | 46 | **************************************************/ |
| @@ -37,8 +48,9 @@ | |||
| 37 | static void b43_radio_2059_channel_setup(struct b43_wldev *dev, | 48 | static void b43_radio_2059_channel_setup(struct b43_wldev *dev, |
| 38 | const struct b43_phy_ht_channeltab_e_radio2059 *e) | 49 | const struct b43_phy_ht_channeltab_e_radio2059 *e) |
| 39 | { | 50 | { |
| 40 | u8 i; | 51 | static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3, }; |
| 41 | u16 routing; | 52 | u16 r; |
| 53 | int core; | ||
| 42 | 54 | ||
| 43 | b43_radio_write(dev, 0x16, e->radio_syn16); | 55 | b43_radio_write(dev, 0x16, e->radio_syn16); |
| 44 | b43_radio_write(dev, 0x17, e->radio_syn17); | 56 | b43_radio_write(dev, 0x17, e->radio_syn17); |
| @@ -53,25 +65,17 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, | |||
| 53 | b43_radio_write(dev, 0x41, e->radio_syn41); | 65 | b43_radio_write(dev, 0x41, e->radio_syn41); |
| 54 | b43_radio_write(dev, 0x43, e->radio_syn43); | 66 | b43_radio_write(dev, 0x43, e->radio_syn43); |
| 55 | b43_radio_write(dev, 0x47, e->radio_syn47); | 67 | b43_radio_write(dev, 0x47, e->radio_syn47); |
| 56 | b43_radio_write(dev, 0x4a, e->radio_syn4a); | 68 | |
| 57 | b43_radio_write(dev, 0x58, e->radio_syn58); | 69 | for (core = 0; core < 3; core++) { |
| 58 | b43_radio_write(dev, 0x5a, e->radio_syn5a); | 70 | r = routing[core]; |
| 59 | b43_radio_write(dev, 0x6a, e->radio_syn6a); | 71 | b43_radio_write(dev, r | 0x4a, e->radio_rxtx4a); |
| 60 | b43_radio_write(dev, 0x6d, e->radio_syn6d); | 72 | b43_radio_write(dev, r | 0x58, e->radio_rxtx58); |
| 61 | b43_radio_write(dev, 0x6e, e->radio_syn6e); | 73 | b43_radio_write(dev, r | 0x5a, e->radio_rxtx5a); |
| 62 | b43_radio_write(dev, 0x92, e->radio_syn92); | 74 | b43_radio_write(dev, r | 0x6a, e->radio_rxtx6a); |
| 63 | b43_radio_write(dev, 0x98, e->radio_syn98); | 75 | b43_radio_write(dev, r | 0x6d, e->radio_rxtx6d); |
| 64 | 76 | b43_radio_write(dev, r | 0x6e, e->radio_rxtx6e); | |
| 65 | for (i = 0; i < 2; i++) { | 77 | b43_radio_write(dev, r | 0x92, e->radio_rxtx92); |
| 66 | routing = i ? R2059_RXRX1 : R2059_TXRX0; | 78 | b43_radio_write(dev, r | 0x98, e->radio_rxtx98); |
| 67 | b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); | ||
| 68 | b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); | ||
| 69 | b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); | ||
| 70 | b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a); | ||
| 71 | b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d); | ||
| 72 | b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e); | ||
| 73 | b43_radio_write(dev, routing | 0x92, e->radio_rxtx92); | ||
| 74 | b43_radio_write(dev, routing | 0x98, e->radio_rxtx98); | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | udelay(50); | 81 | udelay(50); |
| @@ -87,7 +91,7 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, | |||
| 87 | 91 | ||
| 88 | static void b43_radio_2059_init(struct b43_wldev *dev) | 92 | static void b43_radio_2059_init(struct b43_wldev *dev) |
| 89 | { | 93 | { |
| 90 | const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; | 94 | const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 }; |
| 91 | const u16 radio_values[3][2] = { | 95 | const u16 radio_values[3][2] = { |
| 92 | { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, | 96 | { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, |
| 93 | }; | 97 | }; |
| @@ -106,17 +110,17 @@ static void b43_radio_2059_init(struct b43_wldev *dev) | |||
| 106 | b43_radio_mask(dev, 0xc0, ~0x0080); | 110 | b43_radio_mask(dev, 0xc0, ~0x0080); |
| 107 | 111 | ||
| 108 | if (1) { /* FIXME */ | 112 | if (1) { /* FIXME */ |
| 109 | b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); | 113 | b43_radio_set(dev, R2059_C3 | 0x4, 0x1); |
| 110 | udelay(10); | 114 | udelay(10); |
| 111 | b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); | 115 | b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1); |
| 112 | b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); | 116 | b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2); |
| 113 | 117 | ||
| 114 | b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); | 118 | b43_radio_set(dev, R2059_C3 | 0x4, 0x2); |
| 115 | udelay(100); | 119 | udelay(100); |
| 116 | b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); | 120 | b43_radio_mask(dev, R2059_C3 | 0x4, ~0x2); |
| 117 | 121 | ||
| 118 | for (i = 0; i < 10000; i++) { | 122 | for (i = 0; i < 10000; i++) { |
| 119 | if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { | 123 | if (b43_radio_read(dev, R2059_C3 | 0x145) & 1) { |
| 120 | i = 0; | 124 | i = 0; |
| 121 | break; | 125 | break; |
| 122 | } | 126 | } |
| @@ -125,7 +129,7 @@ static void b43_radio_2059_init(struct b43_wldev *dev) | |||
| 125 | if (i) | 129 | if (i) |
| 126 | b43err(dev->wl, "radio 0x945 timeout\n"); | 130 | b43err(dev->wl, "radio 0x945 timeout\n"); |
| 127 | 131 | ||
| 128 | b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); | 132 | b43_radio_mask(dev, R2059_C3 | 0x4, ~0x1); |
| 129 | b43_radio_set(dev, 0xa, 0x60); | 133 | b43_radio_set(dev, 0xa, 0x60); |
| 130 | 134 | ||
| 131 | for (i = 0; i < 3; i++) { | 135 | for (i = 0; i < 3; i++) { |
| @@ -390,14 +394,14 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev) | |||
| 390 | **************************************************/ | 394 | **************************************************/ |
| 391 | 395 | ||
| 392 | static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, | 396 | static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, |
| 393 | u8 rssi_type) | 397 | enum ht_rssi_type rssi_type) |
| 394 | { | 398 | { |
| 395 | static const u16 ctl_regs[3][2] = { | 399 | static const u16 ctl_regs[3][2] = { |
| 396 | { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, }, | 400 | { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, }, |
| 397 | { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, }, | 401 | { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, }, |
| 398 | { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, }, | 402 | { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, }, |
| 399 | }; | 403 | }; |
| 400 | static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, }; | 404 | static const u16 radio_r[] = { R2059_C1, R2059_C2, R2059_C3, }; |
| 401 | int core; | 405 | int core; |
| 402 | 406 | ||
| 403 | if (core_sel == 0) { | 407 | if (core_sel == 0) { |
| @@ -411,13 +415,13 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, | |||
| 411 | continue; | 415 | continue; |
| 412 | 416 | ||
| 413 | switch (rssi_type) { | 417 | switch (rssi_type) { |
| 414 | case 4: | 418 | case HT_RSSI_TSSI_2G: |
| 415 | b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8); | 419 | b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8); |
| 416 | b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10); | 420 | b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10); |
| 417 | b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9); | 421 | b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9); |
| 418 | b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10); | 422 | b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10); |
| 419 | 423 | ||
| 420 | b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1); | 424 | b43_radio_set(dev, R2059_C3 | 0xbf, 0x1); |
| 421 | b43_radio_write(dev, radio_r[core] | 0x159, | 425 | b43_radio_write(dev, radio_r[core] | 0x159, |
| 422 | 0x11); | 426 | 0x11); |
| 423 | break; | 427 | break; |
| @@ -429,8 +433,8 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, | |||
| 429 | } | 433 | } |
| 430 | } | 434 | } |
| 431 | 435 | ||
| 432 | static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | 436 | static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, enum ht_rssi_type type, |
| 433 | u8 nsamp) | 437 | s32 *buf, u8 nsamp) |
| 434 | { | 438 | { |
| 435 | u16 phy_regs_values[12]; | 439 | u16 phy_regs_values[12]; |
| 436 | static const u16 phy_regs_to_save[] = { | 440 | static const u16 phy_regs_to_save[] = { |
| @@ -504,15 +508,17 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) | |||
| 504 | static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1, | 508 | static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1, |
| 505 | B43_PHY_HT_TXPCTL_CMD_C2, | 509 | B43_PHY_HT_TXPCTL_CMD_C2, |
| 506 | B43_PHY_HT_TXPCTL_CMD_C3 }; | 510 | B43_PHY_HT_TXPCTL_CMD_C3 }; |
| 511 | static const u16 status_regs[3] = { B43_PHY_HT_TX_PCTL_STATUS_C1, | ||
| 512 | B43_PHY_HT_TX_PCTL_STATUS_C2, | ||
| 513 | B43_PHY_HT_TX_PCTL_STATUS_C3 }; | ||
| 507 | int i; | 514 | int i; |
| 508 | 515 | ||
| 509 | if (!enable) { | 516 | if (!enable) { |
| 510 | if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { | 517 | if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { |
| 511 | /* We disable enabled TX pwr ctl, save it's state */ | 518 | /* We disable enabled TX pwr ctl, save it's state */ |
| 512 | /* | 519 | for (i = 0; i < 3; i++) |
| 513 | * TODO: find the registers. On N-PHY they were 0x1ed | 520 | phy_ht->tx_pwr_idx[i] = |
| 514 | * and 0x1ee, we need 3 such a registers for HT-PHY | 521 | b43_phy_read(dev, status_regs[i]); |
| 515 | */ | ||
| 516 | } | 522 | } |
| 517 | b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); | 523 | b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); |
| 518 | } else { | 524 | } else { |
| @@ -536,13 +542,25 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) | |||
| 536 | static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) | 542 | static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) |
| 537 | { | 543 | { |
| 538 | struct b43_phy_ht *phy_ht = dev->phy.ht; | 544 | struct b43_phy_ht *phy_ht = dev->phy.ht; |
| 545 | static const u16 base[] = { 0x840, 0x860, 0x880 }; | ||
| 546 | u16 save_regs[3][3]; | ||
| 539 | s32 rssi_buf[6]; | 547 | s32 rssi_buf[6]; |
| 548 | int core; | ||
| 549 | |||
| 550 | for (core = 0; core < 3; core++) { | ||
| 551 | save_regs[core][1] = b43_phy_read(dev, base[core] + 6); | ||
| 552 | save_regs[core][2] = b43_phy_read(dev, base[core] + 7); | ||
| 553 | save_regs[core][0] = b43_phy_read(dev, base[core] + 0); | ||
| 540 | 554 | ||
| 541 | /* TODO */ | 555 | b43_phy_write(dev, base[core] + 6, 0); |
| 556 | b43_phy_mask(dev, base[core] + 7, ~0xF); /* 0xF? Or just 0x6? */ | ||
| 557 | b43_phy_set(dev, base[core] + 0, 0x0400); | ||
| 558 | b43_phy_set(dev, base[core] + 0, 0x1000); | ||
| 559 | } | ||
| 542 | 560 | ||
| 543 | b43_phy_ht_tx_tone(dev); | 561 | b43_phy_ht_tx_tone(dev); |
| 544 | udelay(20); | 562 | udelay(20); |
| 545 | b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1); | 563 | b43_phy_ht_poll_rssi(dev, HT_RSSI_TSSI_2G, rssi_buf, 1); |
| 546 | b43_phy_ht_stop_playback(dev); | 564 | b43_phy_ht_stop_playback(dev); |
| 547 | b43_phy_ht_reset_cca(dev); | 565 | b43_phy_ht_reset_cca(dev); |
| 548 | 566 | ||
| @@ -550,7 +568,23 @@ static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) | |||
| 550 | phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff; | 568 | phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff; |
| 551 | phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff; | 569 | phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff; |
| 552 | 570 | ||
| 553 | /* TODO */ | 571 | for (core = 0; core < 3; core++) { |
| 572 | b43_phy_write(dev, base[core] + 0, save_regs[core][0]); | ||
| 573 | b43_phy_write(dev, base[core] + 6, save_regs[core][1]); | ||
| 574 | b43_phy_write(dev, base[core] + 7, save_regs[core][2]); | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
| 578 | static void b43_phy_ht_tssi_setup(struct b43_wldev *dev) | ||
| 579 | { | ||
| 580 | static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3, }; | ||
| 581 | int core; | ||
| 582 | |||
| 583 | /* 0x159 is probably TX_SSI_MUX or TSSIG (by comparing to N-PHY) */ | ||
| 584 | for (core = 0; core < 3; core++) { | ||
| 585 | b43_radio_set(dev, 0x8bf, 0x1); | ||
| 586 | b43_radio_write(dev, routing[core] | 0x0159, 0x0011); | ||
| 587 | } | ||
| 554 | } | 588 | } |
| 555 | 589 | ||
| 556 | static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev) | 590 | static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev) |
| @@ -946,6 +980,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) | |||
| 946 | b43_phy_ht_tx_power_ctl(dev, false); | 980 | b43_phy_ht_tx_power_ctl(dev, false); |
| 947 | b43_phy_ht_tx_power_ctl_idle_tssi(dev); | 981 | b43_phy_ht_tx_power_ctl_idle_tssi(dev); |
| 948 | b43_phy_ht_tx_power_ctl_setup(dev); | 982 | b43_phy_ht_tx_power_ctl_setup(dev); |
| 983 | b43_phy_ht_tssi_setup(dev); | ||
| 949 | b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); | 984 | b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); |
| 950 | 985 | ||
| 951 | return 0; | 986 | return 0; |
| @@ -1011,8 +1046,9 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) | |||
| 1011 | static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, | 1046 | static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, |
| 1012 | unsigned int new_channel) | 1047 | unsigned int new_channel) |
| 1013 | { | 1048 | { |
| 1014 | struct ieee80211_channel *channel = dev->wl->hw->conf.channel; | 1049 | struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; |
| 1015 | enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; | 1050 | enum nl80211_channel_type channel_type = |
| 1051 | cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); | ||
| 1016 | 1052 | ||
| 1017 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 1053 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
| 1018 | if ((new_channel < 1) || (new_channel > 14)) | 1054 | if ((new_channel < 1) || (new_channel > 14)) |
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 9b2408efb224..6cae370d1018 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h | |||
| @@ -23,6 +23,9 @@ | |||
| 23 | #define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ | 23 | #define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ |
| 24 | #define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ | 24 | #define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ |
| 25 | #define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ | 25 | #define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ |
| 26 | #define B43_PHY_HT_EST_PWR_C1 0x118 | ||
| 27 | #define B43_PHY_HT_EST_PWR_C2 0x119 | ||
| 28 | #define B43_PHY_HT_EST_PWR_C3 0x11A | ||
| 26 | #define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */ | 29 | #define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */ |
| 27 | #define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */ | 30 | #define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */ |
| 28 | #define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */ | 31 | #define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */ |
| @@ -53,6 +56,8 @@ | |||
| 53 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0 | 56 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0 |
| 54 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */ | 57 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */ |
| 55 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8 | 58 | #define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8 |
| 59 | #define B43_PHY_HT_TX_PCTL_STATUS_C1 0x1ED | ||
| 60 | #define B43_PHY_HT_TX_PCTL_STATUS_C2 0x1EE | ||
| 56 | #define B43_PHY_HT_TXPCTL_CMD_C2 0x222 | 61 | #define B43_PHY_HT_TXPCTL_CMD_C2 0x222 |
| 57 | #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F | 62 | #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F |
| 58 | #define B43_PHY_HT_RSSI_C1 0x219 | 63 | #define B43_PHY_HT_RSSI_C1 0x219 |
| @@ -97,6 +102,7 @@ | |||
| 97 | #define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */ | 102 | #define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */ |
| 98 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF | 103 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF |
| 99 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 | 104 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 |
| 105 | #define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169) | ||
| 100 | 106 | ||
| 101 | #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) | 107 | #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) |
| 102 | 108 | ||
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index a13e28ef6246..0bafa3b17035 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c | |||
| @@ -808,8 +808,9 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on) | |||
| 808 | static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev, | 808 | static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev, |
| 809 | unsigned int new_channel) | 809 | unsigned int new_channel) |
| 810 | { | 810 | { |
| 811 | struct ieee80211_channel *channel = dev->wl->hw->conf.channel; | 811 | struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; |
| 812 | enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; | 812 | enum nl80211_channel_type channel_type = |
| 813 | cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); | ||
| 813 | 814 | ||
| 814 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 815 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
| 815 | if ((new_channel < 1) || (new_channel > 14)) | 816 | if ((new_channel < 1) || (new_channel > 14)) |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 5ed352ddae9e..92190dacf689 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
| @@ -281,8 +281,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 281 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); | 281 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); |
| 282 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); | 282 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); |
| 283 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || | 283 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || |
| 284 | (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && | 284 | (dev->dev->board_type == SSB_BOARD_BU4312) || |
| 285 | (sprom->boardflags_lo & B43_BFL_FEM))) { | 285 | (dev->phy.rev == 0 && (sprom->boardflags_lo & B43_BFL_FEM))) { |
| 286 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); | 286 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); |
| 287 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); | 287 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); |
| 288 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); | 288 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 63cca9c2bf97..7c970d3ae358 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
| @@ -69,14 +69,27 @@ enum b43_nphy_rf_sequence { | |||
| 69 | B43_RFSEQ_UPDATE_GAINU, | 69 | B43_RFSEQ_UPDATE_GAINU, |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | enum b43_nphy_rssi_type { | 72 | enum n_intc_override { |
| 73 | B43_NPHY_RSSI_X = 0, | 73 | N_INTC_OVERRIDE_OFF = 0, |
| 74 | B43_NPHY_RSSI_Y, | 74 | N_INTC_OVERRIDE_TRSW = 1, |
| 75 | B43_NPHY_RSSI_Z, | 75 | N_INTC_OVERRIDE_PA = 2, |
| 76 | B43_NPHY_RSSI_PWRDET, | 76 | N_INTC_OVERRIDE_EXT_LNA_PU = 3, |
| 77 | B43_NPHY_RSSI_TSSI_I, | 77 | N_INTC_OVERRIDE_EXT_LNA_GAIN = 4, |
| 78 | B43_NPHY_RSSI_TSSI_Q, | 78 | }; |
| 79 | B43_NPHY_RSSI_TBD, | 79 | |
| 80 | enum n_rssi_type { | ||
| 81 | N_RSSI_W1 = 0, | ||
| 82 | N_RSSI_W2, | ||
| 83 | N_RSSI_NB, | ||
| 84 | N_RSSI_IQ, | ||
| 85 | N_RSSI_TSSI_2G, | ||
| 86 | N_RSSI_TSSI_5G, | ||
| 87 | N_RSSI_TBD, | ||
| 88 | }; | ||
| 89 | |||
| 90 | enum n_rail_type { | ||
| 91 | N_RAIL_I = 0, | ||
| 92 | N_RAIL_Q = 1, | ||
| 80 | }; | 93 | }; |
| 81 | 94 | ||
| 82 | static inline bool b43_nphy_ipa(struct b43_wldev *dev) | 95 | static inline bool b43_nphy_ipa(struct b43_wldev *dev) |
| @@ -94,7 +107,7 @@ static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev) | |||
| 94 | } | 107 | } |
| 95 | 108 | ||
| 96 | /************************************************** | 109 | /************************************************** |
| 97 | * RF (just without b43_nphy_rf_control_intc_override) | 110 | * RF (just without b43_nphy_rf_ctl_intc_override) |
| 98 | **************************************************/ | 111 | **************************************************/ |
| 99 | 112 | ||
| 100 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ | 113 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ |
| @@ -128,9 +141,9 @@ ok: | |||
| 128 | } | 141 | } |
| 129 | 142 | ||
| 130 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */ | 143 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */ |
| 131 | static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field, | 144 | static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field, |
| 132 | u16 value, u8 core, bool off, | 145 | u16 value, u8 core, bool off, |
| 133 | u8 override) | 146 | u8 override) |
| 134 | { | 147 | { |
| 135 | const struct nphy_rf_control_override_rev7 *e; | 148 | const struct nphy_rf_control_override_rev7 *e; |
| 136 | u16 en_addrs[3][2] = { | 149 | u16 en_addrs[3][2] = { |
| @@ -168,8 +181,8 @@ static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field, | |||
| 168 | } | 181 | } |
| 169 | 182 | ||
| 170 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ | 183 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ |
| 171 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | 184 | static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field, |
| 172 | u16 value, u8 core, bool off) | 185 | u16 value, u8 core, bool off) |
| 173 | { | 186 | { |
| 174 | int i; | 187 | int i; |
| 175 | u8 index = fls(field); | 188 | u8 index = fls(field); |
| @@ -244,14 +257,14 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | |||
| 244 | } | 257 | } |
| 245 | 258 | ||
| 246 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ | 259 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ |
| 247 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | 260 | static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev, |
| 248 | u16 value, u8 core) | 261 | enum n_intc_override intc_override, |
| 262 | u16 value, u8 core) | ||
| 249 | { | 263 | { |
| 250 | u8 i, j; | 264 | u8 i, j; |
| 251 | u16 reg, tmp, val; | 265 | u16 reg, tmp, val; |
| 252 | 266 | ||
| 253 | B43_WARN_ON(dev->phy.rev < 3); | 267 | B43_WARN_ON(dev->phy.rev < 3); |
| 254 | B43_WARN_ON(field > 4); | ||
| 255 | 268 | ||
| 256 | for (i = 0; i < 2; i++) { | 269 | for (i = 0; i < 2; i++) { |
| 257 | if ((core == 1 && i == 1) || (core == 2 && !i)) | 270 | if ((core == 1 && i == 1) || (core == 2 && !i)) |
| @@ -261,12 +274,12 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | |||
| 261 | B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; | 274 | B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; |
| 262 | b43_phy_set(dev, reg, 0x400); | 275 | b43_phy_set(dev, reg, 0x400); |
| 263 | 276 | ||
| 264 | switch (field) { | 277 | switch (intc_override) { |
| 265 | case 0: | 278 | case N_INTC_OVERRIDE_OFF: |
| 266 | b43_phy_write(dev, reg, 0); | 279 | b43_phy_write(dev, reg, 0); |
| 267 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 280 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
| 268 | break; | 281 | break; |
| 269 | case 1: | 282 | case N_INTC_OVERRIDE_TRSW: |
| 270 | if (!i) { | 283 | if (!i) { |
| 271 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, | 284 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, |
| 272 | 0xFC3F, (value << 6)); | 285 | 0xFC3F, (value << 6)); |
| @@ -307,7 +320,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | |||
| 307 | 0xFFFE); | 320 | 0xFFFE); |
| 308 | } | 321 | } |
| 309 | break; | 322 | break; |
| 310 | case 2: | 323 | case N_INTC_OVERRIDE_PA: |
| 311 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | 324 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { |
| 312 | tmp = 0x0020; | 325 | tmp = 0x0020; |
| 313 | val = value << 5; | 326 | val = value << 5; |
| @@ -317,7 +330,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | |||
| 317 | } | 330 | } |
| 318 | b43_phy_maskset(dev, reg, ~tmp, val); | 331 | b43_phy_maskset(dev, reg, ~tmp, val); |
| 319 | break; | 332 | break; |
| 320 | case 3: | 333 | case N_INTC_OVERRIDE_EXT_LNA_PU: |
| 321 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | 334 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { |
| 322 | tmp = 0x0001; | 335 | tmp = 0x0001; |
| 323 | val = value; | 336 | val = value; |
| @@ -327,7 +340,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | |||
| 327 | } | 340 | } |
| 328 | b43_phy_maskset(dev, reg, ~tmp, val); | 341 | b43_phy_maskset(dev, reg, ~tmp, val); |
| 329 | break; | 342 | break; |
| 330 | case 4: | 343 | case N_INTC_OVERRIDE_EXT_LNA_GAIN: |
| 331 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | 344 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { |
| 332 | tmp = 0x0002; | 345 | tmp = 0x0002; |
| 333 | val = value << 1; | 346 | val = value << 1; |
| @@ -1011,7 +1024,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) | |||
| 1011 | 1024 | ||
| 1012 | if (sprom->revision < 4) | 1025 | if (sprom->revision < 4) |
| 1013 | workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM | 1026 | workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM |
| 1014 | && dev->dev->board_type == 0x46D | 1027 | && dev->dev->board_type == SSB_BOARD_CB2_4321 |
| 1015 | && dev->dev->board_rev >= 0x41); | 1028 | && dev->dev->board_rev >= 0x41); |
| 1016 | else | 1029 | else |
| 1017 | workaround = | 1030 | workaround = |
| @@ -1207,8 +1220,9 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, | |||
| 1207 | 1220 | ||
| 1208 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ | 1221 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ |
| 1209 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | 1222 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, |
| 1210 | s8 offset, u8 core, u8 rail, | 1223 | s8 offset, u8 core, |
| 1211 | enum b43_nphy_rssi_type type) | 1224 | enum n_rail_type rail, |
| 1225 | enum n_rssi_type rssi_type) | ||
| 1212 | { | 1226 | { |
| 1213 | u16 tmp; | 1227 | u16 tmp; |
| 1214 | bool core1or5 = (core == 1) || (core == 5); | 1228 | bool core1or5 = (core == 1) || (core == 5); |
| @@ -1217,63 +1231,74 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | |||
| 1217 | offset = clamp_val(offset, -32, 31); | 1231 | offset = clamp_val(offset, -32, 31); |
| 1218 | tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); | 1232 | tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); |
| 1219 | 1233 | ||
| 1220 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | 1234 | switch (rssi_type) { |
| 1221 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); | 1235 | case N_RSSI_NB: |
| 1222 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | 1236 | if (core1or5 && rail == N_RAIL_I) |
| 1223 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); | 1237 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); |
| 1224 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | 1238 | if (core1or5 && rail == N_RAIL_Q) |
| 1225 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); | 1239 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); |
| 1226 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | 1240 | if (core2or5 && rail == N_RAIL_I) |
| 1227 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); | 1241 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); |
| 1228 | 1242 | if (core2or5 && rail == N_RAIL_Q) | |
| 1229 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | 1243 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); |
| 1230 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); | 1244 | break; |
| 1231 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | 1245 | case N_RSSI_W1: |
| 1232 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); | 1246 | if (core1or5 && rail == N_RAIL_I) |
| 1233 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | 1247 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); |
| 1234 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); | 1248 | if (core1or5 && rail == N_RAIL_Q) |
| 1235 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | 1249 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); |
| 1236 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); | 1250 | if (core2or5 && rail == N_RAIL_I) |
| 1237 | 1251 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); | |
| 1238 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | 1252 | if (core2or5 && rail == N_RAIL_Q) |
| 1239 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); | 1253 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); |
| 1240 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | 1254 | break; |
| 1241 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); | 1255 | case N_RSSI_W2: |
| 1242 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | 1256 | if (core1or5 && rail == N_RAIL_I) |
| 1243 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); | 1257 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); |
| 1244 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | 1258 | if (core1or5 && rail == N_RAIL_Q) |
| 1245 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); | 1259 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); |
| 1246 | 1260 | if (core2or5 && rail == N_RAIL_I) | |
| 1247 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | 1261 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); |
| 1248 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); | 1262 | if (core2or5 && rail == N_RAIL_Q) |
| 1249 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | 1263 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); |
| 1250 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); | 1264 | break; |
| 1251 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | 1265 | case N_RSSI_TBD: |
| 1252 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); | 1266 | if (core1or5 && rail == N_RAIL_I) |
| 1253 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | 1267 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); |
| 1254 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); | 1268 | if (core1or5 && rail == N_RAIL_Q) |
| 1255 | 1269 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); | |
| 1256 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | 1270 | if (core2or5 && rail == N_RAIL_I) |
| 1257 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); | 1271 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); |
| 1258 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | 1272 | if (core2or5 && rail == N_RAIL_Q) |
| 1259 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); | 1273 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); |
| 1260 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | 1274 | break; |
| 1261 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); | 1275 | case N_RSSI_IQ: |
| 1262 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | 1276 | if (core1or5 && rail == N_RAIL_I) |
| 1263 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); | 1277 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); |
| 1264 | 1278 | if (core1or5 && rail == N_RAIL_Q) | |
| 1265 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I)) | 1279 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); |
| 1266 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); | 1280 | if (core2or5 && rail == N_RAIL_I) |
| 1267 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I)) | 1281 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); |
| 1268 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); | 1282 | if (core2or5 && rail == N_RAIL_Q) |
| 1269 | 1283 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); | |
| 1270 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | 1284 | break; |
| 1271 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); | 1285 | case N_RSSI_TSSI_2G: |
| 1272 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | 1286 | if (core1or5) |
| 1273 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | 1287 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); |
| 1288 | if (core2or5) | ||
| 1289 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); | ||
| 1290 | break; | ||
| 1291 | case N_RSSI_TSSI_5G: | ||
| 1292 | if (core1or5) | ||
| 1293 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); | ||
| 1294 | if (core2or5) | ||
| 1295 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | ||
| 1296 | break; | ||
| 1297 | } | ||
| 1274 | } | 1298 | } |
| 1275 | 1299 | ||
| 1276 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | 1300 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, |
| 1301 | enum n_rssi_type rssi_type) | ||
| 1277 | { | 1302 | { |
| 1278 | u8 i; | 1303 | u8 i; |
| 1279 | u16 reg, val; | 1304 | u16 reg, val; |
| @@ -1296,7 +1321,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1296 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; | 1321 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; |
| 1297 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); | 1322 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); |
| 1298 | 1323 | ||
| 1299 | if (type < 3) { | 1324 | if (rssi_type == N_RSSI_W1 || |
| 1325 | rssi_type == N_RSSI_W2 || | ||
| 1326 | rssi_type == N_RSSI_NB) { | ||
| 1300 | reg = (i == 0) ? | 1327 | reg = (i == 0) ? |
| 1301 | B43_NPHY_AFECTL_C1 : | 1328 | B43_NPHY_AFECTL_C1 : |
| 1302 | B43_NPHY_AFECTL_C2; | 1329 | B43_NPHY_AFECTL_C2; |
| @@ -1307,9 +1334,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1307 | B43_NPHY_RFCTL_LUT_TRSW_UP2; | 1334 | B43_NPHY_RFCTL_LUT_TRSW_UP2; |
| 1308 | b43_phy_maskset(dev, reg, 0xFFC3, 0); | 1335 | b43_phy_maskset(dev, reg, 0xFFC3, 0); |
| 1309 | 1336 | ||
| 1310 | if (type == 0) | 1337 | if (rssi_type == N_RSSI_W1) |
| 1311 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; | 1338 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; |
| 1312 | else if (type == 1) | 1339 | else if (rssi_type == N_RSSI_W2) |
| 1313 | val = 16; | 1340 | val = 16; |
| 1314 | else | 1341 | else |
| 1315 | val = 32; | 1342 | val = 32; |
| @@ -1320,9 +1347,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1320 | B43_NPHY_TXF_40CO_B32S1; | 1347 | B43_NPHY_TXF_40CO_B32S1; |
| 1321 | b43_phy_set(dev, reg, 0x0020); | 1348 | b43_phy_set(dev, reg, 0x0020); |
| 1322 | } else { | 1349 | } else { |
| 1323 | if (type == 6) | 1350 | if (rssi_type == N_RSSI_TBD) |
| 1324 | val = 0x0100; | 1351 | val = 0x0100; |
| 1325 | else if (type == 3) | 1352 | else if (rssi_type == N_RSSI_IQ) |
| 1326 | val = 0x0200; | 1353 | val = 0x0200; |
| 1327 | else | 1354 | else |
| 1328 | val = 0x0300; | 1355 | val = 0x0300; |
| @@ -1334,7 +1361,8 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1334 | b43_phy_maskset(dev, reg, 0xFCFF, val); | 1361 | b43_phy_maskset(dev, reg, 0xFCFF, val); |
| 1335 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); | 1362 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); |
| 1336 | 1363 | ||
| 1337 | if (type != 3 && type != 6) { | 1364 | if (rssi_type != N_RSSI_IQ && |
| 1365 | rssi_type != N_RSSI_TBD) { | ||
| 1338 | enum ieee80211_band band = | 1366 | enum ieee80211_band band = |
| 1339 | b43_current_band(dev->wl); | 1367 | b43_current_band(dev->wl); |
| 1340 | 1368 | ||
| @@ -1344,7 +1372,7 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1344 | val = 0x11; | 1372 | val = 0x11; |
| 1345 | reg = (i == 0) ? 0x2000 : 0x3000; | 1373 | reg = (i == 0) ? 0x2000 : 0x3000; |
| 1346 | reg |= B2055_PADDRV; | 1374 | reg |= B2055_PADDRV; |
| 1347 | b43_radio_write16(dev, reg, val); | 1375 | b43_radio_write(dev, reg, val); |
| 1348 | 1376 | ||
| 1349 | reg = (i == 0) ? | 1377 | reg = (i == 0) ? |
| 1350 | B43_NPHY_AFECTL_OVER1 : | 1378 | B43_NPHY_AFECTL_OVER1 : |
| @@ -1356,33 +1384,43 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1356 | } | 1384 | } |
| 1357 | } | 1385 | } |
| 1358 | 1386 | ||
| 1359 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | 1387 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, |
| 1388 | enum n_rssi_type rssi_type) | ||
| 1360 | { | 1389 | { |
| 1361 | u16 val; | 1390 | u16 val; |
| 1391 | bool rssi_w1_w2_nb = false; | ||
| 1362 | 1392 | ||
| 1363 | if (type < 3) | 1393 | switch (rssi_type) { |
| 1394 | case N_RSSI_W1: | ||
| 1395 | case N_RSSI_W2: | ||
| 1396 | case N_RSSI_NB: | ||
| 1364 | val = 0; | 1397 | val = 0; |
| 1365 | else if (type == 6) | 1398 | rssi_w1_w2_nb = true; |
| 1399 | break; | ||
| 1400 | case N_RSSI_TBD: | ||
| 1366 | val = 1; | 1401 | val = 1; |
| 1367 | else if (type == 3) | 1402 | break; |
| 1403 | case N_RSSI_IQ: | ||
| 1368 | val = 2; | 1404 | val = 2; |
| 1369 | else | 1405 | break; |
| 1406 | default: | ||
| 1370 | val = 3; | 1407 | val = 3; |
| 1408 | } | ||
| 1371 | 1409 | ||
| 1372 | val = (val << 12) | (val << 14); | 1410 | val = (val << 12) | (val << 14); |
| 1373 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); | 1411 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); |
| 1374 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); | 1412 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); |
| 1375 | 1413 | ||
| 1376 | if (type < 3) { | 1414 | if (rssi_w1_w2_nb) { |
| 1377 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | 1415 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, |
| 1378 | (type + 1) << 4); | 1416 | (rssi_type + 1) << 4); |
| 1379 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | 1417 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, |
| 1380 | (type + 1) << 4); | 1418 | (rssi_type + 1) << 4); |
| 1381 | } | 1419 | } |
| 1382 | 1420 | ||
| 1383 | if (code == 0) { | 1421 | if (code == 0) { |
| 1384 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); | 1422 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); |
| 1385 | if (type < 3) { | 1423 | if (rssi_w1_w2_nb) { |
| 1386 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | 1424 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, |
| 1387 | ~(B43_NPHY_RFCTL_CMD_RXEN | | 1425 | ~(B43_NPHY_RFCTL_CMD_RXEN | |
| 1388 | B43_NPHY_RFCTL_CMD_CORESEL)); | 1426 | B43_NPHY_RFCTL_CMD_CORESEL)); |
| @@ -1398,7 +1436,7 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1398 | } | 1436 | } |
| 1399 | } else { | 1437 | } else { |
| 1400 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); | 1438 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); |
| 1401 | if (type < 3) { | 1439 | if (rssi_w1_w2_nb) { |
| 1402 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | 1440 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, |
| 1403 | ~(B43_NPHY_RFCTL_CMD_RXEN | | 1441 | ~(B43_NPHY_RFCTL_CMD_RXEN | |
| 1404 | B43_NPHY_RFCTL_CMD_CORESEL), | 1442 | B43_NPHY_RFCTL_CMD_CORESEL), |
| @@ -1418,7 +1456,8 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1418 | } | 1456 | } |
| 1419 | 1457 | ||
| 1420 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | 1458 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ |
| 1421 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | 1459 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, |
| 1460 | enum n_rssi_type type) | ||
| 1422 | { | 1461 | { |
| 1423 | if (dev->phy.rev >= 3) | 1462 | if (dev->phy.rev >= 3) |
| 1424 | b43_nphy_rev3_rssi_select(dev, code, type); | 1463 | b43_nphy_rev3_rssi_select(dev, code, type); |
| @@ -1427,11 +1466,12 @@ static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | |||
| 1427 | } | 1466 | } |
| 1428 | 1467 | ||
| 1429 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ | 1468 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ |
| 1430 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | 1469 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, |
| 1470 | enum n_rssi_type rssi_type, u8 *buf) | ||
| 1431 | { | 1471 | { |
| 1432 | int i; | 1472 | int i; |
| 1433 | for (i = 0; i < 2; i++) { | 1473 | for (i = 0; i < 2; i++) { |
| 1434 | if (type == 2) { | 1474 | if (rssi_type == N_RSSI_NB) { |
| 1435 | if (i == 0) { | 1475 | if (i == 0) { |
| 1436 | b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, | 1476 | b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, |
| 1437 | 0xFC, buf[0]); | 1477 | 0xFC, buf[0]); |
| @@ -1455,8 +1495,8 @@ static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | |||
| 1455 | } | 1495 | } |
| 1456 | 1496 | ||
| 1457 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ | 1497 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ |
| 1458 | static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | 1498 | static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type, |
| 1459 | u8 nsamp) | 1499 | s32 *buf, u8 nsamp) |
| 1460 | { | 1500 | { |
| 1461 | int i; | 1501 | int i; |
| 1462 | int out; | 1502 | int out; |
| @@ -1487,7 +1527,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | |||
| 1487 | save_regs_phy[8] = 0; | 1527 | save_regs_phy[8] = 0; |
| 1488 | } | 1528 | } |
| 1489 | 1529 | ||
| 1490 | b43_nphy_rssi_select(dev, 5, type); | 1530 | b43_nphy_rssi_select(dev, 5, rssi_type); |
| 1491 | 1531 | ||
| 1492 | if (dev->phy.rev < 2) { | 1532 | if (dev->phy.rev < 2) { |
| 1493 | save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL); | 1533 | save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL); |
| @@ -1574,7 +1614,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1574 | 1614 | ||
| 1575 | u16 r; /* routing */ | 1615 | u16 r; /* routing */ |
| 1576 | u8 rx_core_state; | 1616 | u8 rx_core_state; |
| 1577 | u8 core, i, j; | 1617 | int core, i, j, vcm; |
| 1578 | 1618 | ||
| 1579 | class = b43_nphy_classifier(dev, 0, 0); | 1619 | class = b43_nphy_classifier(dev, 0, 0); |
| 1580 | b43_nphy_classifier(dev, 7, 4); | 1620 | b43_nphy_classifier(dev, 7, 4); |
| @@ -1586,19 +1626,19 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1586 | for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) | 1626 | for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) |
| 1587 | saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); | 1627 | saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); |
| 1588 | 1628 | ||
| 1589 | b43_nphy_rf_control_intc_override(dev, 0, 0, 7); | 1629 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7); |
| 1590 | b43_nphy_rf_control_intc_override(dev, 1, 1, 7); | 1630 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7); |
| 1591 | b43_nphy_rf_control_override(dev, 0x1, 0, 0, false); | 1631 | b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false); |
| 1592 | b43_nphy_rf_control_override(dev, 0x2, 1, 0, false); | 1632 | b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false); |
| 1593 | b43_nphy_rf_control_override(dev, 0x80, 1, 0, false); | 1633 | b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false); |
| 1594 | b43_nphy_rf_control_override(dev, 0x40, 1, 0, false); | 1634 | b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false); |
| 1595 | 1635 | ||
| 1596 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | 1636 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { |
| 1597 | b43_nphy_rf_control_override(dev, 0x20, 0, 0, false); | 1637 | b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false); |
| 1598 | b43_nphy_rf_control_override(dev, 0x10, 1, 0, false); | 1638 | b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false); |
| 1599 | } else { | 1639 | } else { |
| 1600 | b43_nphy_rf_control_override(dev, 0x10, 0, 0, false); | 1640 | b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false); |
| 1601 | b43_nphy_rf_control_override(dev, 0x20, 1, 0, false); | 1641 | b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false); |
| 1602 | } | 1642 | } |
| 1603 | 1643 | ||
| 1604 | rx_core_state = b43_nphy_get_rx_core_state(dev); | 1644 | rx_core_state = b43_nphy_get_rx_core_state(dev); |
| @@ -1606,35 +1646,44 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1606 | if (!(rx_core_state & (1 << core))) | 1646 | if (!(rx_core_state & (1 << core))) |
| 1607 | continue; | 1647 | continue; |
| 1608 | r = core ? B2056_RX1 : B2056_RX0; | 1648 | r = core ? B2056_RX1 : B2056_RX0; |
| 1609 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2); | 1649 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_I, |
| 1610 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2); | 1650 | N_RSSI_NB); |
| 1611 | for (i = 0; i < 8; i++) { | 1651 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_Q, |
| 1652 | N_RSSI_NB); | ||
| 1653 | |||
| 1654 | /* Grab RSSI results for every possible VCM */ | ||
| 1655 | for (vcm = 0; vcm < 8; vcm++) { | ||
| 1612 | b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, | 1656 | b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, |
| 1613 | i << 2); | 1657 | vcm << 2); |
| 1614 | b43_nphy_poll_rssi(dev, 2, results[i], 8); | 1658 | b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8); |
| 1615 | } | 1659 | } |
| 1660 | |||
| 1661 | /* Find out which VCM got the best results */ | ||
| 1616 | for (i = 0; i < 4; i += 2) { | 1662 | for (i = 0; i < 4; i += 2) { |
| 1617 | s32 curr; | 1663 | s32 currd; |
| 1618 | s32 mind = 0x100000; | 1664 | s32 mind = 0x100000; |
| 1619 | s32 minpoll = 249; | 1665 | s32 minpoll = 249; |
| 1620 | u8 minvcm = 0; | 1666 | u8 minvcm = 0; |
| 1621 | if (2 * core != i) | 1667 | if (2 * core != i) |
| 1622 | continue; | 1668 | continue; |
| 1623 | for (j = 0; j < 8; j++) { | 1669 | for (vcm = 0; vcm < 8; vcm++) { |
| 1624 | curr = results[j][i] * results[j][i] + | 1670 | currd = results[vcm][i] * results[vcm][i] + |
| 1625 | results[j][i + 1] * results[j][i]; | 1671 | results[vcm][i + 1] * results[vcm][i]; |
| 1626 | if (curr < mind) { | 1672 | if (currd < mind) { |
| 1627 | mind = curr; | 1673 | mind = currd; |
| 1628 | minvcm = j; | 1674 | minvcm = vcm; |
| 1629 | } | 1675 | } |
| 1630 | if (results[j][i] < minpoll) | 1676 | if (results[vcm][i] < minpoll) |
| 1631 | minpoll = results[j][i]; | 1677 | minpoll = results[vcm][i]; |
| 1632 | } | 1678 | } |
| 1633 | vcm_final = minvcm; | 1679 | vcm_final = minvcm; |
| 1634 | results_min[i] = minpoll; | 1680 | results_min[i] = minpoll; |
| 1635 | } | 1681 | } |
| 1682 | |||
| 1683 | /* Select the best VCM */ | ||
| 1636 | b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, | 1684 | b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, |
| 1637 | vcm_final << 2); | 1685 | vcm_final << 2); |
| 1686 | |||
| 1638 | for (i = 0; i < 4; i++) { | 1687 | for (i = 0; i < 4; i++) { |
| 1639 | if (core != i / 2) | 1688 | if (core != i / 2) |
| 1640 | continue; | 1689 | continue; |
| @@ -1647,16 +1696,19 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1647 | offset[i] = -32; | 1696 | offset[i] = -32; |
| 1648 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], | 1697 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], |
| 1649 | (i / 2 == 0) ? 1 : 2, | 1698 | (i / 2 == 0) ? 1 : 2, |
| 1650 | (i % 2 == 0) ? 0 : 1, | 1699 | (i % 2 == 0) ? N_RAIL_I : N_RAIL_Q, |
| 1651 | 2); | 1700 | N_RSSI_NB); |
| 1652 | } | 1701 | } |
| 1653 | } | 1702 | } |
| 1703 | |||
| 1654 | for (core = 0; core < 2; core++) { | 1704 | for (core = 0; core < 2; core++) { |
| 1655 | if (!(rx_core_state & (1 << core))) | 1705 | if (!(rx_core_state & (1 << core))) |
| 1656 | continue; | 1706 | continue; |
| 1657 | for (i = 0; i < 2; i++) { | 1707 | for (i = 0; i < 2; i++) { |
| 1658 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i); | 1708 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, |
| 1659 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i); | 1709 | N_RAIL_I, i); |
| 1710 | b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, | ||
| 1711 | N_RAIL_Q, i); | ||
| 1660 | b43_nphy_poll_rssi(dev, i, poll_results, 8); | 1712 | b43_nphy_poll_rssi(dev, i, poll_results, 8); |
| 1661 | for (j = 0; j < 4; j++) { | 1713 | for (j = 0; j < 4; j++) { |
| 1662 | if (j / 2 == core) { | 1714 | if (j / 2 == core) { |
| @@ -1696,8 +1748,13 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1696 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; | 1748 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; |
| 1697 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; | 1749 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; |
| 1698 | } | 1750 | } |
| 1699 | rssical_radio_regs[0] = b43_radio_read(dev, 0x602B); | 1751 | if (dev->phy.rev >= 7) { |
| 1700 | rssical_radio_regs[0] = b43_radio_read(dev, 0x702B); | 1752 | } else { |
| 1753 | rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 | | ||
| 1754 | B2056_RX_RSSI_MISC); | ||
| 1755 | rssical_radio_regs[1] = b43_radio_read(dev, B2056_RX1 | | ||
| 1756 | B2056_RX_RSSI_MISC); | ||
| 1757 | } | ||
| 1701 | rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); | 1758 | rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); |
| 1702 | rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); | 1759 | rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); |
| 1703 | rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z); | 1760 | rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z); |
| @@ -1723,9 +1780,9 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | |||
| 1723 | } | 1780 | } |
| 1724 | 1781 | ||
| 1725 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ | 1782 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ |
| 1726 | static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | 1783 | static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type) |
| 1727 | { | 1784 | { |
| 1728 | int i, j; | 1785 | int i, j, vcm; |
| 1729 | u8 state[4]; | 1786 | u8 state[4]; |
| 1730 | u8 code, val; | 1787 | u8 code, val; |
| 1731 | u16 class, override; | 1788 | u16 class, override; |
| @@ -1743,10 +1800,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | |||
| 1743 | s32 results[4][4] = { }; | 1800 | s32 results[4][4] = { }; |
| 1744 | s32 miniq[4][2] = { }; | 1801 | s32 miniq[4][2] = { }; |
| 1745 | 1802 | ||
| 1746 | if (type == 2) { | 1803 | if (type == N_RSSI_NB) { |
| 1747 | code = 0; | 1804 | code = 0; |
| 1748 | val = 6; | 1805 | val = 6; |
| 1749 | } else if (type < 2) { | 1806 | } else if (type == N_RSSI_W1 || type == N_RSSI_W2) { |
| 1750 | code = 25; | 1807 | code = 25; |
| 1751 | val = 4; | 1808 | val = 4; |
| 1752 | } else { | 1809 | } else { |
| @@ -1765,63 +1822,63 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | |||
| 1765 | override = 0x110; | 1822 | override = 0x110; |
| 1766 | 1823 | ||
| 1767 | regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | 1824 | regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); |
| 1768 | regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX); | 1825 | regs_save_radio[0] = b43_radio_read(dev, B2055_C1_PD_RXTX); |
| 1769 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); | 1826 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); |
| 1770 | b43_radio_write16(dev, B2055_C1_PD_RXTX, val); | 1827 | b43_radio_write(dev, B2055_C1_PD_RXTX, val); |
| 1771 | 1828 | ||
| 1772 | regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | 1829 | regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); |
| 1773 | regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX); | 1830 | regs_save_radio[1] = b43_radio_read(dev, B2055_C2_PD_RXTX); |
| 1774 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); | 1831 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); |
| 1775 | b43_radio_write16(dev, B2055_C2_PD_RXTX, val); | 1832 | b43_radio_write(dev, B2055_C2_PD_RXTX, val); |
| 1776 | 1833 | ||
| 1777 | state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07; | 1834 | state[0] = b43_radio_read(dev, B2055_C1_PD_RSSIMISC) & 0x07; |
| 1778 | state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07; | 1835 | state[1] = b43_radio_read(dev, B2055_C2_PD_RSSIMISC) & 0x07; |
| 1779 | b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); | 1836 | b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); |
| 1780 | b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); | 1837 | b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); |
| 1781 | state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07; | 1838 | state[2] = b43_radio_read(dev, B2055_C1_SP_RSSI) & 0x07; |
| 1782 | state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07; | 1839 | state[3] = b43_radio_read(dev, B2055_C2_SP_RSSI) & 0x07; |
| 1783 | 1840 | ||
| 1784 | b43_nphy_rssi_select(dev, 5, type); | 1841 | b43_nphy_rssi_select(dev, 5, type); |
| 1785 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type); | 1842 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_I, type); |
| 1786 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type); | 1843 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_Q, type); |
| 1787 | 1844 | ||
| 1788 | for (i = 0; i < 4; i++) { | 1845 | for (vcm = 0; vcm < 4; vcm++) { |
| 1789 | u8 tmp[4]; | 1846 | u8 tmp[4]; |
| 1790 | for (j = 0; j < 4; j++) | 1847 | for (j = 0; j < 4; j++) |
| 1791 | tmp[j] = i; | 1848 | tmp[j] = vcm; |
| 1792 | if (type != 1) | 1849 | if (type != N_RSSI_W2) |
| 1793 | b43_nphy_set_rssi_2055_vcm(dev, type, tmp); | 1850 | b43_nphy_set_rssi_2055_vcm(dev, type, tmp); |
| 1794 | b43_nphy_poll_rssi(dev, type, results[i], 8); | 1851 | b43_nphy_poll_rssi(dev, type, results[vcm], 8); |
| 1795 | if (type < 2) | 1852 | if (type == N_RSSI_W1 || type == N_RSSI_W2) |
| 1796 | for (j = 0; j < 2; j++) | 1853 | for (j = 0; j < 2; j++) |
| 1797 | miniq[i][j] = min(results[i][2 * j], | 1854 | miniq[vcm][j] = min(results[vcm][2 * j], |
| 1798 | results[i][2 * j + 1]); | 1855 | results[vcm][2 * j + 1]); |
| 1799 | } | 1856 | } |
| 1800 | 1857 | ||
| 1801 | for (i = 0; i < 4; i++) { | 1858 | for (i = 0; i < 4; i++) { |
| 1802 | s32 mind = 0x100000; | 1859 | s32 mind = 0x100000; |
| 1803 | u8 minvcm = 0; | 1860 | u8 minvcm = 0; |
| 1804 | s32 minpoll = 249; | 1861 | s32 minpoll = 249; |
| 1805 | s32 curr; | 1862 | s32 currd; |
| 1806 | for (j = 0; j < 4; j++) { | 1863 | for (vcm = 0; vcm < 4; vcm++) { |
| 1807 | if (type == 2) | 1864 | if (type == N_RSSI_NB) |
| 1808 | curr = abs(results[j][i]); | 1865 | currd = abs(results[vcm][i] - code * 8); |
| 1809 | else | 1866 | else |
| 1810 | curr = abs(miniq[j][i / 2] - code * 8); | 1867 | currd = abs(miniq[vcm][i / 2] - code * 8); |
| 1811 | 1868 | ||
| 1812 | if (curr < mind) { | 1869 | if (currd < mind) { |
| 1813 | mind = curr; | 1870 | mind = currd; |
| 1814 | minvcm = j; | 1871 | minvcm = vcm; |
| 1815 | } | 1872 | } |
| 1816 | 1873 | ||
| 1817 | if (results[j][i] < minpoll) | 1874 | if (results[vcm][i] < minpoll) |
| 1818 | minpoll = results[j][i]; | 1875 | minpoll = results[vcm][i]; |
| 1819 | } | 1876 | } |
| 1820 | results_min[i] = minpoll; | 1877 | results_min[i] = minpoll; |
| 1821 | vcm_final[i] = minvcm; | 1878 | vcm_final[i] = minvcm; |
| 1822 | } | 1879 | } |
| 1823 | 1880 | ||
| 1824 | if (type != 1) | 1881 | if (type != N_RSSI_W2) |
| 1825 | b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); | 1882 | b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); |
| 1826 | 1883 | ||
| 1827 | for (i = 0; i < 4; i++) { | 1884 | for (i = 0; i < 4; i++) { |
| @@ -1836,7 +1893,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | |||
| 1836 | offset[i] = code - 32; | 1893 | offset[i] = code - 32; |
| 1837 | 1894 | ||
| 1838 | core = (i / 2) ? 2 : 1; | 1895 | core = (i / 2) ? 2 : 1; |
| 1839 | rail = (i % 2) ? 1 : 0; | 1896 | rail = (i % 2) ? N_RAIL_Q : N_RAIL_I; |
| 1840 | 1897 | ||
| 1841 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, | 1898 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, |
| 1842 | type); | 1899 | type); |
| @@ -1847,37 +1904,37 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | |||
| 1847 | 1904 | ||
| 1848 | switch (state[2]) { | 1905 | switch (state[2]) { |
| 1849 | case 1: | 1906 | case 1: |
| 1850 | b43_nphy_rssi_select(dev, 1, 2); | 1907 | b43_nphy_rssi_select(dev, 1, N_RSSI_NB); |
| 1851 | break; | 1908 | break; |
| 1852 | case 4: | 1909 | case 4: |
| 1853 | b43_nphy_rssi_select(dev, 1, 0); | 1910 | b43_nphy_rssi_select(dev, 1, N_RSSI_W1); |
| 1854 | break; | 1911 | break; |
| 1855 | case 2: | 1912 | case 2: |
| 1856 | b43_nphy_rssi_select(dev, 1, 1); | 1913 | b43_nphy_rssi_select(dev, 1, N_RSSI_W2); |
| 1857 | break; | 1914 | break; |
| 1858 | default: | 1915 | default: |
| 1859 | b43_nphy_rssi_select(dev, 1, 1); | 1916 | b43_nphy_rssi_select(dev, 1, N_RSSI_W2); |
| 1860 | break; | 1917 | break; |
| 1861 | } | 1918 | } |
| 1862 | 1919 | ||
| 1863 | switch (state[3]) { | 1920 | switch (state[3]) { |
| 1864 | case 1: | 1921 | case 1: |
| 1865 | b43_nphy_rssi_select(dev, 2, 2); | 1922 | b43_nphy_rssi_select(dev, 2, N_RSSI_NB); |
| 1866 | break; | 1923 | break; |
| 1867 | case 4: | 1924 | case 4: |
| 1868 | b43_nphy_rssi_select(dev, 2, 0); | 1925 | b43_nphy_rssi_select(dev, 2, N_RSSI_W1); |
| 1869 | break; | 1926 | break; |
| 1870 | default: | 1927 | default: |
| 1871 | b43_nphy_rssi_select(dev, 2, 1); | 1928 | b43_nphy_rssi_select(dev, 2, N_RSSI_W2); |
| 1872 | break; | 1929 | break; |
| 1873 | } | 1930 | } |
| 1874 | 1931 | ||
| 1875 | b43_nphy_rssi_select(dev, 0, type); | 1932 | b43_nphy_rssi_select(dev, 0, type); |
| 1876 | 1933 | ||
| 1877 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); | 1934 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); |
| 1878 | b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); | 1935 | b43_radio_write(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); |
| 1879 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); | 1936 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); |
| 1880 | b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); | 1937 | b43_radio_write(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); |
| 1881 | 1938 | ||
| 1882 | b43_nphy_classifier(dev, 7, class); | 1939 | b43_nphy_classifier(dev, 7, class); |
| 1883 | b43_nphy_write_clip_detection(dev, clip_state); | 1940 | b43_nphy_write_clip_detection(dev, clip_state); |
| @@ -1895,9 +1952,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev) | |||
| 1895 | if (dev->phy.rev >= 3) { | 1952 | if (dev->phy.rev >= 3) { |
| 1896 | b43_nphy_rev3_rssi_cal(dev); | 1953 | b43_nphy_rev3_rssi_cal(dev); |
| 1897 | } else { | 1954 | } else { |
| 1898 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z); | 1955 | b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB); |
| 1899 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X); | 1956 | b43_nphy_rev2_rssi_cal(dev, N_RSSI_W1); |
| 1900 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y); | 1957 | b43_nphy_rev2_rssi_cal(dev, N_RSSI_W2); |
| 1901 | } | 1958 | } |
| 1902 | } | 1959 | } |
| 1903 | 1960 | ||
| @@ -1930,10 +1987,8 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 1930 | b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); | 1987 | b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); |
| 1931 | 1988 | ||
| 1932 | /* Set Clip 2 detect */ | 1989 | /* Set Clip 2 detect */ |
| 1933 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | 1990 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT); |
| 1934 | B43_NPHY_C1_CGAINI_CL2DETECT); | 1991 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT); |
| 1935 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
| 1936 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
| 1937 | 1992 | ||
| 1938 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, | 1993 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, |
| 1939 | 0x17); | 1994 | 0x17); |
| @@ -1967,22 +2022,22 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 1967 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); | 2022 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); |
| 1968 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); | 2023 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); |
| 1969 | 2024 | ||
| 1970 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | 2025 | b43_phy_write(dev, B43_NPHY_REV3_C1_INITGAIN_A, e->init_gain); |
| 1971 | b43_phy_write(dev, 0x2A7, e->init_gain); | 2026 | b43_phy_write(dev, B43_NPHY_REV3_C2_INITGAIN_A, e->init_gain); |
| 2027 | |||
| 1972 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, | 2028 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, |
| 1973 | e->rfseq_init); | 2029 | e->rfseq_init); |
| 1974 | 2030 | ||
| 1975 | /* TODO: check defines. Do not match variables names */ | 2031 | b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_HIGAIN_A, e->cliphi_gain); |
| 1976 | b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); | 2032 | b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_HIGAIN_A, e->cliphi_gain); |
| 1977 | b43_phy_write(dev, 0x2A9, e->cliphi_gain); | 2033 | b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_MEDGAIN_A, e->clipmd_gain); |
| 1978 | b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); | 2034 | b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_MEDGAIN_A, e->clipmd_gain); |
| 1979 | b43_phy_write(dev, 0x2AB, e->clipmd_gain); | 2035 | b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_A, e->cliplo_gain); |
| 1980 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); | 2036 | b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_A, e->cliplo_gain); |
| 1981 | b43_phy_write(dev, 0x2AD, e->cliplo_gain); | 2037 | |
| 1982 | 2038 | b43_phy_maskset(dev, B43_NPHY_CRSMINPOWER0, 0xFF00, e->crsmin); | |
| 1983 | b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); | 2039 | b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERL0, 0xFF00, e->crsminl); |
| 1984 | b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); | 2040 | b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERU0, 0xFF00, e->crsminu); |
| 1985 | b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); | ||
| 1986 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); | 2041 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); |
| 1987 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); | 2042 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); |
| 1988 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | 2043 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, |
| @@ -2164,8 +2219,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) | |||
| 2164 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000); | 2219 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000); |
| 2165 | } | 2220 | } |
| 2166 | if (phy->rev <= 8) { | 2221 | if (phy->rev <= 8) { |
| 2167 | b43_phy_write(dev, 0x23F, 0x1B0); | 2222 | b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0); |
| 2168 | b43_phy_write(dev, 0x240, 0x1B0); | 2223 | b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0); |
| 2169 | } | 2224 | } |
| 2170 | if (phy->rev >= 8) | 2225 | if (phy->rev >= 8) |
| 2171 | b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72); | 2226 | b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72); |
| @@ -2182,8 +2237,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) | |||
| 2182 | b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, | 2237 | b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, |
| 2183 | rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); | 2238 | rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); |
| 2184 | 2239 | ||
| 2185 | b43_phy_maskset(dev, 0x299, 0x3FFF, 0x4000); | 2240 | b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000); |
| 2186 | b43_phy_maskset(dev, 0x29D, 0x3FFF, 0x4000); | 2241 | b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000); |
| 2187 | 2242 | ||
| 2188 | lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154); | 2243 | lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154); |
| 2189 | lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159); | 2244 | lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159); |
| @@ -2260,11 +2315,11 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) | |||
| 2260 | b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16), | 2315 | b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16), |
| 2261 | rx2tx_lut_40_11n); | 2316 | rx2tx_lut_40_11n); |
| 2262 | } | 2317 | } |
| 2263 | b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, false, 2); | 2318 | b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2); |
| 2264 | } | 2319 | } |
| 2265 | b43_phy_write(dev, 0x32F, 0x3); | 2320 | b43_phy_write(dev, 0x32F, 0x3); |
| 2266 | if (phy->radio_rev == 4 || phy->radio_rev == 6) | 2321 | if (phy->radio_rev == 4 || phy->radio_rev == 6) |
| 2267 | b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, false, 0); | 2322 | b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0); |
| 2268 | 2323 | ||
| 2269 | if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) { | 2324 | if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) { |
| 2270 | if (sprom->revision && | 2325 | if (sprom->revision && |
| @@ -2450,8 +2505,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 2450 | u16 tmp16; | 2505 | u16 tmp16; |
| 2451 | u32 tmp32; | 2506 | u32 tmp32; |
| 2452 | 2507 | ||
| 2453 | b43_phy_write(dev, 0x23f, 0x1f8); | 2508 | b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1f8); |
| 2454 | b43_phy_write(dev, 0x240, 0x1f8); | 2509 | b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1f8); |
| 2455 | 2510 | ||
| 2456 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); | 2511 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); |
| 2457 | tmp32 &= 0xffffff; | 2512 | tmp32 &= 0xffffff; |
| @@ -2464,8 +2519,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 2464 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); | 2519 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); |
| 2465 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); | 2520 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); |
| 2466 | 2521 | ||
| 2467 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); | 2522 | b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_B, 0x000C); |
| 2468 | b43_phy_write(dev, 0x2AE, 0x000C); | 2523 | b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_B, 0x000C); |
| 2469 | 2524 | ||
| 2470 | /* TX to RX */ | 2525 | /* TX to RX */ |
| 2471 | b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, | 2526 | b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, |
| @@ -2490,7 +2545,7 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 2490 | 0x2 : 0x9C40; | 2545 | 0x2 : 0x9C40; |
| 2491 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); | 2546 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); |
| 2492 | 2547 | ||
| 2493 | b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); | 2548 | b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700); |
| 2494 | 2549 | ||
| 2495 | if (!dev->phy.is_40mhz) { | 2550 | if (!dev->phy.is_40mhz) { |
| 2496 | b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); | 2551 | b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); |
| @@ -2542,18 +2597,18 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | |||
| 2542 | } | 2597 | } |
| 2543 | 2598 | ||
| 2544 | /* Dropped probably-always-true condition */ | 2599 | /* Dropped probably-always-true condition */ |
| 2545 | b43_phy_write(dev, 0x224, 0x03eb); | 2600 | b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb); |
| 2546 | b43_phy_write(dev, 0x225, 0x03eb); | 2601 | b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb); |
| 2547 | b43_phy_write(dev, 0x226, 0x0341); | 2602 | b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); |
| 2548 | b43_phy_write(dev, 0x227, 0x0341); | 2603 | b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); |
| 2549 | b43_phy_write(dev, 0x228, 0x042b); | 2604 | b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b); |
| 2550 | b43_phy_write(dev, 0x229, 0x042b); | 2605 | b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b); |
| 2551 | b43_phy_write(dev, 0x22a, 0x0381); | 2606 | b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH0, 0x0381); |
| 2552 | b43_phy_write(dev, 0x22b, 0x0381); | 2607 | b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH1, 0x0381); |
| 2553 | b43_phy_write(dev, 0x22c, 0x042b); | 2608 | b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH0, 0x042b); |
| 2554 | b43_phy_write(dev, 0x22d, 0x042b); | 2609 | b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH1, 0x042b); |
| 2555 | b43_phy_write(dev, 0x22e, 0x0381); | 2610 | b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH0, 0x0381); |
| 2556 | b43_phy_write(dev, 0x22f, 0x0381); | 2611 | b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH1, 0x0381); |
| 2557 | 2612 | ||
| 2558 | if (dev->phy.rev >= 6 && sprom->boardflags2_lo & B43_BFL2_SINGLEANT_CCK) | 2613 | if (dev->phy.rev >= 6 && sprom->boardflags2_lo & B43_BFL2_SINGLEANT_CCK) |
| 2559 | ; /* TODO: 0x0080000000000000 HF */ | 2614 | ; /* TODO: 0x0080000000000000 HF */ |
| @@ -2572,7 +2627,7 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) | |||
| 2572 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | 2627 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; |
| 2573 | 2628 | ||
| 2574 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || | 2629 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || |
| 2575 | dev->dev->board_type == 0x8B) { | 2630 | dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93) { |
| 2576 | delays1[0] = 0x1; | 2631 | delays1[0] = 0x1; |
| 2577 | delays1[5] = 0x14; | 2632 | delays1[5] = 0x14; |
| 2578 | } | 2633 | } |
| @@ -3120,21 +3175,21 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) | |||
| 3120 | b43_nphy_ipa_internal_tssi_setup(dev); | 3175 | b43_nphy_ipa_internal_tssi_setup(dev); |
| 3121 | 3176 | ||
| 3122 | if (phy->rev >= 7) | 3177 | if (phy->rev >= 7) |
| 3123 | b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, false, 0); | 3178 | b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0); |
| 3124 | else if (phy->rev >= 3) | 3179 | else if (phy->rev >= 3) |
| 3125 | b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false); | 3180 | b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false); |
| 3126 | 3181 | ||
| 3127 | b43_nphy_stop_playback(dev); | 3182 | b43_nphy_stop_playback(dev); |
| 3128 | b43_nphy_tx_tone(dev, 0xFA0, 0, false, false); | 3183 | b43_nphy_tx_tone(dev, 0xFA0, 0, false, false); |
| 3129 | udelay(20); | 3184 | udelay(20); |
| 3130 | tmp = b43_nphy_poll_rssi(dev, 4, rssi, 1); | 3185 | tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1); |
| 3131 | b43_nphy_stop_playback(dev); | 3186 | b43_nphy_stop_playback(dev); |
| 3132 | b43_nphy_rssi_select(dev, 0, 0); | 3187 | b43_nphy_rssi_select(dev, 0, N_RSSI_W1); |
| 3133 | 3188 | ||
| 3134 | if (phy->rev >= 7) | 3189 | if (phy->rev >= 7) |
| 3135 | b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, true, 0); | 3190 | b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0); |
| 3136 | else if (phy->rev >= 3) | 3191 | else if (phy->rev >= 3) |
| 3137 | b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true); | 3192 | b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true); |
| 3138 | 3193 | ||
| 3139 | if (phy->rev >= 3) { | 3194 | if (phy->rev >= 3) { |
| 3140 | nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF; | 3195 | nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF; |
| @@ -3573,8 +3628,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) | |||
| 3573 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); | 3628 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); |
| 3574 | } | 3629 | } |
| 3575 | 3630 | ||
| 3576 | b43_nphy_rf_control_intc_override(dev, 2, 0, 3); | 3631 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 0, 3); |
| 3577 | b43_nphy_rf_control_override(dev, 8, 0, 3, false); | 3632 | b43_nphy_rf_ctl_override(dev, 8, 0, 3, false); |
| 3578 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); | 3633 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); |
| 3579 | 3634 | ||
| 3580 | if (core == 0) { | 3635 | if (core == 0) { |
| @@ -3584,8 +3639,10 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) | |||
| 3584 | rxval = 4; | 3639 | rxval = 4; |
| 3585 | txval = 2; | 3640 | txval = 2; |
| 3586 | } | 3641 | } |
| 3587 | b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1)); | 3642 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, rxval, |
| 3588 | b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core)); | 3643 | core + 1); |
| 3644 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, txval, | ||
| 3645 | 2 - core); | ||
| 3589 | } | 3646 | } |
| 3590 | #endif | 3647 | #endif |
| 3591 | 3648 | ||
| @@ -3847,9 +3904,13 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) | |||
| 3847 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; | 3904 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; |
| 3848 | } | 3905 | } |
| 3849 | 3906 | ||
| 3850 | /* TODO use some definitions */ | 3907 | if (dev->phy.rev >= 7) { |
| 3851 | b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]); | 3908 | } else { |
| 3852 | b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]); | 3909 | b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3, |
| 3910 | rssical_radio_regs[0]); | ||
| 3911 | b43_radio_maskset(dev, B2056_RX1 | B2056_RX_RSSI_MISC, 0xE3, | ||
| 3912 | rssical_radio_regs[1]); | ||
| 3913 | } | ||
| 3853 | 3914 | ||
| 3854 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]); | 3915 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]); |
| 3855 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]); | 3916 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]); |
| @@ -3880,75 +3941,75 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) | |||
| 3880 | tmp = (i == 0) ? 0x2000 : 0x3000; | 3941 | tmp = (i == 0) ? 0x2000 : 0x3000; |
| 3881 | offset = i * 11; | 3942 | offset = i * 11; |
| 3882 | 3943 | ||
| 3883 | save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL); | 3944 | save[offset + 0] = b43_radio_read(dev, B2055_CAL_RVARCTL); |
| 3884 | save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL); | 3945 | save[offset + 1] = b43_radio_read(dev, B2055_CAL_LPOCTL); |
| 3885 | save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS); | 3946 | save[offset + 2] = b43_radio_read(dev, B2055_CAL_TS); |
| 3886 | save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS); | 3947 | save[offset + 3] = b43_radio_read(dev, B2055_CAL_RCCALRTS); |
| 3887 | save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS); | 3948 | save[offset + 4] = b43_radio_read(dev, B2055_CAL_RCALRTS); |
| 3888 | save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV); | 3949 | save[offset + 5] = b43_radio_read(dev, B2055_PADDRV); |
| 3889 | save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1); | 3950 | save[offset + 6] = b43_radio_read(dev, B2055_XOCTL1); |
| 3890 | save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2); | 3951 | save[offset + 7] = b43_radio_read(dev, B2055_XOCTL2); |
| 3891 | save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL); | 3952 | save[offset + 8] = b43_radio_read(dev, B2055_XOREGUL); |
| 3892 | save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC); | 3953 | save[offset + 9] = b43_radio_read(dev, B2055_XOMISC); |
| 3893 | save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1); | 3954 | save[offset + 10] = b43_radio_read(dev, B2055_PLL_LFC1); |
| 3894 | 3955 | ||
| 3895 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | 3956 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { |
| 3896 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A); | 3957 | b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x0A); |
| 3897 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | 3958 | b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40); |
| 3898 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | 3959 | b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55); |
| 3899 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | 3960 | b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0); |
| 3900 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | 3961 | b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0); |
| 3901 | if (nphy->ipa5g_on) { | 3962 | if (nphy->ipa5g_on) { |
| 3902 | b43_radio_write16(dev, tmp | B2055_PADDRV, 4); | 3963 | b43_radio_write(dev, tmp | B2055_PADDRV, 4); |
| 3903 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 1); | 3964 | b43_radio_write(dev, tmp | B2055_XOCTL1, 1); |
| 3904 | } else { | 3965 | } else { |
| 3905 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | 3966 | b43_radio_write(dev, tmp | B2055_PADDRV, 0); |
| 3906 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F); | 3967 | b43_radio_write(dev, tmp | B2055_XOCTL1, 0x2F); |
| 3907 | } | 3968 | } |
| 3908 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | 3969 | b43_radio_write(dev, tmp | B2055_XOCTL2, 0); |
| 3909 | } else { | 3970 | } else { |
| 3910 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06); | 3971 | b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x06); |
| 3911 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | 3972 | b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40); |
| 3912 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | 3973 | b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55); |
| 3913 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | 3974 | b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0); |
| 3914 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | 3975 | b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0); |
| 3915 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0); | 3976 | b43_radio_write(dev, tmp | B2055_XOCTL1, 0); |
| 3916 | if (nphy->ipa2g_on) { | 3977 | if (nphy->ipa2g_on) { |
| 3917 | b43_radio_write16(dev, tmp | B2055_PADDRV, 6); | 3978 | b43_radio_write(dev, tmp | B2055_PADDRV, 6); |
| 3918 | b43_radio_write16(dev, tmp | B2055_XOCTL2, | 3979 | b43_radio_write(dev, tmp | B2055_XOCTL2, |
| 3919 | (dev->phy.rev < 5) ? 0x11 : 0x01); | 3980 | (dev->phy.rev < 5) ? 0x11 : 0x01); |
| 3920 | } else { | 3981 | } else { |
| 3921 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | 3982 | b43_radio_write(dev, tmp | B2055_PADDRV, 0); |
| 3922 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | 3983 | b43_radio_write(dev, tmp | B2055_XOCTL2, 0); |
| 3923 | } | 3984 | } |
| 3924 | } | 3985 | } |
| 3925 | b43_radio_write16(dev, tmp | B2055_XOREGUL, 0); | 3986 | b43_radio_write(dev, tmp | B2055_XOREGUL, 0); |
| 3926 | b43_radio_write16(dev, tmp | B2055_XOMISC, 0); | 3987 | b43_radio_write(dev, tmp | B2055_XOMISC, 0); |
| 3927 | b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0); | 3988 | b43_radio_write(dev, tmp | B2055_PLL_LFC1, 0); |
| 3928 | } | 3989 | } |
| 3929 | } else { | 3990 | } else { |
| 3930 | save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); | 3991 | save[0] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL1); |
| 3931 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); | 3992 | b43_radio_write(dev, B2055_C1_TX_RF_IQCAL1, 0x29); |
| 3932 | 3993 | ||
| 3933 | save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2); | 3994 | save[1] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL2); |
| 3934 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54); | 3995 | b43_radio_write(dev, B2055_C1_TX_RF_IQCAL2, 0x54); |
| 3935 | 3996 | ||
| 3936 | save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1); | 3997 | save[2] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL1); |
| 3937 | b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29); | 3998 | b43_radio_write(dev, B2055_C2_TX_RF_IQCAL1, 0x29); |
| 3938 | 3999 | ||
| 3939 | save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2); | 4000 | save[3] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL2); |
| 3940 | b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54); | 4001 | b43_radio_write(dev, B2055_C2_TX_RF_IQCAL2, 0x54); |
| 3941 | 4002 | ||
| 3942 | save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX); | 4003 | save[3] = b43_radio_read(dev, B2055_C1_PWRDET_RXTX); |
| 3943 | save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX); | 4004 | save[4] = b43_radio_read(dev, B2055_C2_PWRDET_RXTX); |
| 3944 | 4005 | ||
| 3945 | if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) & | 4006 | if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) & |
| 3946 | B43_NPHY_BANDCTL_5GHZ)) { | 4007 | B43_NPHY_BANDCTL_5GHZ)) { |
| 3947 | b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04); | 4008 | b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x04); |
| 3948 | b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04); | 4009 | b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x04); |
| 3949 | } else { | 4010 | } else { |
| 3950 | b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20); | 4011 | b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x20); |
| 3951 | b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20); | 4012 | b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x20); |
| 3952 | } | 4013 | } |
| 3953 | 4014 | ||
| 3954 | if (dev->phy.rev < 2) { | 4015 | if (dev->phy.rev < 2) { |
| @@ -4144,9 +4205,9 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) | |||
| 4144 | regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | 4205 | regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); |
| 4145 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | 4206 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); |
| 4146 | 4207 | ||
| 4147 | b43_nphy_rf_control_intc_override(dev, 2, 1, 3); | 4208 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3); |
| 4148 | b43_nphy_rf_control_intc_override(dev, 1, 2, 1); | 4209 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1); |
| 4149 | b43_nphy_rf_control_intc_override(dev, 1, 8, 2); | 4210 | b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2); |
| 4150 | 4211 | ||
| 4151 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); | 4212 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); |
| 4152 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); | 4213 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); |
| @@ -4679,7 +4740,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
| 4679 | 4740 | ||
| 4680 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | | 4741 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | |
| 4681 | (cur_lna << 2)); | 4742 | (cur_lna << 2)); |
| 4682 | b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, | 4743 | b43_nphy_rf_ctl_override(dev, 0x400, tmp[0], 3, |
| 4683 | false); | 4744 | false); |
| 4684 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 4745 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
| 4685 | b43_nphy_stop_playback(dev); | 4746 | b43_nphy_stop_playback(dev); |
| @@ -4728,7 +4789,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
| 4728 | break; | 4789 | break; |
| 4729 | } | 4790 | } |
| 4730 | 4791 | ||
| 4731 | b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); | 4792 | b43_nphy_rf_ctl_override(dev, 0x400, 0, 3, true); |
| 4732 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 4793 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
| 4733 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); | 4794 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); |
| 4734 | 4795 | ||
| @@ -4797,18 +4858,6 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) | |||
| 4797 | * N-PHY init | 4858 | * N-PHY init |
| 4798 | **************************************************/ | 4859 | **************************************************/ |
| 4799 | 4860 | ||
| 4800 | /* | ||
| 4801 | * Upload the N-PHY tables. | ||
| 4802 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables | ||
| 4803 | */ | ||
| 4804 | static void b43_nphy_tables_init(struct b43_wldev *dev) | ||
| 4805 | { | ||
| 4806 | if (dev->phy.rev < 3) | ||
| 4807 | b43_nphy_rev0_1_2_tables_init(dev); | ||
| 4808 | else | ||
| 4809 | b43_nphy_rev3plus_tables_init(dev); | ||
| 4810 | } | ||
| 4811 | |||
| 4812 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ | 4861 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ |
| 4813 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) | 4862 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) |
| 4814 | { | 4863 | { |
| @@ -4958,7 +5007,7 @@ static int b43_phy_initn(struct b43_wldev *dev) | |||
| 4958 | 5007 | ||
| 4959 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || | 5008 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || |
| 4960 | (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && | 5009 | (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && |
| 4961 | dev->dev->board_type == 0x8B)) | 5010 | dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93)) |
| 4962 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); | 5011 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); |
| 4963 | else | 5012 | else |
| 4964 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); | 5013 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); |
| @@ -5100,63 +5149,11 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev, | |||
| 5100 | /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ | 5149 | /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ |
| 5101 | static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) | 5150 | static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) |
| 5102 | { | 5151 | { |
| 5103 | struct bcma_drv_cc __maybe_unused *cc; | ||
| 5104 | u32 __maybe_unused pmu_ctl; | ||
| 5105 | |||
| 5106 | switch (dev->dev->bus_type) { | 5152 | switch (dev->dev->bus_type) { |
| 5107 | #ifdef CONFIG_B43_BCMA | 5153 | #ifdef CONFIG_B43_BCMA |
| 5108 | case B43_BUS_BCMA: | 5154 | case B43_BUS_BCMA: |
| 5109 | cc = &dev->dev->bdev->bus->drv_cc; | 5155 | bcma_pmu_spuravoid_pllupdate(&dev->dev->bdev->bus->drv_cc, |
| 5110 | if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) { | 5156 | avoid); |
| 5111 | if (avoid) { | ||
| 5112 | bcma_chipco_pll_write(cc, 0x0, 0x11500010); | ||
| 5113 | bcma_chipco_pll_write(cc, 0x1, 0x000C0C06); | ||
| 5114 | bcma_chipco_pll_write(cc, 0x2, 0x0F600a08); | ||
| 5115 | bcma_chipco_pll_write(cc, 0x3, 0x00000000); | ||
| 5116 | bcma_chipco_pll_write(cc, 0x4, 0x2001E920); | ||
| 5117 | bcma_chipco_pll_write(cc, 0x5, 0x88888815); | ||
| 5118 | } else { | ||
| 5119 | bcma_chipco_pll_write(cc, 0x0, 0x11100010); | ||
| 5120 | bcma_chipco_pll_write(cc, 0x1, 0x000c0c06); | ||
| 5121 | bcma_chipco_pll_write(cc, 0x2, 0x03000a08); | ||
| 5122 | bcma_chipco_pll_write(cc, 0x3, 0x00000000); | ||
| 5123 | bcma_chipco_pll_write(cc, 0x4, 0x200005c0); | ||
| 5124 | bcma_chipco_pll_write(cc, 0x5, 0x88888815); | ||
| 5125 | } | ||
| 5126 | pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD; | ||
| 5127 | } else if (dev->dev->chip_id == 0x4716) { | ||
| 5128 | if (avoid) { | ||
| 5129 | bcma_chipco_pll_write(cc, 0x0, 0x11500060); | ||
| 5130 | bcma_chipco_pll_write(cc, 0x1, 0x080C0C06); | ||
| 5131 | bcma_chipco_pll_write(cc, 0x2, 0x0F600000); | ||
| 5132 | bcma_chipco_pll_write(cc, 0x3, 0x00000000); | ||
| 5133 | bcma_chipco_pll_write(cc, 0x4, 0x2001E924); | ||
| 5134 | bcma_chipco_pll_write(cc, 0x5, 0x88888815); | ||
| 5135 | } else { | ||
| 5136 | bcma_chipco_pll_write(cc, 0x0, 0x11100060); | ||
| 5137 | bcma_chipco_pll_write(cc, 0x1, 0x080c0c06); | ||
| 5138 | bcma_chipco_pll_write(cc, 0x2, 0x03000000); | ||
| 5139 | bcma_chipco_pll_write(cc, 0x3, 0x00000000); | ||
| 5140 | bcma_chipco_pll_write(cc, 0x4, 0x200005c0); | ||
| 5141 | bcma_chipco_pll_write(cc, 0x5, 0x88888815); | ||
| 5142 | } | ||
| 5143 | pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD | | ||
| 5144 | BCMA_CC_PMU_CTL_NOILPONW; | ||
| 5145 | } else if (dev->dev->chip_id == 0x4322 || | ||
| 5146 | dev->dev->chip_id == 0x4340 || | ||
| 5147 | dev->dev->chip_id == 0x4341) { | ||
| 5148 | bcma_chipco_pll_write(cc, 0x0, 0x11100070); | ||
| 5149 | bcma_chipco_pll_write(cc, 0x1, 0x1014140a); | ||
| 5150 | bcma_chipco_pll_write(cc, 0x5, 0x88888854); | ||
| 5151 | if (avoid) | ||
| 5152 | bcma_chipco_pll_write(cc, 0x2, 0x05201828); | ||
| 5153 | else | ||
| 5154 | bcma_chipco_pll_write(cc, 0x2, 0x05001828); | ||
| 5155 | pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD; | ||
| 5156 | } else { | ||
| 5157 | return; | ||
| 5158 | } | ||
| 5159 | bcma_cc_set32(cc, BCMA_CC_PMU_CTL, pmu_ctl); | ||
| 5160 | break; | 5157 | break; |
| 5161 | #endif | 5158 | #endif |
| 5162 | #ifdef CONFIG_B43_SSB | 5159 | #ifdef CONFIG_B43_SSB |
| @@ -5527,8 +5524,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) | |||
| 5527 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, | 5524 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, |
| 5528 | unsigned int new_channel) | 5525 | unsigned int new_channel) |
| 5529 | { | 5526 | { |
| 5530 | struct ieee80211_channel *channel = dev->wl->hw->conf.channel; | 5527 | struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; |
| 5531 | enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; | 5528 | enum nl80211_channel_type channel_type = |
| 5529 | cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); | ||
| 5532 | 5530 | ||
| 5533 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 5531 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
| 5534 | if ((new_channel < 1) || (new_channel > 14)) | 5532 | if ((new_channel < 1) || (new_channel > 14)) |
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 092c0140c249..9a5b6bc27d24 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h | |||
| @@ -54,10 +54,15 @@ | |||
| 54 | #define B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT 7 | 54 | #define B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT 7 |
| 55 | #define B43_NPHY_C1_INITGAIN_TRRX 0x1000 /* TR RX index */ | 55 | #define B43_NPHY_C1_INITGAIN_TRRX 0x1000 /* TR RX index */ |
| 56 | #define B43_NPHY_C1_INITGAIN_TRTX 0x2000 /* TR TX index */ | 56 | #define B43_NPHY_C1_INITGAIN_TRTX 0x2000 /* TR TX index */ |
| 57 | #define B43_NPHY_REV3_C1_INITGAIN_A B43_PHY_N(0x020) | ||
| 57 | #define B43_NPHY_C1_CLIP1_HIGAIN B43_PHY_N(0x021) /* Core 1 clip1 high gain code */ | 58 | #define B43_NPHY_C1_CLIP1_HIGAIN B43_PHY_N(0x021) /* Core 1 clip1 high gain code */ |
| 59 | #define B43_NPHY_REV3_C1_INITGAIN_B B43_PHY_N(0x021) | ||
| 58 | #define B43_NPHY_C1_CLIP1_MEDGAIN B43_PHY_N(0x022) /* Core 1 clip1 medium gain code */ | 60 | #define B43_NPHY_C1_CLIP1_MEDGAIN B43_PHY_N(0x022) /* Core 1 clip1 medium gain code */ |
| 61 | #define B43_NPHY_REV3_C1_CLIP_HIGAIN_A B43_PHY_N(0x022) | ||
| 59 | #define B43_NPHY_C1_CLIP1_LOGAIN B43_PHY_N(0x023) /* Core 1 clip1 low gain code */ | 62 | #define B43_NPHY_C1_CLIP1_LOGAIN B43_PHY_N(0x023) /* Core 1 clip1 low gain code */ |
| 63 | #define B43_NPHY_REV3_C1_CLIP_HIGAIN_B B43_PHY_N(0x023) | ||
| 60 | #define B43_NPHY_C1_CLIP2_GAIN B43_PHY_N(0x024) /* Core 1 clip2 gain code */ | 64 | #define B43_NPHY_C1_CLIP2_GAIN B43_PHY_N(0x024) /* Core 1 clip2 gain code */ |
| 65 | #define B43_NPHY_REV3_C1_CLIP_MEDGAIN_A B43_PHY_N(0x024) | ||
| 61 | #define B43_NPHY_C1_FILTERGAIN B43_PHY_N(0x025) /* Core 1 filter gain */ | 66 | #define B43_NPHY_C1_FILTERGAIN B43_PHY_N(0x025) /* Core 1 filter gain */ |
| 62 | #define B43_NPHY_C1_LPF_QHPF_BW B43_PHY_N(0x026) /* Core 1 LPF Q HP F bandwidth */ | 67 | #define B43_NPHY_C1_LPF_QHPF_BW B43_PHY_N(0x026) /* Core 1 LPF Q HP F bandwidth */ |
| 63 | #define B43_NPHY_C1_CLIPWBTHRES B43_PHY_N(0x027) /* Core 1 clip wideband threshold */ | 68 | #define B43_NPHY_C1_CLIPWBTHRES B43_PHY_N(0x027) /* Core 1 clip wideband threshold */ |
| @@ -107,10 +112,15 @@ | |||
| 107 | #define B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT 7 | 112 | #define B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT 7 |
| 108 | #define B43_NPHY_C2_INITGAIN_TRRX 0x1000 /* TR RX index */ | 113 | #define B43_NPHY_C2_INITGAIN_TRRX 0x1000 /* TR RX index */ |
| 109 | #define B43_NPHY_C2_INITGAIN_TRTX 0x2000 /* TR TX index */ | 114 | #define B43_NPHY_C2_INITGAIN_TRTX 0x2000 /* TR TX index */ |
| 115 | #define B43_NPHY_REV3_C1_CLIP_MEDGAIN_B B43_PHY_N(0x036) | ||
| 110 | #define B43_NPHY_C2_CLIP1_HIGAIN B43_PHY_N(0x037) /* Core 2 clip1 high gain code */ | 116 | #define B43_NPHY_C2_CLIP1_HIGAIN B43_PHY_N(0x037) /* Core 2 clip1 high gain code */ |
| 117 | #define B43_NPHY_REV3_C1_CLIP_LOGAIN_A B43_PHY_N(0x037) | ||
| 111 | #define B43_NPHY_C2_CLIP1_MEDGAIN B43_PHY_N(0x038) /* Core 2 clip1 medium gain code */ | 118 | #define B43_NPHY_C2_CLIP1_MEDGAIN B43_PHY_N(0x038) /* Core 2 clip1 medium gain code */ |
| 119 | #define B43_NPHY_REV3_C1_CLIP_LOGAIN_B B43_PHY_N(0x038) | ||
| 112 | #define B43_NPHY_C2_CLIP1_LOGAIN B43_PHY_N(0x039) /* Core 2 clip1 low gain code */ | 120 | #define B43_NPHY_C2_CLIP1_LOGAIN B43_PHY_N(0x039) /* Core 2 clip1 low gain code */ |
| 121 | #define B43_NPHY_REV3_C1_CLIP2_GAIN_A B43_PHY_N(0x039) | ||
| 113 | #define B43_NPHY_C2_CLIP2_GAIN B43_PHY_N(0x03A) /* Core 2 clip2 gain code */ | 122 | #define B43_NPHY_C2_CLIP2_GAIN B43_PHY_N(0x03A) /* Core 2 clip2 gain code */ |
| 123 | #define B43_NPHY_REV3_C1_CLIP2_GAIN_B B43_PHY_N(0x03A) | ||
| 114 | #define B43_NPHY_C2_FILTERGAIN B43_PHY_N(0x03B) /* Core 2 filter gain */ | 124 | #define B43_NPHY_C2_FILTERGAIN B43_PHY_N(0x03B) /* Core 2 filter gain */ |
| 115 | #define B43_NPHY_C2_LPF_QHPF_BW B43_PHY_N(0x03C) /* Core 2 LPF Q HP F bandwidth */ | 125 | #define B43_NPHY_C2_LPF_QHPF_BW B43_PHY_N(0x03C) /* Core 2 LPF Q HP F bandwidth */ |
| 116 | #define B43_NPHY_C2_CLIPWBTHRES B43_PHY_N(0x03D) /* Core 2 clip wideband threshold */ | 126 | #define B43_NPHY_C2_CLIPWBTHRES B43_PHY_N(0x03D) /* Core 2 clip wideband threshold */ |
| @@ -706,10 +716,146 @@ | |||
| 706 | #define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power control init */ | 716 | #define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power control init */ |
| 707 | #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ | 717 | #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ |
| 708 | #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 | 718 | #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 |
| 719 | #define B43_NPHY_ED_CRSEN B43_PHY_N(0x223) | ||
| 720 | #define B43_NPHY_ED_CRS40ASSERTTHRESH0 B43_PHY_N(0x224) | ||
| 721 | #define B43_NPHY_ED_CRS40ASSERTTHRESH1 B43_PHY_N(0x225) | ||
| 722 | #define B43_NPHY_ED_CRS40DEASSERTTHRESH0 B43_PHY_N(0x226) | ||
| 723 | #define B43_NPHY_ED_CRS40DEASSERTTHRESH1 B43_PHY_N(0x227) | ||
| 724 | #define B43_NPHY_ED_CRS20LASSERTTHRESH0 B43_PHY_N(0x228) | ||
| 725 | #define B43_NPHY_ED_CRS20LASSERTTHRESH1 B43_PHY_N(0x229) | ||
| 726 | #define B43_NPHY_ED_CRS20LDEASSERTTHRESH0 B43_PHY_N(0x22A) | ||
| 727 | #define B43_NPHY_ED_CRS20LDEASSERTTHRESH1 B43_PHY_N(0x22B) | ||
| 728 | #define B43_NPHY_ED_CRS20UASSERTTHRESH0 B43_PHY_N(0x22C) | ||
| 729 | #define B43_NPHY_ED_CRS20UASSERTTHRESH1 B43_PHY_N(0x22D) | ||
| 730 | #define B43_NPHY_ED_CRS20UDEASSERTTHRESH0 B43_PHY_N(0x22E) | ||
| 731 | #define B43_NPHY_ED_CRS20UDEASSERTTHRESH1 B43_PHY_N(0x22F) | ||
| 732 | #define B43_NPHY_ED_CRS B43_PHY_N(0x230) | ||
| 733 | #define B43_NPHY_TIMEOUTEN B43_PHY_N(0x231) | ||
| 734 | #define B43_NPHY_OFDMPAYDECODETIMEOUTLEN B43_PHY_N(0x232) | ||
| 735 | #define B43_NPHY_CCKPAYDECODETIMEOUTLEN B43_PHY_N(0x233) | ||
| 736 | #define B43_NPHY_NONPAYDECODETIMEOUTLEN B43_PHY_N(0x234) | ||
| 737 | #define B43_NPHY_TIMEOUTSTATUS B43_PHY_N(0x235) | ||
| 738 | #define B43_NPHY_RFCTRLCORE0GPIO0 B43_PHY_N(0x236) | ||
| 739 | #define B43_NPHY_RFCTRLCORE0GPIO1 B43_PHY_N(0x237) | ||
| 740 | #define B43_NPHY_RFCTRLCORE0GPIO2 B43_PHY_N(0x238) | ||
| 741 | #define B43_NPHY_RFCTRLCORE0GPIO3 B43_PHY_N(0x239) | ||
| 742 | #define B43_NPHY_RFCTRLCORE1GPIO0 B43_PHY_N(0x23A) | ||
| 743 | #define B43_NPHY_RFCTRLCORE1GPIO1 B43_PHY_N(0x23B) | ||
| 744 | #define B43_NPHY_RFCTRLCORE1GPIO2 B43_PHY_N(0x23C) | ||
| 745 | #define B43_NPHY_RFCTRLCORE1GPIO3 B43_PHY_N(0x23D) | ||
| 746 | #define B43_NPHY_BPHYTESTCONTROL B43_PHY_N(0x23E) | ||
| 747 | /* REV3+ */ | ||
| 748 | #define B43_NPHY_FORCEFRONT0 B43_PHY_N(0x23F) | ||
| 749 | #define B43_NPHY_FORCEFRONT1 B43_PHY_N(0x240) | ||
| 750 | #define B43_NPHY_NORMVARHYSTTH B43_PHY_N(0x241) | ||
| 751 | #define B43_NPHY_TXCCKERROR B43_PHY_N(0x242) | ||
| 752 | #define B43_NPHY_AFESEQINITDACGAIN B43_PHY_N(0x243) | ||
| 753 | #define B43_NPHY_TXANTSWLUT B43_PHY_N(0x244) | ||
| 754 | #define B43_NPHY_CORECONFIG B43_PHY_N(0x245) | ||
| 755 | #define B43_NPHY_ANTENNADIVDWELLTIME B43_PHY_N(0x246) | ||
| 756 | #define B43_NPHY_ANTENNACCKDIVDWELLTIME B43_PHY_N(0x247) | ||
| 757 | #define B43_NPHY_ANTENNADIVBACKOFFGAIN B43_PHY_N(0x248) | ||
| 758 | #define B43_NPHY_ANTENNADIVMINGAIN B43_PHY_N(0x249) | ||
| 759 | #define B43_NPHY_BRDSEL_NORMVARHYSTTH B43_PHY_N(0x24A) | ||
| 760 | #define B43_NPHY_RXANTSWITCHCTRL B43_PHY_N(0x24B) | ||
| 761 | #define B43_NPHY_ENERGYDROPTIMEOUTLEN2 B43_PHY_N(0x24C) | ||
| 762 | #define B43_NPHY_ML_LOG_TXEVM0 B43_PHY_N(0x250) | ||
| 763 | #define B43_NPHY_ML_LOG_TXEVM1 B43_PHY_N(0x251) | ||
| 764 | #define B43_NPHY_ML_LOG_TXEVM2 B43_PHY_N(0x252) | ||
| 765 | #define B43_NPHY_ML_LOG_TXEVM3 B43_PHY_N(0x253) | ||
| 766 | #define B43_NPHY_ML_LOG_TXEVM4 B43_PHY_N(0x254) | ||
| 767 | #define B43_NPHY_ML_LOG_TXEVM5 B43_PHY_N(0x255) | ||
| 768 | #define B43_NPHY_ML_LOG_TXEVM6 B43_PHY_N(0x256) | ||
| 769 | #define B43_NPHY_ML_LOG_TXEVM7 B43_PHY_N(0x257) | ||
| 770 | #define B43_NPHY_ML_SCALE_TWEAK B43_PHY_N(0x258) | ||
| 771 | #define B43_NPHY_MLUA B43_PHY_N(0x259) | ||
| 772 | #define B43_NPHY_ZFUA B43_PHY_N(0x25A) | ||
| 773 | #define B43_NPHY_CHANUPSYM01 B43_PHY_N(0x25B) | ||
| 774 | #define B43_NPHY_CHANUPSYM2 B43_PHY_N(0x25C) | ||
| 775 | #define B43_NPHY_RXSTRNFILT20NUM00 B43_PHY_N(0x25D) | ||
| 776 | #define B43_NPHY_RXSTRNFILT20NUM01 B43_PHY_N(0x25E) | ||
| 777 | #define B43_NPHY_RXSTRNFILT20NUM02 B43_PHY_N(0x25F) | ||
| 778 | #define B43_NPHY_RXSTRNFILT20DEN00 B43_PHY_N(0x260) | ||
| 779 | #define B43_NPHY_RXSTRNFILT20DEN01 B43_PHY_N(0x261) | ||
| 780 | #define B43_NPHY_RXSTRNFILT20NUM10 B43_PHY_N(0x262) | ||
| 781 | #define B43_NPHY_RXSTRNFILT20NUM11 B43_PHY_N(0x263) | ||
| 782 | #define B43_NPHY_RXSTRNFILT20NUM12 B43_PHY_N(0x264) | ||
| 783 | #define B43_NPHY_RXSTRNFILT20DEN10 B43_PHY_N(0x265) | ||
| 784 | #define B43_NPHY_RXSTRNFILT20DEN11 B43_PHY_N(0x266) | ||
| 785 | #define B43_NPHY_RXSTRNFILT40NUM00 B43_PHY_N(0x267) | ||
| 786 | #define B43_NPHY_RXSTRNFILT40NUM01 B43_PHY_N(0x268) | ||
| 787 | #define B43_NPHY_RXSTRNFILT40NUM02 B43_PHY_N(0x269) | ||
| 788 | #define B43_NPHY_RXSTRNFILT40DEN00 B43_PHY_N(0x26A) | ||
| 789 | #define B43_NPHY_RXSTRNFILT40DEN01 B43_PHY_N(0x26B) | ||
| 790 | #define B43_NPHY_RXSTRNFILT40NUM10 B43_PHY_N(0x26C) | ||
| 791 | #define B43_NPHY_RXSTRNFILT40NUM11 B43_PHY_N(0x26D) | ||
| 792 | #define B43_NPHY_RXSTRNFILT40NUM12 B43_PHY_N(0x26E) | ||
| 793 | #define B43_NPHY_RXSTRNFILT40DEN10 B43_PHY_N(0x26F) | ||
| 794 | #define B43_NPHY_RXSTRNFILT40DEN11 B43_PHY_N(0x270) | ||
| 795 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD1 B43_PHY_N(0x271) | ||
| 796 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD2 B43_PHY_N(0x272) | ||
| 797 | #define B43_NPHY_CRSHIGHLOWPOWTHRESHOLD B43_PHY_N(0x273) | ||
| 798 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD1L B43_PHY_N(0x274) | ||
| 799 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD2L B43_PHY_N(0x275) | ||
| 800 | #define B43_NPHY_CRSHIGHLOWPOWTHRESHOLDL B43_PHY_N(0x276) | ||
| 801 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD1U B43_PHY_N(0x277) | ||
| 802 | #define B43_NPHY_CRSHIGHPOWTHRESHOLD2U B43_PHY_N(0x278) | ||
| 803 | #define B43_NPHY_CRSHIGHLOWPOWTHRESHOLDU B43_PHY_N(0x279) | ||
| 804 | #define B43_NPHY_CRSACIDETECTTHRESH B43_PHY_N(0x27A) | ||
| 805 | #define B43_NPHY_CRSACIDETECTTHRESHL B43_PHY_N(0x27B) | ||
| 806 | #define B43_NPHY_CRSACIDETECTTHRESHU B43_PHY_N(0x27C) | ||
| 807 | #define B43_NPHY_CRSMINPOWER0 B43_PHY_N(0x27D) | ||
| 808 | #define B43_NPHY_CRSMINPOWER1 B43_PHY_N(0x27E) | ||
| 809 | #define B43_NPHY_CRSMINPOWER2 B43_PHY_N(0x27F) | ||
| 810 | #define B43_NPHY_CRSMINPOWERL0 B43_PHY_N(0x280) | ||
| 811 | #define B43_NPHY_CRSMINPOWERL1 B43_PHY_N(0x281) | ||
| 812 | #define B43_NPHY_CRSMINPOWERL2 B43_PHY_N(0x282) | ||
| 813 | #define B43_NPHY_CRSMINPOWERU0 B43_PHY_N(0x283) | ||
| 814 | #define B43_NPHY_CRSMINPOWERU1 B43_PHY_N(0x284) | ||
| 815 | #define B43_NPHY_CRSMINPOWERU2 B43_PHY_N(0x285) | ||
| 816 | #define B43_NPHY_STRPARAM B43_PHY_N(0x286) | ||
| 817 | #define B43_NPHY_STRPARAML B43_PHY_N(0x287) | ||
| 818 | #define B43_NPHY_STRPARAMU B43_PHY_N(0x288) | ||
| 819 | #define B43_NPHY_BPHYCRSMINPOWER0 B43_PHY_N(0x289) | ||
| 820 | #define B43_NPHY_BPHYCRSMINPOWER1 B43_PHY_N(0x28A) | ||
| 821 | #define B43_NPHY_BPHYCRSMINPOWER2 B43_PHY_N(0x28B) | ||
| 822 | #define B43_NPHY_BPHYFILTDEN0COEF B43_PHY_N(0x28C) | ||
| 823 | #define B43_NPHY_BPHYFILTDEN1COEF B43_PHY_N(0x28D) | ||
| 824 | #define B43_NPHY_BPHYFILTDEN2COEF B43_PHY_N(0x28E) | ||
| 825 | #define B43_NPHY_BPHYFILTNUM0COEF B43_PHY_N(0x28F) | ||
| 826 | #define B43_NPHY_BPHYFILTNUM1COEF B43_PHY_N(0x290) | ||
| 827 | #define B43_NPHY_BPHYFILTNUM2COEF B43_PHY_N(0x291) | ||
| 828 | #define B43_NPHY_BPHYFILTNUM01COEF2 B43_PHY_N(0x292) | ||
| 829 | #define B43_NPHY_BPHYFILTBYPASS B43_PHY_N(0x293) | ||
| 830 | #define B43_NPHY_SGILTRNOFFSET B43_PHY_N(0x294) | ||
| 831 | #define B43_NPHY_RADAR_T2_MIN B43_PHY_N(0x295) | ||
| 832 | #define B43_NPHY_TXPWRCTRLDAMPING B43_PHY_N(0x296) | ||
| 709 | #define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */ | 833 | #define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */ |
| 710 | #define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */ | 834 | #define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */ |
| 835 | #define B43_NPHY_EPS_OVERRIDEI_0 B43_PHY_N(0x299) | ||
| 836 | #define B43_NPHY_EPS_OVERRIDEQ_0 B43_PHY_N(0x29A) | ||
| 711 | #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ | 837 | #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ |
| 712 | #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ | 838 | #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ |
| 839 | #define B43_NPHY_EPS_OVERRIDEI_1 B43_PHY_N(0x29D) | ||
| 840 | #define B43_NPHY_EPS_OVERRIDEQ_1 B43_PHY_N(0x29E) | ||
| 841 | #define B43_NPHY_PAPD_CAL_ADDRESS B43_PHY_N(0x29F) | ||
| 842 | #define B43_NPHY_PAPD_CAL_YREFEPSILON B43_PHY_N(0x2A0) | ||
| 843 | #define B43_NPHY_PAPD_CAL_SETTLE B43_PHY_N(0x2A1) | ||
| 844 | #define B43_NPHY_PAPD_CAL_CORRELATE B43_PHY_N(0x2A2) | ||
| 845 | #define B43_NPHY_PAPD_CAL_SHIFTS0 B43_PHY_N(0x2A3) | ||
| 846 | #define B43_NPHY_PAPD_CAL_SHIFTS1 B43_PHY_N(0x2A4) | ||
| 847 | #define B43_NPHY_SAMPLE_START_ADDR B43_PHY_N(0x2A5) | ||
| 848 | #define B43_NPHY_RADAR_ADC_TO_DBM B43_PHY_N(0x2A6) | ||
| 849 | #define B43_NPHY_REV3_C2_INITGAIN_A B43_PHY_N(0x2A7) | ||
| 850 | #define B43_NPHY_REV3_C2_INITGAIN_B B43_PHY_N(0x2A8) | ||
| 851 | #define B43_NPHY_REV3_C2_CLIP_HIGAIN_A B43_PHY_N(0x2A9) | ||
| 852 | #define B43_NPHY_REV3_C2_CLIP_HIGAIN_B B43_PHY_N(0x2AA) | ||
| 853 | #define B43_NPHY_REV3_C2_CLIP_MEDGAIN_A B43_PHY_N(0x2AB) | ||
| 854 | #define B43_NPHY_REV3_C2_CLIP_MEDGAIN_B B43_PHY_N(0x2AC) | ||
| 855 | #define B43_NPHY_REV3_C2_CLIP_LOGAIN_A B43_PHY_N(0x2AD) | ||
| 856 | #define B43_NPHY_REV3_C2_CLIP_LOGAIN_B B43_PHY_N(0x2AE) | ||
| 857 | #define B43_NPHY_REV3_C2_CLIP2_GAIN_A B43_PHY_N(0x2AF) | ||
| 858 | #define B43_NPHY_REV3_C2_CLIP2_GAIN_B B43_PHY_N(0x2B0) | ||
| 713 | 859 | ||
| 714 | #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ | 860 | #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ |
| 715 | #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) | 861 | #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) |
diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c index d4ce8a12ff9a..38e31d857e3e 100644 --- a/drivers/net/wireless/b43/radio_2059.c +++ b/drivers/net/wireless/b43/radio_2059.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ | 28 | #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ |
| 29 | r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ | 29 | r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ |
| 30 | r20, r21, r22, r23, r24, r25, r26, r27, r28) \ | 30 | r20) \ |
| 31 | .radio_syn16 = r00, \ | 31 | .radio_syn16 = r00, \ |
| 32 | .radio_syn17 = r01, \ | 32 | .radio_syn17 = r01, \ |
| 33 | .radio_syn22 = r02, \ | 33 | .radio_syn22 = r02, \ |
| @@ -41,22 +41,14 @@ | |||
| 41 | .radio_syn41 = r10, \ | 41 | .radio_syn41 = r10, \ |
| 42 | .radio_syn43 = r11, \ | 42 | .radio_syn43 = r11, \ |
| 43 | .radio_syn47 = r12, \ | 43 | .radio_syn47 = r12, \ |
| 44 | .radio_syn4a = r13, \ | 44 | .radio_rxtx4a = r13, \ |
| 45 | .radio_syn58 = r14, \ | 45 | .radio_rxtx58 = r14, \ |
| 46 | .radio_syn5a = r15, \ | 46 | .radio_rxtx5a = r15, \ |
| 47 | .radio_syn6a = r16, \ | 47 | .radio_rxtx6a = r16, \ |
| 48 | .radio_syn6d = r17, \ | 48 | .radio_rxtx6d = r17, \ |
| 49 | .radio_syn6e = r18, \ | 49 | .radio_rxtx6e = r18, \ |
| 50 | .radio_syn92 = r19, \ | 50 | .radio_rxtx92 = r19, \ |
| 51 | .radio_syn98 = r20, \ | 51 | .radio_rxtx98 = r20 |
| 52 | .radio_rxtx4a = r21, \ | ||
| 53 | .radio_rxtx58 = r22, \ | ||
| 54 | .radio_rxtx5a = r23, \ | ||
| 55 | .radio_rxtx6a = r24, \ | ||
| 56 | .radio_rxtx6d = r25, \ | ||
| 57 | .radio_rxtx6e = r26, \ | ||
| 58 | .radio_rxtx92 = r27, \ | ||
| 59 | .radio_rxtx98 = r28 | ||
| 60 | 52 | ||
| 61 | #define PHYREGS(r0, r1, r2, r3, r4, r5) \ | 53 | #define PHYREGS(r0, r1, r2, r3, r4, r5) \ |
| 62 | .phy_regs.bw1 = r0, \ | 54 | .phy_regs.bw1 = r0, \ |
| @@ -70,91 +62,78 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi | |||
| 70 | { .freq = 2412, | 62 | { .freq = 2412, |
| 71 | RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, | 63 | RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, |
| 72 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, | 64 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, |
| 73 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 74 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 65 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 75 | PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), | 66 | PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), |
| 76 | }, | 67 | }, |
| 77 | { .freq = 2417, | 68 | { .freq = 2417, |
| 78 | RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, | 69 | RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, |
| 79 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, | 70 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, |
| 80 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 81 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 71 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 82 | PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), | 72 | PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), |
| 83 | }, | 73 | }, |
| 84 | { .freq = 2422, | 74 | { .freq = 2422, |
| 85 | RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, | 75 | RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, |
| 86 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, | 76 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, |
| 87 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 88 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 77 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 89 | PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), | 78 | PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), |
| 90 | }, | 79 | }, |
| 91 | { .freq = 2427, | 80 | { .freq = 2427, |
| 92 | RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, | 81 | RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, |
| 93 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, | 82 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, |
| 94 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 95 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 83 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 96 | PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), | 84 | PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), |
| 97 | }, | 85 | }, |
| 98 | { .freq = 2432, | 86 | { .freq = 2432, |
| 99 | RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, | 87 | RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, |
| 100 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, | 88 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, |
| 101 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 102 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 89 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 103 | PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), | 90 | PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), |
| 104 | }, | 91 | }, |
| 105 | { .freq = 2437, | 92 | { .freq = 2437, |
| 106 | RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, | 93 | RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, |
| 107 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, | 94 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, |
| 108 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 109 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 95 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 110 | PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), | 96 | PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), |
| 111 | }, | 97 | }, |
| 112 | { .freq = 2442, | 98 | { .freq = 2442, |
| 113 | RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, | 99 | RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, |
| 114 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 100 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, |
| 115 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 116 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 101 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 117 | PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), | 102 | PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), |
| 118 | }, | 103 | }, |
| 119 | { .freq = 2447, | 104 | { .freq = 2447, |
| 120 | RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, | 105 | RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, |
| 121 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 106 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, |
| 122 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 123 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 107 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 124 | PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), | 108 | PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), |
| 125 | }, | 109 | }, |
| 126 | { .freq = 2452, | 110 | { .freq = 2452, |
| 127 | RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, | 111 | RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, |
| 128 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 112 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, |
| 129 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 130 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 113 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 131 | PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), | 114 | PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), |
| 132 | }, | 115 | }, |
| 133 | { .freq = 2457, | 116 | { .freq = 2457, |
| 134 | RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, | 117 | RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, |
| 135 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, | 118 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, |
| 136 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 137 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 119 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 138 | PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), | 120 | PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), |
| 139 | }, | 121 | }, |
| 140 | { .freq = 2462, | 122 | { .freq = 2462, |
| 141 | RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, | 123 | RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, |
| 142 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, | 124 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, |
| 143 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 144 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 125 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 145 | PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), | 126 | PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), |
| 146 | }, | 127 | }, |
| 147 | { .freq = 2467, | 128 | { .freq = 2467, |
| 148 | RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, | 129 | RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, |
| 149 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, | 130 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, |
| 150 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 151 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 131 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 152 | PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), | 132 | PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), |
| 153 | }, | 133 | }, |
| 154 | { .freq = 2472, | 134 | { .freq = 2472, |
| 155 | RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, | 135 | RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, |
| 156 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, | 136 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, |
| 157 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, | ||
| 158 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 137 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
| 159 | PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), | 138 | PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), |
| 160 | }, | 139 | }, |
diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h index e4d69e55e9fe..40a82d7f510c 100644 --- a/drivers/net/wireless/b43/radio_2059.h +++ b/drivers/net/wireless/b43/radio_2059.h | |||
| @@ -5,9 +5,9 @@ | |||
| 5 | 5 | ||
| 6 | #include "phy_ht.h" | 6 | #include "phy_ht.h" |
| 7 | 7 | ||
| 8 | #define R2059_SYN 0x000 | 8 | #define R2059_C1 0x000 |
| 9 | #define R2059_TXRX0 0x400 | 9 | #define R2059_C2 0x400 |
| 10 | #define R2059_RXRX1 0x800 | 10 | #define R2059_C3 0x800 |
| 11 | #define R2059_ALL 0xC00 | 11 | #define R2059_ALL 0xC00 |
| 12 | 12 | ||
| 13 | /* Values for various registers uploaded on channel switching */ | 13 | /* Values for various registers uploaded on channel switching */ |
| @@ -28,14 +28,6 @@ struct b43_phy_ht_channeltab_e_radio2059 { | |||
| 28 | u8 radio_syn41; | 28 | u8 radio_syn41; |
| 29 | u8 radio_syn43; | 29 | u8 radio_syn43; |
| 30 | u8 radio_syn47; | 30 | u8 radio_syn47; |
| 31 | u8 radio_syn4a; | ||
| 32 | u8 radio_syn58; | ||
| 33 | u8 radio_syn5a; | ||
| 34 | u8 radio_syn6a; | ||
| 35 | u8 radio_syn6d; | ||
| 36 | u8 radio_syn6e; | ||
| 37 | u8 radio_syn92; | ||
| 38 | u8 radio_syn98; | ||
| 39 | u8 radio_rxtx4a; | 31 | u8 radio_rxtx4a; |
| 40 | u8 radio_rxtx58; | 32 | u8 radio_rxtx58; |
| 41 | u8 radio_rxtx5a; | 33 | u8 radio_rxtx5a; |
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 110510d53958..94c755fdda14 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
| @@ -2174,7 +2174,7 @@ static const u16 b43_ntab_loftlt1_r3[] = { | |||
| 2174 | /* volatile tables, PHY revision >= 3 */ | 2174 | /* volatile tables, PHY revision >= 3 */ |
| 2175 | 2175 | ||
| 2176 | /* indexed by antswctl2g */ | 2176 | /* indexed by antswctl2g */ |
| 2177 | static const u16 b43_ntab_antswctl2g_r3[4][32] = { | 2177 | static const u16 b43_ntab_antswctl_r3[4][32] = { |
| 2178 | { | 2178 | { |
| 2179 | 0x0082, 0x0082, 0x0211, 0x0222, 0x0328, | 2179 | 0x0082, 0x0082, 0x0211, 0x0222, 0x0328, |
| 2180 | 0x0000, 0x0000, 0x0000, 0x0144, 0x0000, | 2180 | 0x0000, 0x0000, 0x0000, 0x0144, 0x0000, |
| @@ -3095,9 +3095,55 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | |||
| 3095 | } | 3095 | } |
| 3096 | 3096 | ||
| 3097 | #define ntab_upload(dev, offset, data) do { \ | 3097 | #define ntab_upload(dev, offset, data) do { \ |
| 3098 | b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \ | 3098 | b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ |
| 3099 | } while (0) | 3099 | } while (0) |
| 3100 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) | 3100 | |
| 3101 | static void b43_nphy_tables_init_rev3(struct b43_wldev *dev) | ||
| 3102 | { | ||
| 3103 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
| 3104 | u8 antswlut; | ||
| 3105 | |||
| 3106 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
| 3107 | antswlut = sprom->fem.ghz5.antswlut; | ||
| 3108 | else | ||
| 3109 | antswlut = sprom->fem.ghz2.antswlut; | ||
| 3110 | |||
| 3111 | /* Static tables */ | ||
| 3112 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3); | ||
| 3113 | ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3); | ||
| 3114 | ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); | ||
| 3115 | ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); | ||
| 3116 | ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); | ||
| 3117 | ntab_upload(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); | ||
| 3118 | ntab_upload(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3); | ||
| 3119 | ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); | ||
| 3120 | ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); | ||
| 3121 | ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); | ||
| 3122 | ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3); | ||
| 3123 | ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3); | ||
| 3124 | ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); | ||
| 3125 | ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); | ||
| 3126 | ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); | ||
| 3127 | ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3); | ||
| 3128 | ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3); | ||
| 3129 | ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3); | ||
| 3130 | ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3); | ||
| 3131 | ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3); | ||
| 3132 | ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3); | ||
| 3133 | ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3); | ||
| 3134 | ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3); | ||
| 3135 | ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3); | ||
| 3136 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3); | ||
| 3137 | |||
| 3138 | /* Volatile tables */ | ||
| 3139 | if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3)) | ||
| 3140 | ntab_upload(dev, B43_NTAB_ANT_SW_CTL_R3, | ||
| 3141 | b43_ntab_antswctl_r3[antswlut]); | ||
| 3142 | else | ||
| 3143 | B43_WARN_ON(1); | ||
| 3144 | } | ||
| 3145 | |||
| 3146 | static void b43_nphy_tables_init_rev0(struct b43_wldev *dev) | ||
| 3101 | { | 3147 | { |
| 3102 | /* Static tables */ | 3148 | /* Static tables */ |
| 3103 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); | 3149 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); |
| @@ -3130,48 +3176,13 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) | |||
| 3130 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); | 3176 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); |
| 3131 | } | 3177 | } |
| 3132 | 3178 | ||
| 3133 | #define ntab_upload_r3(dev, offset, data) do { \ | 3179 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */ |
| 3134 | b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ | 3180 | void b43_nphy_tables_init(struct b43_wldev *dev) |
| 3135 | } while (0) | ||
| 3136 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) | ||
| 3137 | { | 3181 | { |
| 3138 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | 3182 | if (dev->phy.rev >= 3) |
| 3139 | 3183 | b43_nphy_tables_init_rev3(dev); | |
| 3140 | /* Static tables */ | ||
| 3141 | ntab_upload_r3(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3); | ||
| 3142 | ntab_upload_r3(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3); | ||
| 3143 | ntab_upload_r3(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); | ||
| 3144 | ntab_upload_r3(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); | ||
| 3145 | ntab_upload_r3(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); | ||
| 3146 | ntab_upload_r3(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); | ||
| 3147 | ntab_upload_r3(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3); | ||
| 3148 | ntab_upload_r3(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); | ||
| 3149 | ntab_upload_r3(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); | ||
| 3150 | ntab_upload_r3(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); | ||
| 3151 | ntab_upload_r3(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3); | ||
| 3152 | ntab_upload_r3(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3); | ||
| 3153 | ntab_upload_r3(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); | ||
| 3154 | ntab_upload_r3(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); | ||
| 3155 | ntab_upload_r3(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); | ||
| 3156 | ntab_upload_r3(dev, B43_NTAB_C0_ESTPLT_R3, | ||
| 3157 | b43_ntab_estimatepowerlt0_r3); | ||
| 3158 | ntab_upload_r3(dev, B43_NTAB_C1_ESTPLT_R3, | ||
| 3159 | b43_ntab_estimatepowerlt1_r3); | ||
| 3160 | ntab_upload_r3(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3); | ||
| 3161 | ntab_upload_r3(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3); | ||
| 3162 | ntab_upload_r3(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3); | ||
| 3163 | ntab_upload_r3(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3); | ||
| 3164 | ntab_upload_r3(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3); | ||
| 3165 | ntab_upload_r3(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3); | ||
| 3166 | ntab_upload_r3(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3); | ||
| 3167 | ntab_upload_r3(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3); | ||
| 3168 | |||
| 3169 | /* Volatile tables */ | ||
| 3170 | if (sprom->fem.ghz2.antswlut < ARRAY_SIZE(b43_ntab_antswctl2g_r3)) | ||
| 3171 | ntab_upload_r3(dev, B43_NTAB_ANT_SW_CTL_R3, | ||
| 3172 | b43_ntab_antswctl2g_r3[sprom->fem.ghz2.antswlut]); | ||
| 3173 | else | 3184 | else |
| 3174 | B43_WARN_ON(1); | 3185 | b43_nphy_tables_init_rev0(dev); |
| 3175 | } | 3186 | } |
| 3176 | 3187 | ||
| 3177 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ | 3188 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ |
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index c600700ceedc..9ff33adcff89 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
| @@ -115,22 +115,22 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
| 115 | #define B43_NTAB_NOISEVAR11_SIZE 256 | 115 | #define B43_NTAB_NOISEVAR11_SIZE 256 |
| 116 | #define B43_NTAB_C0_ESTPLT B43_NTAB8 (0x1A, 0x000) /* Estimate Power Lookup Table Core 0 */ | 116 | #define B43_NTAB_C0_ESTPLT B43_NTAB8 (0x1A, 0x000) /* Estimate Power Lookup Table Core 0 */ |
| 117 | #define B43_NTAB_C0_ESTPLT_SIZE 64 | 117 | #define B43_NTAB_C0_ESTPLT_SIZE 64 |
| 118 | #define B43_NTAB_C1_ESTPLT B43_NTAB8 (0x1B, 0x000) /* Estimate Power Lookup Table Core 1 */ | ||
| 119 | #define B43_NTAB_C1_ESTPLT_SIZE 64 | ||
| 120 | #define B43_NTAB_C0_ADJPLT B43_NTAB8 (0x1A, 0x040) /* Adjust Power Lookup Table Core 0 */ | 118 | #define B43_NTAB_C0_ADJPLT B43_NTAB8 (0x1A, 0x040) /* Adjust Power Lookup Table Core 0 */ |
| 121 | #define B43_NTAB_C0_ADJPLT_SIZE 128 | 119 | #define B43_NTAB_C0_ADJPLT_SIZE 128 |
| 122 | #define B43_NTAB_C1_ADJPLT B43_NTAB8 (0x1B, 0x040) /* Adjust Power Lookup Table Core 1 */ | ||
| 123 | #define B43_NTAB_C1_ADJPLT_SIZE 128 | ||
| 124 | #define B43_NTAB_C0_GAINCTL B43_NTAB32(0x1A, 0x0C0) /* Gain Control Lookup Table Core 0 */ | 120 | #define B43_NTAB_C0_GAINCTL B43_NTAB32(0x1A, 0x0C0) /* Gain Control Lookup Table Core 0 */ |
| 125 | #define B43_NTAB_C0_GAINCTL_SIZE 128 | 121 | #define B43_NTAB_C0_GAINCTL_SIZE 128 |
| 126 | #define B43_NTAB_C1_GAINCTL B43_NTAB32(0x1B, 0x0C0) /* Gain Control Lookup Table Core 1 */ | ||
| 127 | #define B43_NTAB_C1_GAINCTL_SIZE 128 | ||
| 128 | #define B43_NTAB_C0_IQLT B43_NTAB32(0x1A, 0x140) /* IQ Lookup Table Core 0 */ | 122 | #define B43_NTAB_C0_IQLT B43_NTAB32(0x1A, 0x140) /* IQ Lookup Table Core 0 */ |
| 129 | #define B43_NTAB_C0_IQLT_SIZE 128 | 123 | #define B43_NTAB_C0_IQLT_SIZE 128 |
| 130 | #define B43_NTAB_C1_IQLT B43_NTAB32(0x1B, 0x140) /* IQ Lookup Table Core 1 */ | ||
| 131 | #define B43_NTAB_C1_IQLT_SIZE 128 | ||
| 132 | #define B43_NTAB_C0_LOFEEDTH B43_NTAB16(0x1A, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 0 */ | 124 | #define B43_NTAB_C0_LOFEEDTH B43_NTAB16(0x1A, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 0 */ |
| 133 | #define B43_NTAB_C0_LOFEEDTH_SIZE 128 | 125 | #define B43_NTAB_C0_LOFEEDTH_SIZE 128 |
| 126 | #define B43_NTAB_C1_ESTPLT B43_NTAB8 (0x1B, 0x000) /* Estimate Power Lookup Table Core 1 */ | ||
| 127 | #define B43_NTAB_C1_ESTPLT_SIZE 64 | ||
| 128 | #define B43_NTAB_C1_ADJPLT B43_NTAB8 (0x1B, 0x040) /* Adjust Power Lookup Table Core 1 */ | ||
| 129 | #define B43_NTAB_C1_ADJPLT_SIZE 128 | ||
| 130 | #define B43_NTAB_C1_GAINCTL B43_NTAB32(0x1B, 0x0C0) /* Gain Control Lookup Table Core 1 */ | ||
| 131 | #define B43_NTAB_C1_GAINCTL_SIZE 128 | ||
| 132 | #define B43_NTAB_C1_IQLT B43_NTAB32(0x1B, 0x140) /* IQ Lookup Table Core 1 */ | ||
| 133 | #define B43_NTAB_C1_IQLT_SIZE 128 | ||
| 134 | #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ | 134 | #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ |
| 135 | #define B43_NTAB_C1_LOFEEDTH_SIZE 128 | 135 | #define B43_NTAB_C1_LOFEEDTH_SIZE 128 |
| 136 | 136 | ||
| @@ -154,15 +154,17 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | |||
| 154 | #define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 0) /* channel estimate */ | 154 | #define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 0) /* channel estimate */ |
| 155 | #define B43_NTAB_FRAMELT_R3 B43_NTAB8(24, 0) /* frame lookup */ | 155 | #define B43_NTAB_FRAMELT_R3 B43_NTAB8(24, 0) /* frame lookup */ |
| 156 | #define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8(26, 0) /* estimated power lookup 0 */ | 156 | #define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8(26, 0) /* estimated power lookup 0 */ |
| 157 | #define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8(27, 0) /* estimated power lookup 1 */ | ||
| 158 | #define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8(26, 64) /* adjusted power lookup 0 */ | 157 | #define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8(26, 64) /* adjusted power lookup 0 */ |
| 159 | #define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8(27, 64) /* adjusted power lookup 1 */ | ||
| 160 | #define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */ | 158 | #define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */ |
| 161 | #define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */ | ||
| 162 | #define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */ | 159 | #define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */ |
| 163 | #define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */ | ||
| 164 | #define B43_NTAB_C0_LOFEEDTH_R3 B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0 */ | 160 | #define B43_NTAB_C0_LOFEEDTH_R3 B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0 */ |
| 161 | #define B43_NTAB_C0_PAPD_COMP_R3 B43_NTAB16(26, 576) | ||
| 162 | #define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8(27, 0) /* estimated power lookup 1 */ | ||
| 163 | #define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8(27, 64) /* adjusted power lookup 1 */ | ||
| 164 | #define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */ | ||
| 165 | #define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */ | ||
| 165 | #define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */ | 166 | #define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */ |
| 167 | #define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576) | ||
| 166 | 168 | ||
| 167 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 | 169 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 |
| 168 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 | 170 | #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 |
| @@ -182,8 +184,7 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); | |||
| 182 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | 184 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, |
| 183 | unsigned int nr_elements, const void *_data); | 185 | unsigned int nr_elements, const void *_data); |
| 184 | 186 | ||
| 185 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); | 187 | void b43_nphy_tables_init(struct b43_wldev *dev); |
| 186 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); | ||
| 187 | 188 | ||
| 188 | const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); | 189 | const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); |
| 189 | 190 | ||
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 8c3f70e1a013..572668821862 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
| @@ -2720,7 +2720,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
| 2720 | goto out_unlock_mutex; | 2720 | goto out_unlock_mutex; |
| 2721 | 2721 | ||
| 2722 | /* Switch the PHY mode (if necessary). */ | 2722 | /* Switch the PHY mode (if necessary). */ |
| 2723 | switch (conf->channel->band) { | 2723 | switch (conf->chandef.chan->band) { |
| 2724 | case IEEE80211_BAND_2GHZ: | 2724 | case IEEE80211_BAND_2GHZ: |
| 2725 | if (phy->type == B43legacy_PHYTYPE_B) | 2725 | if (phy->type == B43legacy_PHYTYPE_B) |
| 2726 | new_phymode = B43legacy_PHYMODE_B; | 2726 | new_phymode = B43legacy_PHYMODE_B; |
| @@ -2748,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
| 2748 | 2748 | ||
| 2749 | /* Switch to the requested channel. | 2749 | /* Switch to the requested channel. |
| 2750 | * The firmware takes care of races with the TX handler. */ | 2750 | * The firmware takes care of races with the TX handler. */ |
| 2751 | if (conf->channel->hw_value != phy->channel) | 2751 | if (conf->chandef.chan->hw_value != phy->channel) |
| 2752 | b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); | 2752 | b43legacy_radio_selectchannel(dev, conf->chandef.chan->hw_value, |
| 2753 | 0); | ||
| 2753 | 2754 | ||
| 2754 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); | 2755 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); |
| 2755 | 2756 | ||
| @@ -3558,7 +3559,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 3558 | if (idx != 0) | 3559 | if (idx != 0) |
| 3559 | return -ENOENT; | 3560 | return -ENOENT; |
| 3560 | 3561 | ||
| 3561 | survey->channel = conf->channel; | 3562 | survey->channel = conf->chandef.chan; |
| 3562 | survey->filled = SURVEY_INFO_NOISE_DBM; | 3563 | survey->filled = SURVEY_INFO_NOISE_DBM; |
| 3563 | survey->noise = dev->stats.link_noise; | 3564 | survey->noise = dev->stats.link_noise; |
| 3564 | 3565 | ||
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index 747e9317dabd..fc8a0fa6d3b2 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
| @@ -37,15 +37,6 @@ config BRCMFMAC_SDIO | |||
| 37 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to | 37 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to |
| 38 | use the driver for a SDIO wireless card. | 38 | use the driver for a SDIO wireless card. |
| 39 | 39 | ||
| 40 | config BRCMFMAC_SDIO_OOB | ||
| 41 | bool "Out of band interrupt support for SDIO interface chipset" | ||
| 42 | depends on BRCMFMAC_SDIO | ||
| 43 | ---help--- | ||
| 44 | This option enables out-of-band interrupt support for Broadcom | ||
| 45 | SDIO Wifi chipset using fullmac in order to gain better | ||
| 46 | performance and deep sleep wake up capability on certain | ||
| 47 | platforms. Say N if you are unsure. | ||
| 48 | |||
| 49 | config BRCMFMAC_USB | 40 | config BRCMFMAC_USB |
| 50 | bool "USB bus interface support for FullMAC driver" | 41 | bool "USB bus interface support for FullMAC driver" |
| 51 | depends on USB | 42 | depends on USB |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 598c8e2f8d2b..8e9b1221b32c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
| @@ -30,7 +30,8 @@ brcmfmac-objs += \ | |||
| 30 | p2p.o \ | 30 | p2p.o \ |
| 31 | dhd_cdc.o \ | 31 | dhd_cdc.o \ |
| 32 | dhd_common.o \ | 32 | dhd_common.o \ |
| 33 | dhd_linux.o | 33 | dhd_linux.o \ |
| 34 | btcoex.o | ||
| 34 | brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ | 35 | brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ |
| 35 | dhd_sdio.o \ | 36 | dhd_sdio.o \ |
| 36 | bcmsdh.o \ | 37 | bcmsdh.o \ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index f3149debede0..4891e3df2058 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/mmc/sdio.h> | 25 | #include <linux/mmc/sdio.h> |
| 26 | #include <linux/mmc/sdio_func.h> | 26 | #include <linux/mmc/sdio_func.h> |
| 27 | #include <linux/mmc/card.h> | 27 | #include <linux/mmc/card.h> |
| 28 | #include <linux/platform_data/brcmfmac-sdio.h> | ||
| 28 | 29 | ||
| 29 | #include <defs.h> | 30 | #include <defs.h> |
| 30 | #include <brcm_hw_ids.h> | 31 | #include <brcm_hw_ids.h> |
| @@ -37,16 +38,15 @@ | |||
| 37 | 38 | ||
| 38 | #define SDIOH_API_ACCESS_RETRY_LIMIT 2 | 39 | #define SDIOH_API_ACCESS_RETRY_LIMIT 2 |
| 39 | 40 | ||
| 40 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 41 | |
| 41 | static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) | 42 | static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) |
| 42 | { | 43 | { |
| 43 | struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); | 44 | struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); |
| 44 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 45 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
| 45 | 46 | ||
| 46 | brcmf_dbg(INTR, "oob intr triggered\n"); | 47 | brcmf_dbg(INTR, "OOB intr triggered\n"); |
| 47 | 48 | ||
| 48 | /* | 49 | /* out-of-band interrupt is level-triggered which won't |
| 49 | * out-of-band interrupt is level-triggered which won't | ||
| 50 | * be cleared until dpc | 50 | * be cleared until dpc |
| 51 | */ | 51 | */ |
| 52 | if (sdiodev->irq_en) { | 52 | if (sdiodev->irq_en) { |
| @@ -59,72 +59,12 @@ static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) | |||
| 59 | return IRQ_HANDLED; | 59 | return IRQ_HANDLED; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | 62 | static void brcmf_sdio_ib_irqhandler(struct sdio_func *func) |
| 63 | { | ||
| 64 | int ret = 0; | ||
| 65 | u8 data; | ||
| 66 | unsigned long flags; | ||
| 67 | |||
| 68 | brcmf_dbg(SDIO, "Entering: irq %d\n", sdiodev->irq); | ||
| 69 | |||
| 70 | ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, | ||
| 71 | sdiodev->irq_flags, "brcmf_oob_intr", | ||
| 72 | &sdiodev->func[1]->dev); | ||
| 73 | if (ret != 0) | ||
| 74 | return ret; | ||
| 75 | spin_lock_init(&sdiodev->irq_en_lock); | ||
| 76 | spin_lock_irqsave(&sdiodev->irq_en_lock, flags); | ||
| 77 | sdiodev->irq_en = true; | ||
| 78 | spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); | ||
| 79 | |||
| 80 | ret = enable_irq_wake(sdiodev->irq); | ||
| 81 | if (ret != 0) | ||
| 82 | return ret; | ||
| 83 | sdiodev->irq_wake = true; | ||
| 84 | |||
| 85 | sdio_claim_host(sdiodev->func[1]); | ||
| 86 | |||
| 87 | /* must configure SDIO_CCCR_IENx to enable irq */ | ||
| 88 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); | ||
| 89 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; | ||
| 90 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); | ||
| 91 | |||
| 92 | /* redirect, configure and enable io for interrupt signal */ | ||
| 93 | data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; | ||
| 94 | if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH) | ||
| 95 | data |= SDIO_SEPINT_ACT_HI; | ||
| 96 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); | ||
| 97 | |||
| 98 | sdio_release_host(sdiodev->func[1]); | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | ||
| 104 | { | ||
| 105 | brcmf_dbg(SDIO, "Entering\n"); | ||
| 106 | |||
| 107 | sdio_claim_host(sdiodev->func[1]); | ||
| 108 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); | ||
| 109 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); | ||
| 110 | sdio_release_host(sdiodev->func[1]); | ||
| 111 | |||
| 112 | if (sdiodev->irq_wake) { | ||
| 113 | disable_irq_wake(sdiodev->irq); | ||
| 114 | sdiodev->irq_wake = false; | ||
| 115 | } | ||
| 116 | free_irq(sdiodev->irq, &sdiodev->func[1]->dev); | ||
| 117 | sdiodev->irq_en = false; | ||
| 118 | |||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | #else /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 122 | static void brcmf_sdio_irqhandler(struct sdio_func *func) | ||
| 123 | { | 63 | { |
| 124 | struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); | 64 | struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); |
| 125 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 65 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
| 126 | 66 | ||
| 127 | brcmf_dbg(INTR, "ib intr triggered\n"); | 67 | brcmf_dbg(INTR, "IB intr triggered\n"); |
| 128 | 68 | ||
| 129 | brcmf_sdbrcm_isr(sdiodev->bus); | 69 | brcmf_sdbrcm_isr(sdiodev->bus); |
| 130 | } | 70 | } |
| @@ -136,12 +76,56 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) | |||
| 136 | 76 | ||
| 137 | int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | 77 | int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) |
| 138 | { | 78 | { |
| 139 | brcmf_dbg(SDIO, "Entering\n"); | 79 | int ret = 0; |
| 80 | u8 data; | ||
| 81 | unsigned long flags; | ||
| 140 | 82 | ||
| 141 | sdio_claim_host(sdiodev->func[1]); | 83 | if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { |
| 142 | sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler); | 84 | brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", |
| 143 | sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); | 85 | sdiodev->pdata->oob_irq_nr); |
| 144 | sdio_release_host(sdiodev->func[1]); | 86 | ret = request_irq(sdiodev->pdata->oob_irq_nr, |
| 87 | brcmf_sdio_oob_irqhandler, | ||
| 88 | sdiodev->pdata->oob_irq_flags, | ||
| 89 | "brcmf_oob_intr", | ||
| 90 | &sdiodev->func[1]->dev); | ||
| 91 | if (ret != 0) { | ||
| 92 | brcmf_err("request_irq failed %d\n", ret); | ||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | sdiodev->oob_irq_requested = true; | ||
| 96 | spin_lock_init(&sdiodev->irq_en_lock); | ||
| 97 | spin_lock_irqsave(&sdiodev->irq_en_lock, flags); | ||
| 98 | sdiodev->irq_en = true; | ||
| 99 | spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); | ||
| 100 | |||
| 101 | ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr); | ||
| 102 | if (ret != 0) { | ||
| 103 | brcmf_err("enable_irq_wake failed %d\n", ret); | ||
| 104 | return ret; | ||
| 105 | } | ||
| 106 | sdiodev->irq_wake = true; | ||
| 107 | |||
| 108 | sdio_claim_host(sdiodev->func[1]); | ||
| 109 | |||
| 110 | /* must configure SDIO_CCCR_IENx to enable irq */ | ||
| 111 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); | ||
| 112 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; | ||
| 113 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); | ||
| 114 | |||
| 115 | /* redirect, configure and enable io for interrupt signal */ | ||
| 116 | data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; | ||
| 117 | if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) | ||
| 118 | data |= SDIO_SEPINT_ACT_HI; | ||
| 119 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); | ||
| 120 | |||
| 121 | sdio_release_host(sdiodev->func[1]); | ||
| 122 | } else { | ||
| 123 | brcmf_dbg(SDIO, "Entering\n"); | ||
| 124 | sdio_claim_host(sdiodev->func[1]); | ||
| 125 | sdio_claim_irq(sdiodev->func[1], brcmf_sdio_ib_irqhandler); | ||
| 126 | sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); | ||
| 127 | sdio_release_host(sdiodev->func[1]); | ||
| 128 | } | ||
| 145 | 129 | ||
| 146 | return 0; | 130 | return 0; |
| 147 | } | 131 | } |
| @@ -150,14 +134,31 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
| 150 | { | 134 | { |
| 151 | brcmf_dbg(SDIO, "Entering\n"); | 135 | brcmf_dbg(SDIO, "Entering\n"); |
| 152 | 136 | ||
| 153 | sdio_claim_host(sdiodev->func[1]); | 137 | if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { |
| 154 | sdio_release_irq(sdiodev->func[2]); | 138 | sdio_claim_host(sdiodev->func[1]); |
| 155 | sdio_release_irq(sdiodev->func[1]); | 139 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); |
| 156 | sdio_release_host(sdiodev->func[1]); | 140 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); |
| 141 | sdio_release_host(sdiodev->func[1]); | ||
| 142 | |||
| 143 | if (sdiodev->oob_irq_requested) { | ||
| 144 | sdiodev->oob_irq_requested = false; | ||
| 145 | if (sdiodev->irq_wake) { | ||
| 146 | disable_irq_wake(sdiodev->pdata->oob_irq_nr); | ||
| 147 | sdiodev->irq_wake = false; | ||
| 148 | } | ||
| 149 | free_irq(sdiodev->pdata->oob_irq_nr, | ||
| 150 | &sdiodev->func[1]->dev); | ||
| 151 | sdiodev->irq_en = false; | ||
| 152 | } | ||
| 153 | } else { | ||
| 154 | sdio_claim_host(sdiodev->func[1]); | ||
| 155 | sdio_release_irq(sdiodev->func[2]); | ||
| 156 | sdio_release_irq(sdiodev->func[1]); | ||
| 157 | sdio_release_host(sdiodev->func[1]); | ||
| 158 | } | ||
| 157 | 159 | ||
| 158 | return 0; | 160 | return 0; |
| 159 | } | 161 | } |
| 160 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 161 | 162 | ||
| 162 | int | 163 | int |
| 163 | brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | 164 | brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) |
| @@ -457,36 +458,80 @@ done: | |||
| 457 | return err; | 458 | return err; |
| 458 | } | 459 | } |
| 459 | 460 | ||
| 460 | int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, | 461 | int |
| 461 | u8 *buf, uint nbytes) | 462 | brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, |
| 463 | u8 *data, uint size) | ||
| 462 | { | 464 | { |
| 463 | struct sk_buff *mypkt; | 465 | int bcmerror = 0; |
| 464 | bool write = rw ? SDIOH_WRITE : SDIOH_READ; | 466 | struct sk_buff *pkt; |
| 465 | int err; | 467 | u32 sdaddr; |
| 468 | uint dsize; | ||
| 469 | |||
| 470 | dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); | ||
| 471 | pkt = dev_alloc_skb(dsize); | ||
| 472 | if (!pkt) { | ||
| 473 | brcmf_err("dev_alloc_skb failed: len %d\n", dsize); | ||
| 474 | return -EIO; | ||
| 475 | } | ||
| 476 | pkt->priority = 0; | ||
| 466 | 477 | ||
| 467 | addr &= SBSDIO_SB_OFT_ADDR_MASK; | 478 | /* Determine initial transfer parameters */ |
| 468 | addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | 479 | sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; |
| 480 | if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) | ||
| 481 | dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); | ||
| 482 | else | ||
| 483 | dsize = size; | ||
| 469 | 484 | ||
| 470 | mypkt = brcmu_pkt_buf_get_skb(nbytes); | 485 | sdio_claim_host(sdiodev->func[1]); |
| 471 | if (!mypkt) { | 486 | |
| 472 | brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", | 487 | /* Do the transfer(s) */ |
| 473 | nbytes); | 488 | while (size) { |
| 474 | return -EIO; | 489 | /* Set the backplane window to include the start address */ |
| 490 | bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address); | ||
| 491 | if (bcmerror) | ||
| 492 | break; | ||
| 493 | |||
| 494 | brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", | ||
| 495 | write ? "write" : "read", dsize, | ||
| 496 | sdaddr, address & SBSDIO_SBWINDOW_MASK); | ||
| 497 | |||
| 498 | sdaddr &= SBSDIO_SB_OFT_ADDR_MASK; | ||
| 499 | sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | ||
| 500 | |||
| 501 | skb_put(pkt, dsize); | ||
| 502 | if (write) | ||
| 503 | memcpy(pkt->data, data, dsize); | ||
| 504 | bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, | ||
| 505 | write, SDIO_FUNC_1, | ||
| 506 | sdaddr, pkt); | ||
| 507 | if (bcmerror) { | ||
| 508 | brcmf_err("membytes transfer failed\n"); | ||
| 509 | break; | ||
| 510 | } | ||
| 511 | if (!write) | ||
| 512 | memcpy(data, pkt->data, dsize); | ||
| 513 | skb_trim(pkt, dsize); | ||
| 514 | |||
| 515 | /* Adjust for next transfer (if any) */ | ||
| 516 | size -= dsize; | ||
| 517 | if (size) { | ||
| 518 | data += dsize; | ||
| 519 | address += dsize; | ||
| 520 | sdaddr = 0; | ||
| 521 | dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); | ||
| 522 | } | ||
| 475 | } | 523 | } |
| 476 | 524 | ||
| 477 | /* For a write, copy the buffer data into the packet. */ | 525 | dev_kfree_skb(pkt); |
| 478 | if (write) | ||
| 479 | memcpy(mypkt->data, buf, nbytes); | ||
| 480 | 526 | ||
| 481 | err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write, | 527 | /* Return the window to backplane enumeration space for core access */ |
| 482 | SDIO_FUNC_1, addr, mypkt); | 528 | if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad)) |
| 529 | brcmf_err("FAILED to set window back to 0x%x\n", | ||
| 530 | sdiodev->sbwad); | ||
| 483 | 531 | ||
| 484 | /* For a read, copy the packet data back to the buffer. */ | 532 | sdio_release_host(sdiodev->func[1]); |
| 485 | if (!err && !write) | ||
| 486 | memcpy(buf, mypkt->data, nbytes); | ||
| 487 | 533 | ||
| 488 | brcmu_pkt_buf_free_skb(mypkt); | 534 | return bcmerror; |
| 489 | return err; | ||
| 490 | } | 535 | } |
| 491 | 536 | ||
| 492 | int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) | 537 | int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 716548989e4f..44fa0cdbf97b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/sched.h> /* request_irq() */ | 26 | #include <linux/sched.h> /* request_irq() */ |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/platform_data/brcmfmac-sdio.h> | ||
| 29 | #include <net/cfg80211.h> | 30 | #include <net/cfg80211.h> |
| 30 | 31 | ||
| 31 | #include <defs.h> | 32 | #include <defs.h> |
| @@ -40,32 +41,30 @@ | |||
| 40 | 41 | ||
| 41 | #define DMA_ALIGN_MASK 0x03 | 42 | #define DMA_ALIGN_MASK 0x03 |
| 42 | 43 | ||
| 44 | #define SDIO_DEVICE_ID_BROADCOM_43143 43143 | ||
| 43 | #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 | 45 | #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 |
| 44 | #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 | 46 | #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 |
| 45 | #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 | 47 | #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 |
| 46 | #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 | 48 | #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 |
| 49 | #define SDIO_DEVICE_ID_BROADCOM_4335 0x4335 | ||
| 47 | 50 | ||
| 48 | #define SDIO_FUNC1_BLOCKSIZE 64 | 51 | #define SDIO_FUNC1_BLOCKSIZE 64 |
| 49 | #define SDIO_FUNC2_BLOCKSIZE 512 | 52 | #define SDIO_FUNC2_BLOCKSIZE 512 |
| 50 | 53 | ||
| 51 | /* devices we support, null terminated */ | 54 | /* devices we support, null terminated */ |
| 52 | static const struct sdio_device_id brcmf_sdmmc_ids[] = { | 55 | static const struct sdio_device_id brcmf_sdmmc_ids[] = { |
| 56 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, | ||
| 53 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, | 57 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, |
| 54 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, | 58 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, |
| 55 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, | 59 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, |
| 56 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, | 60 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, |
| 61 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335)}, | ||
| 57 | { /* end: all zeroes */ }, | 62 | { /* end: all zeroes */ }, |
| 58 | }; | 63 | }; |
| 59 | MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); | 64 | MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); |
| 60 | 65 | ||
| 61 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 66 | static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; |
| 62 | static struct list_head oobirq_lh; | 67 | |
| 63 | struct brcmf_sdio_oobirq { | ||
| 64 | unsigned int irq; | ||
| 65 | unsigned long flags; | ||
| 66 | struct list_head list; | ||
| 67 | }; | ||
| 68 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 69 | 68 | ||
| 70 | static bool | 69 | static bool |
| 71 | brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) | 70 | brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) |
| @@ -424,33 +423,6 @@ void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) | |||
| 424 | 423 | ||
| 425 | } | 424 | } |
| 426 | 425 | ||
| 427 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | ||
| 428 | static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) | ||
| 429 | { | ||
| 430 | struct brcmf_sdio_oobirq *oobirq_entry; | ||
| 431 | |||
| 432 | if (list_empty(&oobirq_lh)) { | ||
| 433 | brcmf_err("no valid oob irq resource\n"); | ||
| 434 | return -ENXIO; | ||
| 435 | } | ||
| 436 | |||
| 437 | oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq, | ||
| 438 | list); | ||
| 439 | |||
| 440 | sdiodev->irq = oobirq_entry->irq; | ||
| 441 | sdiodev->irq_flags = oobirq_entry->flags; | ||
| 442 | list_del(&oobirq_entry->list); | ||
| 443 | kfree(oobirq_entry); | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | #else | ||
| 448 | static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) | ||
| 449 | { | ||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 453 | |||
| 454 | static int brcmf_ops_sdio_probe(struct sdio_func *func, | 426 | static int brcmf_ops_sdio_probe(struct sdio_func *func, |
| 455 | const struct sdio_device_id *id) | 427 | const struct sdio_device_id *id) |
| 456 | { | 428 | { |
| @@ -491,15 +463,13 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
| 491 | dev_set_drvdata(&func->dev, bus_if); | 463 | dev_set_drvdata(&func->dev, bus_if); |
| 492 | dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); | 464 | dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); |
| 493 | sdiodev->dev = &sdiodev->func[1]->dev; | 465 | sdiodev->dev = &sdiodev->func[1]->dev; |
| 466 | sdiodev->pdata = brcmfmac_sdio_pdata; | ||
| 494 | 467 | ||
| 495 | atomic_set(&sdiodev->suspend, false); | 468 | atomic_set(&sdiodev->suspend, false); |
| 496 | init_waitqueue_head(&sdiodev->request_byte_wait); | 469 | init_waitqueue_head(&sdiodev->request_byte_wait); |
| 497 | init_waitqueue_head(&sdiodev->request_word_wait); | 470 | init_waitqueue_head(&sdiodev->request_word_wait); |
| 498 | init_waitqueue_head(&sdiodev->request_chain_wait); | 471 | init_waitqueue_head(&sdiodev->request_chain_wait); |
| 499 | init_waitqueue_head(&sdiodev->request_buffer_wait); | 472 | init_waitqueue_head(&sdiodev->request_buffer_wait); |
| 500 | err = brcmf_sdio_getintrcfg(sdiodev); | ||
| 501 | if (err) | ||
| 502 | goto fail; | ||
| 503 | 473 | ||
| 504 | brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); | 474 | brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); |
| 505 | err = brcmf_sdio_probe(sdiodev); | 475 | err = brcmf_sdio_probe(sdiodev); |
| @@ -594,7 +564,7 @@ static const struct dev_pm_ops brcmf_sdio_pm_ops = { | |||
| 594 | static struct sdio_driver brcmf_sdmmc_driver = { | 564 | static struct sdio_driver brcmf_sdmmc_driver = { |
| 595 | .probe = brcmf_ops_sdio_probe, | 565 | .probe = brcmf_ops_sdio_probe, |
| 596 | .remove = brcmf_ops_sdio_remove, | 566 | .remove = brcmf_ops_sdio_remove, |
| 597 | .name = "brcmfmac", | 567 | .name = BRCMFMAC_SDIO_PDATA_NAME, |
| 598 | .id_table = brcmf_sdmmc_ids, | 568 | .id_table = brcmf_sdmmc_ids, |
| 599 | #ifdef CONFIG_PM_SLEEP | 569 | #ifdef CONFIG_PM_SLEEP |
| 600 | .drv = { | 570 | .drv = { |
| @@ -603,72 +573,51 @@ static struct sdio_driver brcmf_sdmmc_driver = { | |||
| 603 | #endif /* CONFIG_PM_SLEEP */ | 573 | #endif /* CONFIG_PM_SLEEP */ |
| 604 | }; | 574 | }; |
| 605 | 575 | ||
| 606 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | ||
| 607 | static int brcmf_sdio_pd_probe(struct platform_device *pdev) | 576 | static int brcmf_sdio_pd_probe(struct platform_device *pdev) |
| 608 | { | 577 | { |
| 609 | struct resource *res; | 578 | int ret; |
| 610 | struct brcmf_sdio_oobirq *oobirq_entry; | ||
| 611 | int i, ret; | ||
| 612 | 579 | ||
| 613 | INIT_LIST_HEAD(&oobirq_lh); | 580 | brcmf_dbg(SDIO, "Enter\n"); |
| 614 | 581 | ||
| 615 | for (i = 0; ; i++) { | 582 | brcmfmac_sdio_pdata = pdev->dev.platform_data; |
| 616 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | ||
| 617 | if (!res) | ||
| 618 | break; | ||
| 619 | 583 | ||
| 620 | oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq), | 584 | if (brcmfmac_sdio_pdata->power_on) |
| 621 | GFP_KERNEL); | 585 | brcmfmac_sdio_pdata->power_on(); |
| 622 | if (!oobirq_entry) | ||
| 623 | return -ENOMEM; | ||
| 624 | oobirq_entry->irq = res->start; | ||
| 625 | oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK; | ||
| 626 | list_add_tail(&oobirq_entry->list, &oobirq_lh); | ||
| 627 | } | ||
| 628 | if (i == 0) | ||
| 629 | return -ENXIO; | ||
| 630 | 586 | ||
| 631 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | 587 | ret = sdio_register_driver(&brcmf_sdmmc_driver); |
| 632 | |||
| 633 | if (ret) | 588 | if (ret) |
| 634 | brcmf_err("sdio_register_driver failed: %d\n", ret); | 589 | brcmf_err("sdio_register_driver failed: %d\n", ret); |
| 635 | 590 | ||
| 636 | return ret; | 591 | return ret; |
| 637 | } | 592 | } |
| 638 | 593 | ||
| 639 | static struct platform_driver brcmf_sdio_pd = { | 594 | static int brcmf_sdio_pd_remove(struct platform_device *pdev) |
| 640 | .probe = brcmf_sdio_pd_probe, | ||
| 641 | .driver = { | ||
| 642 | .name = "brcmf_sdio_pd" | ||
| 643 | } | ||
| 644 | }; | ||
| 645 | |||
| 646 | void brcmf_sdio_exit(void) | ||
| 647 | { | 595 | { |
| 648 | brcmf_dbg(SDIO, "Enter\n"); | 596 | brcmf_dbg(SDIO, "Enter\n"); |
| 649 | 597 | ||
| 598 | if (brcmfmac_sdio_pdata->power_off) | ||
| 599 | brcmfmac_sdio_pdata->power_off(); | ||
| 600 | |||
| 650 | sdio_unregister_driver(&brcmf_sdmmc_driver); | 601 | sdio_unregister_driver(&brcmf_sdmmc_driver); |
| 651 | 602 | ||
| 652 | platform_driver_unregister(&brcmf_sdio_pd); | 603 | return 0; |
| 653 | } | 604 | } |
| 654 | 605 | ||
| 655 | void brcmf_sdio_init(void) | 606 | static struct platform_driver brcmf_sdio_pd = { |
| 656 | { | 607 | .remove = brcmf_sdio_pd_remove, |
| 657 | int ret; | 608 | .driver = { |
| 658 | 609 | .name = BRCMFMAC_SDIO_PDATA_NAME | |
| 659 | brcmf_dbg(SDIO, "Enter\n"); | 610 | } |
| 660 | 611 | }; | |
| 661 | ret = platform_driver_register(&brcmf_sdio_pd); | ||
| 662 | 612 | ||
| 663 | if (ret) | ||
| 664 | brcmf_err("platform_driver_register failed: %d\n", ret); | ||
| 665 | } | ||
| 666 | #else | ||
| 667 | void brcmf_sdio_exit(void) | 613 | void brcmf_sdio_exit(void) |
| 668 | { | 614 | { |
| 669 | brcmf_dbg(SDIO, "Enter\n"); | 615 | brcmf_dbg(SDIO, "Enter\n"); |
| 670 | 616 | ||
| 671 | sdio_unregister_driver(&brcmf_sdmmc_driver); | 617 | if (brcmfmac_sdio_pdata) |
| 618 | platform_driver_unregister(&brcmf_sdio_pd); | ||
| 619 | else | ||
| 620 | sdio_unregister_driver(&brcmf_sdmmc_driver); | ||
| 672 | } | 621 | } |
| 673 | 622 | ||
| 674 | void brcmf_sdio_init(void) | 623 | void brcmf_sdio_init(void) |
| @@ -677,9 +626,12 @@ void brcmf_sdio_init(void) | |||
| 677 | 626 | ||
| 678 | brcmf_dbg(SDIO, "Enter\n"); | 627 | brcmf_dbg(SDIO, "Enter\n"); |
| 679 | 628 | ||
| 680 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | 629 | ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); |
| 630 | if (ret == -ENODEV) { | ||
| 631 | brcmf_dbg(SDIO, "No platform data available, registering without.\n"); | ||
| 632 | ret = sdio_register_driver(&brcmf_sdmmc_driver); | ||
| 633 | } | ||
| 681 | 634 | ||
| 682 | if (ret) | 635 | if (ret) |
| 683 | brcmf_err("sdio_register_driver failed: %d\n", ret); | 636 | brcmf_err("driver registration failed: %d\n", ret); |
| 684 | } | 637 | } |
| 685 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c new file mode 100644 index 000000000000..0cb591b050b3 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c | |||
| @@ -0,0 +1,497 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/netdevice.h> | ||
| 18 | #include <net/cfg80211.h> | ||
| 19 | |||
| 20 | #include <brcmu_wifi.h> | ||
| 21 | #include <brcmu_utils.h> | ||
| 22 | #include <defs.h> | ||
| 23 | #include <dhd.h> | ||
| 24 | #include <dhd_dbg.h> | ||
| 25 | #include "fwil.h" | ||
| 26 | #include "fwil_types.h" | ||
| 27 | #include "btcoex.h" | ||
| 28 | #include "p2p.h" | ||
| 29 | #include "wl_cfg80211.h" | ||
| 30 | |||
| 31 | /* T1 start SCO/eSCO priority suppression */ | ||
| 32 | #define BRCMF_BTCOEX_OPPR_WIN_TIME 2000 | ||
| 33 | |||
| 34 | /* BT registers values during DHCP */ | ||
| 35 | #define BRCMF_BT_DHCP_REG50 0x8022 | ||
| 36 | #define BRCMF_BT_DHCP_REG51 0 | ||
| 37 | #define BRCMF_BT_DHCP_REG64 0 | ||
| 38 | #define BRCMF_BT_DHCP_REG65 0 | ||
| 39 | #define BRCMF_BT_DHCP_REG71 0 | ||
| 40 | #define BRCMF_BT_DHCP_REG66 0x2710 | ||
| 41 | #define BRCMF_BT_DHCP_REG41 0x33 | ||
| 42 | #define BRCMF_BT_DHCP_REG68 0x190 | ||
| 43 | |||
| 44 | /* number of samples for SCO detection */ | ||
| 45 | #define BRCMF_BT_SCO_SAMPLES 12 | ||
| 46 | |||
| 47 | /** | ||
| 48 | * enum brcmf_btcoex_state - BT coex DHCP state machine states | ||
| 49 | * @BRCMF_BT_DHCP_IDLE: DCHP is idle | ||
| 50 | * @BRCMF_BT_DHCP_START: DHCP started, wait before | ||
| 51 | * boosting wifi priority | ||
| 52 | * @BRCMF_BT_DHCP_OPPR_WIN: graceful DHCP opportunity ended, | ||
| 53 | * boost wifi priority | ||
| 54 | * @BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT: wifi priority boost end, | ||
| 55 | * restore defaults | ||
| 56 | */ | ||
| 57 | enum brcmf_btcoex_state { | ||
| 58 | BRCMF_BT_DHCP_IDLE, | ||
| 59 | BRCMF_BT_DHCP_START, | ||
| 60 | BRCMF_BT_DHCP_OPPR_WIN, | ||
| 61 | BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT | ||
| 62 | }; | ||
| 63 | |||
| 64 | /** | ||
| 65 | * struct brcmf_btcoex_info - BT coex related information | ||
| 66 | * @vif: interface for which request was done. | ||
| 67 | * @timer: timer for DHCP state machine | ||
| 68 | * @timeout: configured timeout. | ||
| 69 | * @timer_on: DHCP timer active | ||
| 70 | * @dhcp_done: DHCP finished before T1/T2 timer expiration | ||
| 71 | * @bt_state: DHCP state machine state | ||
| 72 | * @work: DHCP state machine work | ||
| 73 | * @cfg: driver private data for cfg80211 interface | ||
| 74 | * @reg66: saved value of btc_params 66 | ||
| 75 | * @reg41: saved value of btc_params 41 | ||
| 76 | * @reg68: saved value of btc_params 68 | ||
| 77 | * @saved_regs_part1: flag indicating regs 66,41,68 | ||
| 78 | * have been saved | ||
| 79 | * @reg51: saved value of btc_params 51 | ||
| 80 | * @reg64: saved value of btc_params 64 | ||
| 81 | * @reg65: saved value of btc_params 65 | ||
| 82 | * @reg71: saved value of btc_params 71 | ||
| 83 | * @saved_regs_part1: flag indicating regs 50,51,64,65,71 | ||
| 84 | * have been saved | ||
| 85 | */ | ||
| 86 | struct brcmf_btcoex_info { | ||
| 87 | struct brcmf_cfg80211_vif *vif; | ||
| 88 | struct timer_list timer; | ||
| 89 | u16 timeout; | ||
| 90 | bool timer_on; | ||
| 91 | bool dhcp_done; | ||
| 92 | enum brcmf_btcoex_state bt_state; | ||
| 93 | struct work_struct work; | ||
| 94 | struct brcmf_cfg80211_info *cfg; | ||
| 95 | u32 reg66; | ||
| 96 | u32 reg41; | ||
| 97 | u32 reg68; | ||
| 98 | bool saved_regs_part1; | ||
| 99 | u32 reg50; | ||
| 100 | u32 reg51; | ||
| 101 | u32 reg64; | ||
| 102 | u32 reg65; | ||
| 103 | u32 reg71; | ||
| 104 | bool saved_regs_part2; | ||
| 105 | }; | ||
| 106 | |||
| 107 | /** | ||
| 108 | * brcmf_btcoex_params_write() - write btc_params firmware variable | ||
| 109 | * @ifp: interface | ||
| 110 | * @addr: btc_params register number | ||
| 111 | * @data: data to write | ||
| 112 | */ | ||
| 113 | static s32 brcmf_btcoex_params_write(struct brcmf_if *ifp, u32 addr, u32 data) | ||
| 114 | { | ||
| 115 | struct { | ||
| 116 | __le32 addr; | ||
| 117 | __le32 data; | ||
| 118 | } reg_write; | ||
| 119 | |||
| 120 | reg_write.addr = cpu_to_le32(addr); | ||
| 121 | reg_write.data = cpu_to_le32(data); | ||
| 122 | return brcmf_fil_iovar_data_set(ifp, "btc_params", | ||
| 123 | ®_write, sizeof(reg_write)); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * brcmf_btcoex_params_read() - read btc_params firmware variable | ||
| 128 | * @ifp: interface | ||
| 129 | * @addr: btc_params register number | ||
| 130 | * @data: read data | ||
| 131 | */ | ||
| 132 | static s32 brcmf_btcoex_params_read(struct brcmf_if *ifp, u32 addr, u32 *data) | ||
| 133 | { | ||
| 134 | *data = addr; | ||
| 135 | |||
| 136 | return brcmf_fil_iovar_int_get(ifp, "btc_params", data); | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * brcmf_btcoex_boost_wifi() - control BT SCO/eSCO parameters | ||
| 141 | * @btci: BT coex info | ||
| 142 | * @trump_sco: | ||
| 143 | * true - set SCO/eSCO parameters for compatibility | ||
| 144 | * during DHCP window | ||
| 145 | * false - restore saved parameter values | ||
| 146 | * | ||
| 147 | * Enhanced BT COEX settings for eSCO compatibility during DHCP window | ||
| 148 | */ | ||
| 149 | static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci, | ||
| 150 | bool trump_sco) | ||
| 151 | { | ||
| 152 | struct brcmf_if *ifp = btci->cfg->pub->iflist[0]; | ||
| 153 | |||
| 154 | if (trump_sco && !btci->saved_regs_part2) { | ||
| 155 | /* this should reduce eSCO agressive | ||
| 156 | * retransmit w/o breaking it | ||
| 157 | */ | ||
| 158 | |||
| 159 | /* save current */ | ||
| 160 | brcmf_dbg(TRACE, "new SCO/eSCO coex algo {save & override}\n"); | ||
| 161 | brcmf_btcoex_params_read(ifp, 50, &btci->reg50); | ||
| 162 | brcmf_btcoex_params_read(ifp, 51, &btci->reg51); | ||
| 163 | brcmf_btcoex_params_read(ifp, 64, &btci->reg64); | ||
| 164 | brcmf_btcoex_params_read(ifp, 65, &btci->reg65); | ||
| 165 | brcmf_btcoex_params_read(ifp, 71, &btci->reg71); | ||
| 166 | |||
| 167 | btci->saved_regs_part2 = true; | ||
| 168 | brcmf_dbg(TRACE, | ||
| 169 | "saved bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", | ||
| 170 | btci->reg50, btci->reg51, btci->reg64, | ||
| 171 | btci->reg65, btci->reg71); | ||
| 172 | |||
| 173 | /* pacify the eSco */ | ||
| 174 | brcmf_btcoex_params_write(ifp, 50, BRCMF_BT_DHCP_REG50); | ||
| 175 | brcmf_btcoex_params_write(ifp, 51, BRCMF_BT_DHCP_REG51); | ||
| 176 | brcmf_btcoex_params_write(ifp, 64, BRCMF_BT_DHCP_REG64); | ||
| 177 | brcmf_btcoex_params_write(ifp, 65, BRCMF_BT_DHCP_REG65); | ||
| 178 | brcmf_btcoex_params_write(ifp, 71, BRCMF_BT_DHCP_REG71); | ||
| 179 | |||
| 180 | } else if (btci->saved_regs_part2) { | ||
| 181 | /* restore previously saved bt params */ | ||
| 182 | brcmf_dbg(TRACE, "Do new SCO/eSCO coex algo {restore}\n"); | ||
| 183 | brcmf_btcoex_params_write(ifp, 50, btci->reg50); | ||
| 184 | brcmf_btcoex_params_write(ifp, 51, btci->reg51); | ||
| 185 | brcmf_btcoex_params_write(ifp, 64, btci->reg64); | ||
| 186 | brcmf_btcoex_params_write(ifp, 65, btci->reg65); | ||
| 187 | brcmf_btcoex_params_write(ifp, 71, btci->reg71); | ||
| 188 | |||
| 189 | brcmf_dbg(TRACE, | ||
| 190 | "restored bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", | ||
| 191 | btci->reg50, btci->reg51, btci->reg64, | ||
| 192 | btci->reg65, btci->reg71); | ||
| 193 | |||
| 194 | btci->saved_regs_part2 = false; | ||
| 195 | } else { | ||
| 196 | brcmf_err("attempted to restore not saved BTCOEX params\n"); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * brcmf_btcoex_is_sco_active() - check if SCO/eSCO is active | ||
| 202 | * @ifp: interface | ||
| 203 | * | ||
| 204 | * return: true if SCO/eSCO session is active | ||
| 205 | */ | ||
| 206 | static bool brcmf_btcoex_is_sco_active(struct brcmf_if *ifp) | ||
| 207 | { | ||
| 208 | int ioc_res = 0; | ||
| 209 | bool res = false; | ||
| 210 | int sco_id_cnt = 0; | ||
| 211 | u32 param27; | ||
| 212 | int i; | ||
| 213 | |||
| 214 | for (i = 0; i < BRCMF_BT_SCO_SAMPLES; i++) { | ||
| 215 | ioc_res = brcmf_btcoex_params_read(ifp, 27, ¶m27); | ||
| 216 | |||
| 217 | if (ioc_res < 0) { | ||
| 218 | brcmf_err("ioc read btc params error\n"); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | brcmf_dbg(TRACE, "sample[%d], btc_params 27:%x\n", i, param27); | ||
| 223 | |||
| 224 | if ((param27 & 0x6) == 2) { /* count both sco & esco */ | ||
| 225 | sco_id_cnt++; | ||
| 226 | } | ||
| 227 | |||
| 228 | if (sco_id_cnt > 2) { | ||
| 229 | brcmf_dbg(TRACE, | ||
| 230 | "sco/esco detected, pkt id_cnt:%d samples:%d\n", | ||
| 231 | sco_id_cnt, i); | ||
| 232 | res = true; | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | brcmf_dbg(TRACE, "exit: result=%d\n", res); | ||
| 237 | return res; | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * btcmf_btcoex_save_part1() - save first step parameters. | ||
| 242 | */ | ||
| 243 | static void btcmf_btcoex_save_part1(struct brcmf_btcoex_info *btci) | ||
| 244 | { | ||
| 245 | struct brcmf_if *ifp = btci->vif->ifp; | ||
| 246 | |||
| 247 | if (!btci->saved_regs_part1) { | ||
| 248 | /* Retrieve and save original reg value */ | ||
| 249 | brcmf_btcoex_params_read(ifp, 66, &btci->reg66); | ||
| 250 | brcmf_btcoex_params_read(ifp, 41, &btci->reg41); | ||
| 251 | brcmf_btcoex_params_read(ifp, 68, &btci->reg68); | ||
| 252 | btci->saved_regs_part1 = true; | ||
| 253 | brcmf_dbg(TRACE, | ||
| 254 | "saved btc_params regs (66,41,68) 0x%x 0x%x 0x%x\n", | ||
| 255 | btci->reg66, btci->reg41, | ||
| 256 | btci->reg68); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | |||
| 260 | /** | ||
| 261 | * brcmf_btcoex_restore_part1() - restore first step parameters. | ||
| 262 | */ | ||
| 263 | static void brcmf_btcoex_restore_part1(struct brcmf_btcoex_info *btci) | ||
| 264 | { | ||
| 265 | struct brcmf_if *ifp; | ||
| 266 | |||
| 267 | if (btci->saved_regs_part1) { | ||
| 268 | btci->saved_regs_part1 = false; | ||
| 269 | ifp = btci->vif->ifp; | ||
| 270 | brcmf_btcoex_params_write(ifp, 66, btci->reg66); | ||
| 271 | brcmf_btcoex_params_write(ifp, 41, btci->reg41); | ||
| 272 | brcmf_btcoex_params_write(ifp, 68, btci->reg68); | ||
| 273 | brcmf_dbg(TRACE, | ||
| 274 | "restored btc_params regs {66,41,68} 0x%x 0x%x 0x%x\n", | ||
| 275 | btci->reg66, btci->reg41, | ||
| 276 | btci->reg68); | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | /** | ||
| 281 | * brcmf_btcoex_timerfunc() - BT coex timer callback | ||
| 282 | */ | ||
| 283 | static void brcmf_btcoex_timerfunc(ulong data) | ||
| 284 | { | ||
| 285 | struct brcmf_btcoex_info *bt_local = (struct brcmf_btcoex_info *)data; | ||
| 286 | brcmf_dbg(TRACE, "enter\n"); | ||
| 287 | |||
| 288 | bt_local->timer_on = false; | ||
| 289 | schedule_work(&bt_local->work); | ||
| 290 | } | ||
| 291 | |||
| 292 | /** | ||
| 293 | * brcmf_btcoex_handler() - BT coex state machine work handler | ||
| 294 | * @work: work | ||
| 295 | */ | ||
| 296 | static void brcmf_btcoex_handler(struct work_struct *work) | ||
| 297 | { | ||
| 298 | struct brcmf_btcoex_info *btci; | ||
| 299 | btci = container_of(work, struct brcmf_btcoex_info, work); | ||
| 300 | if (btci->timer_on) { | ||
| 301 | btci->timer_on = false; | ||
| 302 | del_timer_sync(&btci->timer); | ||
| 303 | } | ||
| 304 | |||
| 305 | switch (btci->bt_state) { | ||
| 306 | case BRCMF_BT_DHCP_START: | ||
| 307 | /* DHCP started provide OPPORTUNITY window | ||
| 308 | to get DHCP address | ||
| 309 | */ | ||
| 310 | brcmf_dbg(TRACE, "DHCP started\n"); | ||
| 311 | btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN; | ||
| 312 | if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) { | ||
| 313 | mod_timer(&btci->timer, btci->timer.expires); | ||
| 314 | } else { | ||
| 315 | btci->timeout -= BRCMF_BTCOEX_OPPR_WIN_TIME; | ||
| 316 | mod_timer(&btci->timer, | ||
| 317 | jiffies + | ||
| 318 | msecs_to_jiffies(BRCMF_BTCOEX_OPPR_WIN_TIME)); | ||
| 319 | } | ||
| 320 | btci->timer_on = true; | ||
| 321 | break; | ||
| 322 | |||
| 323 | case BRCMF_BT_DHCP_OPPR_WIN: | ||
| 324 | if (btci->dhcp_done) { | ||
| 325 | brcmf_dbg(TRACE, "DHCP done before T1 expiration\n"); | ||
| 326 | goto idle; | ||
| 327 | } | ||
| 328 | |||
| 329 | /* DHCP is not over yet, start lowering BT priority */ | ||
| 330 | brcmf_dbg(TRACE, "DHCP T1:%d expired\n", | ||
| 331 | BRCMF_BTCOEX_OPPR_WIN_TIME); | ||
| 332 | brcmf_btcoex_boost_wifi(btci, true); | ||
| 333 | |||
| 334 | btci->bt_state = BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT; | ||
| 335 | mod_timer(&btci->timer, | ||
| 336 | jiffies + msecs_to_jiffies(btci->timeout)); | ||
| 337 | btci->timer_on = true; | ||
| 338 | break; | ||
| 339 | |||
| 340 | case BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT: | ||
| 341 | if (btci->dhcp_done) | ||
| 342 | brcmf_dbg(TRACE, "DHCP done before T2 expiration\n"); | ||
| 343 | else | ||
| 344 | brcmf_dbg(TRACE, "DHCP T2:%d expired\n", | ||
| 345 | BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT); | ||
| 346 | |||
| 347 | goto idle; | ||
| 348 | |||
| 349 | default: | ||
| 350 | brcmf_err("invalid state=%d !!!\n", btci->bt_state); | ||
| 351 | goto idle; | ||
| 352 | } | ||
| 353 | |||
| 354 | return; | ||
| 355 | |||
| 356 | idle: | ||
| 357 | btci->bt_state = BRCMF_BT_DHCP_IDLE; | ||
| 358 | btci->timer_on = false; | ||
| 359 | brcmf_btcoex_boost_wifi(btci, false); | ||
| 360 | cfg80211_crit_proto_stopped(&btci->vif->wdev, GFP_KERNEL); | ||
| 361 | brcmf_btcoex_restore_part1(btci); | ||
| 362 | btci->vif = NULL; | ||
| 363 | } | ||
| 364 | |||
| 365 | /** | ||
| 366 | * brcmf_btcoex_attach() - initialize BT coex data | ||
| 367 | * @cfg: driver private cfg80211 data | ||
| 368 | * | ||
| 369 | * return: 0 on success | ||
| 370 | */ | ||
| 371 | int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg) | ||
| 372 | { | ||
| 373 | struct brcmf_btcoex_info *btci = NULL; | ||
| 374 | brcmf_dbg(TRACE, "enter\n"); | ||
| 375 | |||
| 376 | btci = kmalloc(sizeof(struct brcmf_btcoex_info), GFP_KERNEL); | ||
| 377 | if (!btci) | ||
| 378 | return -ENOMEM; | ||
| 379 | |||
| 380 | btci->bt_state = BRCMF_BT_DHCP_IDLE; | ||
| 381 | |||
| 382 | /* Set up timer for BT */ | ||
| 383 | btci->timer_on = false; | ||
| 384 | btci->timeout = BRCMF_BTCOEX_OPPR_WIN_TIME; | ||
| 385 | init_timer(&btci->timer); | ||
| 386 | btci->timer.data = (ulong)btci; | ||
| 387 | btci->timer.function = brcmf_btcoex_timerfunc; | ||
| 388 | btci->cfg = cfg; | ||
| 389 | btci->saved_regs_part1 = false; | ||
| 390 | btci->saved_regs_part2 = false; | ||
| 391 | |||
| 392 | INIT_WORK(&btci->work, brcmf_btcoex_handler); | ||
| 393 | |||
| 394 | cfg->btcoex = btci; | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | /** | ||
| 399 | * brcmf_btcoex_detach - clean BT coex data | ||
| 400 | * @cfg: driver private cfg80211 data | ||
| 401 | */ | ||
| 402 | void brcmf_btcoex_detach(struct brcmf_cfg80211_info *cfg) | ||
| 403 | { | ||
| 404 | brcmf_dbg(TRACE, "enter\n"); | ||
| 405 | |||
| 406 | if (!cfg->btcoex) | ||
| 407 | return; | ||
| 408 | |||
| 409 | if (cfg->btcoex->timer_on) { | ||
| 410 | cfg->btcoex->timer_on = false; | ||
| 411 | del_timer_sync(&cfg->btcoex->timer); | ||
| 412 | } | ||
| 413 | |||
| 414 | cancel_work_sync(&cfg->btcoex->work); | ||
| 415 | |||
| 416 | brcmf_btcoex_boost_wifi(cfg->btcoex, false); | ||
| 417 | brcmf_btcoex_restore_part1(cfg->btcoex); | ||
| 418 | |||
| 419 | kfree(cfg->btcoex); | ||
| 420 | cfg->btcoex = NULL; | ||
| 421 | } | ||
| 422 | |||
| 423 | static void brcmf_btcoex_dhcp_start(struct brcmf_btcoex_info *btci) | ||
| 424 | { | ||
| 425 | struct brcmf_if *ifp = btci->vif->ifp; | ||
| 426 | |||
| 427 | btcmf_btcoex_save_part1(btci); | ||
| 428 | /* set new regs values */ | ||
| 429 | brcmf_btcoex_params_write(ifp, 66, BRCMF_BT_DHCP_REG66); | ||
| 430 | brcmf_btcoex_params_write(ifp, 41, BRCMF_BT_DHCP_REG41); | ||
| 431 | brcmf_btcoex_params_write(ifp, 68, BRCMF_BT_DHCP_REG68); | ||
| 432 | btci->dhcp_done = false; | ||
| 433 | btci->bt_state = BRCMF_BT_DHCP_START; | ||
| 434 | schedule_work(&btci->work); | ||
| 435 | brcmf_dbg(TRACE, "enable BT DHCP Timer\n"); | ||
| 436 | } | ||
| 437 | |||
| 438 | static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci) | ||
| 439 | { | ||
| 440 | /* Stop any bt timer because DHCP session is done */ | ||
| 441 | btci->dhcp_done = true; | ||
| 442 | if (btci->timer_on) { | ||
| 443 | brcmf_dbg(TRACE, "disable BT DHCP Timer\n"); | ||
| 444 | btci->timer_on = false; | ||
| 445 | del_timer_sync(&btci->timer); | ||
| 446 | |||
| 447 | /* schedule worker if transition to IDLE is needed */ | ||
| 448 | if (btci->bt_state != BRCMF_BT_DHCP_IDLE) { | ||
| 449 | brcmf_dbg(TRACE, "bt_state:%d\n", | ||
| 450 | btci->bt_state); | ||
| 451 | schedule_work(&btci->work); | ||
| 452 | } | ||
| 453 | } else { | ||
| 454 | /* Restore original values */ | ||
| 455 | brcmf_btcoex_restore_part1(btci); | ||
| 456 | } | ||
| 457 | } | ||
| 458 | |||
| 459 | /** | ||
| 460 | * brcmf_btcoex_set_mode - set BT coex mode | ||
| 461 | * @cfg: driver private cfg80211 data | ||
| 462 | * @mode: Wifi-Bluetooth coexistence mode | ||
| 463 | * | ||
| 464 | * return: 0 on success | ||
| 465 | */ | ||
| 466 | int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, | ||
| 467 | enum brcmf_btcoex_mode mode, u16 duration) | ||
| 468 | { | ||
| 469 | struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); | ||
| 470 | struct brcmf_btcoex_info *btci = cfg->btcoex; | ||
| 471 | struct brcmf_if *ifp = cfg->pub->iflist[0]; | ||
| 472 | |||
| 473 | switch (mode) { | ||
| 474 | case BRCMF_BTCOEX_DISABLED: | ||
| 475 | brcmf_dbg(TRACE, "DHCP session starts\n"); | ||
| 476 | if (btci->bt_state != BRCMF_BT_DHCP_IDLE) | ||
| 477 | return -EBUSY; | ||
| 478 | /* Start BT timer only for SCO connection */ | ||
| 479 | if (brcmf_btcoex_is_sco_active(ifp)) { | ||
| 480 | btci->timeout = duration; | ||
| 481 | btci->vif = vif; | ||
| 482 | brcmf_btcoex_dhcp_start(btci); | ||
| 483 | } | ||
| 484 | break; | ||
| 485 | |||
| 486 | case BRCMF_BTCOEX_ENABLED: | ||
| 487 | brcmf_dbg(TRACE, "DHCP session ends\n"); | ||
| 488 | if (btci->bt_state != BRCMF_BT_DHCP_IDLE && | ||
| 489 | vif == btci->vif) { | ||
| 490 | brcmf_btcoex_dhcp_end(btci); | ||
| 491 | } | ||
| 492 | break; | ||
| 493 | default: | ||
| 494 | brcmf_dbg(TRACE, "Unknown mode, ignored\n"); | ||
| 495 | } | ||
| 496 | return 0; | ||
| 497 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.h b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.h new file mode 100644 index 000000000000..19647c68aa9e --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #ifndef WL_BTCOEX_H_ | ||
| 17 | #define WL_BTCOEX_H_ | ||
| 18 | |||
| 19 | enum brcmf_btcoex_mode { | ||
| 20 | BRCMF_BTCOEX_DISABLED, | ||
| 21 | BRCMF_BTCOEX_ENABLED | ||
| 22 | }; | ||
| 23 | |||
| 24 | int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg); | ||
| 25 | void brcmf_btcoex_detach(struct brcmf_cfg80211_info *cfg); | ||
| 26 | int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, | ||
| 27 | enum brcmf_btcoex_mode mode, u16 duration); | ||
| 28 | |||
| 29 | #endif /* WL_BTCOEX_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 5249c67b466c..28db9cf39672 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | /******************************************************************************* | 28 | /******************************************************************************* |
| 29 | * IO codes that are interpreted by dongle firmware | 29 | * IO codes that are interpreted by dongle firmware |
| 30 | ******************************************************************************/ | 30 | ******************************************************************************/ |
| 31 | #define BRCMF_C_GET_VERSION 1 | ||
| 31 | #define BRCMF_C_UP 2 | 32 | #define BRCMF_C_UP 2 |
| 32 | #define BRCMF_C_DOWN 3 | 33 | #define BRCMF_C_DOWN 3 |
| 33 | #define BRCMF_C_SET_PROMISC 10 | 34 | #define BRCMF_C_SET_PROMISC 10 |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 763a84eba216..59c25463e428 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
| @@ -754,14 +754,14 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, | |||
| 754 | /* this is P2P_DEVICE interface */ | 754 | /* this is P2P_DEVICE interface */ |
| 755 | brcmf_dbg(INFO, "allocate non-netdev interface\n"); | 755 | brcmf_dbg(INFO, "allocate non-netdev interface\n"); |
| 756 | ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); | 756 | ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); |
| 757 | if (!ifp) | ||
| 758 | return ERR_PTR(-ENOMEM); | ||
| 757 | } else { | 759 | } else { |
| 758 | brcmf_dbg(INFO, "allocate netdev interface\n"); | 760 | brcmf_dbg(INFO, "allocate netdev interface\n"); |
| 759 | /* Allocate netdev, including space for private structure */ | 761 | /* Allocate netdev, including space for private structure */ |
| 760 | ndev = alloc_netdev(sizeof(*ifp), name, ether_setup); | 762 | ndev = alloc_netdev(sizeof(*ifp), name, ether_setup); |
| 761 | if (!ndev) { | 763 | if (!ndev) |
| 762 | brcmf_err("OOM - alloc_netdev\n"); | ||
| 763 | return ERR_PTR(-ENOMEM); | 764 | return ERR_PTR(-ENOMEM); |
| 764 | } | ||
| 765 | 765 | ||
| 766 | ifp = netdev_priv(ndev); | 766 | ifp = netdev_priv(ndev); |
| 767 | ifp->ndev = ndev; | 767 | ifp->ndev = ndev; |
| @@ -899,7 +899,10 @@ int brcmf_bus_start(struct device *dev) | |||
| 899 | goto fail; | 899 | goto fail; |
| 900 | 900 | ||
| 901 | drvr->fw_signals = true; | 901 | drvr->fw_signals = true; |
| 902 | (void)brcmf_fws_init(drvr); | 902 | ret = brcmf_fws_init(drvr); |
| 903 | if (ret < 0) | ||
| 904 | goto fail; | ||
| 905 | |||
| 903 | brcmf_fws_add_interface(ifp); | 906 | brcmf_fws_add_interface(ifp); |
| 904 | 907 | ||
| 905 | drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); | 908 | drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4ff2d3c52ee6..d2487518bd2a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/bcma/bcma.h> | 31 | #include <linux/bcma/bcma.h> |
| 32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
| 33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
| 34 | #include <linux/platform_data/brcmfmac-sdio.h> | ||
| 34 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
| 35 | #include <defs.h> | 36 | #include <defs.h> |
| 36 | #include <brcmu_wifi.h> | 37 | #include <brcmu_wifi.h> |
| @@ -324,6 +325,9 @@ MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME); | |||
| 324 | */ | 325 | */ |
| 325 | #define BRCMF_IDLE_INTERVAL 1 | 326 | #define BRCMF_IDLE_INTERVAL 1 |
| 326 | 327 | ||
| 328 | #define KSO_WAIT_US 50 | ||
| 329 | #define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) | ||
| 330 | |||
| 327 | /* | 331 | /* |
| 328 | * Conversion of 802.1D priority to precedence level | 332 | * Conversion of 802.1D priority to precedence level |
| 329 | */ | 333 | */ |
| @@ -333,95 +337,6 @@ static uint prio2prec(u32 prio) | |||
| 333 | (prio^2) : prio; | 337 | (prio^2) : prio; |
| 334 | } | 338 | } |
| 335 | 339 | ||
| 336 | /* core registers */ | ||
| 337 | struct sdpcmd_regs { | ||
| 338 | u32 corecontrol; /* 0x00, rev8 */ | ||
| 339 | u32 corestatus; /* rev8 */ | ||
| 340 | u32 PAD[1]; | ||
| 341 | u32 biststatus; /* rev8 */ | ||
| 342 | |||
| 343 | /* PCMCIA access */ | ||
| 344 | u16 pcmciamesportaladdr; /* 0x010, rev8 */ | ||
| 345 | u16 PAD[1]; | ||
| 346 | u16 pcmciamesportalmask; /* rev8 */ | ||
| 347 | u16 PAD[1]; | ||
| 348 | u16 pcmciawrframebc; /* rev8 */ | ||
| 349 | u16 PAD[1]; | ||
| 350 | u16 pcmciaunderflowtimer; /* rev8 */ | ||
| 351 | u16 PAD[1]; | ||
| 352 | |||
| 353 | /* interrupt */ | ||
| 354 | u32 intstatus; /* 0x020, rev8 */ | ||
| 355 | u32 hostintmask; /* rev8 */ | ||
| 356 | u32 intmask; /* rev8 */ | ||
| 357 | u32 sbintstatus; /* rev8 */ | ||
| 358 | u32 sbintmask; /* rev8 */ | ||
| 359 | u32 funcintmask; /* rev4 */ | ||
| 360 | u32 PAD[2]; | ||
| 361 | u32 tosbmailbox; /* 0x040, rev8 */ | ||
| 362 | u32 tohostmailbox; /* rev8 */ | ||
| 363 | u32 tosbmailboxdata; /* rev8 */ | ||
| 364 | u32 tohostmailboxdata; /* rev8 */ | ||
| 365 | |||
| 366 | /* synchronized access to registers in SDIO clock domain */ | ||
| 367 | u32 sdioaccess; /* 0x050, rev8 */ | ||
| 368 | u32 PAD[3]; | ||
| 369 | |||
| 370 | /* PCMCIA frame control */ | ||
| 371 | u8 pcmciaframectrl; /* 0x060, rev8 */ | ||
| 372 | u8 PAD[3]; | ||
| 373 | u8 pcmciawatermark; /* rev8 */ | ||
| 374 | u8 PAD[155]; | ||
| 375 | |||
| 376 | /* interrupt batching control */ | ||
| 377 | u32 intrcvlazy; /* 0x100, rev8 */ | ||
| 378 | u32 PAD[3]; | ||
| 379 | |||
| 380 | /* counters */ | ||
| 381 | u32 cmd52rd; /* 0x110, rev8 */ | ||
| 382 | u32 cmd52wr; /* rev8 */ | ||
| 383 | u32 cmd53rd; /* rev8 */ | ||
| 384 | u32 cmd53wr; /* rev8 */ | ||
| 385 | u32 abort; /* rev8 */ | ||
| 386 | u32 datacrcerror; /* rev8 */ | ||
| 387 | u32 rdoutofsync; /* rev8 */ | ||
| 388 | u32 wroutofsync; /* rev8 */ | ||
| 389 | u32 writebusy; /* rev8 */ | ||
| 390 | u32 readwait; /* rev8 */ | ||
| 391 | u32 readterm; /* rev8 */ | ||
| 392 | u32 writeterm; /* rev8 */ | ||
| 393 | u32 PAD[40]; | ||
| 394 | u32 clockctlstatus; /* rev8 */ | ||
| 395 | u32 PAD[7]; | ||
| 396 | |||
| 397 | u32 PAD[128]; /* DMA engines */ | ||
| 398 | |||
| 399 | /* SDIO/PCMCIA CIS region */ | ||
| 400 | char cis[512]; /* 0x400-0x5ff, rev6 */ | ||
| 401 | |||
| 402 | /* PCMCIA function control registers */ | ||
| 403 | char pcmciafcr[256]; /* 0x600-6ff, rev6 */ | ||
| 404 | u16 PAD[55]; | ||
| 405 | |||
| 406 | /* PCMCIA backplane access */ | ||
| 407 | u16 backplanecsr; /* 0x76E, rev6 */ | ||
| 408 | u16 backplaneaddr0; /* rev6 */ | ||
| 409 | u16 backplaneaddr1; /* rev6 */ | ||
| 410 | u16 backplaneaddr2; /* rev6 */ | ||
| 411 | u16 backplaneaddr3; /* rev6 */ | ||
| 412 | u16 backplanedata0; /* rev6 */ | ||
| 413 | u16 backplanedata1; /* rev6 */ | ||
| 414 | u16 backplanedata2; /* rev6 */ | ||
| 415 | u16 backplanedata3; /* rev6 */ | ||
| 416 | u16 PAD[31]; | ||
| 417 | |||
| 418 | /* sprom "size" & "blank" info */ | ||
| 419 | u16 spromstatus; /* 0x7BE, rev2 */ | ||
| 420 | u32 PAD[464]; | ||
| 421 | |||
| 422 | u16 PAD[0x80]; | ||
| 423 | }; | ||
| 424 | |||
| 425 | #ifdef DEBUG | 340 | #ifdef DEBUG |
| 426 | /* Device console log buffer state */ | 341 | /* Device console log buffer state */ |
| 427 | struct brcmf_console { | 342 | struct brcmf_console { |
| @@ -588,12 +503,14 @@ struct brcmf_sdio { | |||
| 588 | 503 | ||
| 589 | bool txoff; /* Transmit flow-controlled */ | 504 | bool txoff; /* Transmit flow-controlled */ |
| 590 | struct brcmf_sdio_count sdcnt; | 505 | struct brcmf_sdio_count sdcnt; |
| 506 | bool sr_enabled; /* SaveRestore enabled */ | ||
| 507 | bool sleeping; /* SDIO bus sleeping */ | ||
| 591 | }; | 508 | }; |
| 592 | 509 | ||
| 593 | /* clkstate */ | 510 | /* clkstate */ |
| 594 | #define CLK_NONE 0 | 511 | #define CLK_NONE 0 |
| 595 | #define CLK_SDONLY 1 | 512 | #define CLK_SDONLY 1 |
| 596 | #define CLK_PENDING 2 /* Not used yet */ | 513 | #define CLK_PENDING 2 |
| 597 | #define CLK_AVAIL 3 | 514 | #define CLK_AVAIL 3 |
| 598 | 515 | ||
| 599 | #ifdef DEBUG | 516 | #ifdef DEBUG |
| @@ -601,7 +518,7 @@ static int qcount[NUMPRIO]; | |||
| 601 | static int tx_packets[NUMPRIO]; | 518 | static int tx_packets[NUMPRIO]; |
| 602 | #endif /* DEBUG */ | 519 | #endif /* DEBUG */ |
| 603 | 520 | ||
| 604 | #define SDIO_DRIVE_STRENGTH 6 /* in milliamps */ | 521 | #define DEFAULT_SDIO_DRIVE_STRENGTH 6 /* in milliamps */ |
| 605 | 522 | ||
| 606 | #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL) | 523 | #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL) |
| 607 | 524 | ||
| @@ -665,6 +582,62 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) | |||
| 665 | return ret; | 582 | return ret; |
| 666 | } | 583 | } |
| 667 | 584 | ||
| 585 | static int | ||
| 586 | brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) | ||
| 587 | { | ||
| 588 | u8 wr_val = 0, rd_val, cmp_val, bmask; | ||
| 589 | int err = 0; | ||
| 590 | int try_cnt = 0; | ||
| 591 | |||
| 592 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 593 | |||
| 594 | wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); | ||
| 595 | /* 1st KSO write goes to AOS wake up core if device is asleep */ | ||
| 596 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, | ||
| 597 | wr_val, &err); | ||
| 598 | if (err) { | ||
| 599 | brcmf_err("SDIO_AOS KSO write error: %d\n", err); | ||
| 600 | return err; | ||
| 601 | } | ||
| 602 | |||
| 603 | if (on) { | ||
| 604 | /* device WAKEUP through KSO: | ||
| 605 | * write bit 0 & read back until | ||
| 606 | * both bits 0 (kso bit) & 1 (dev on status) are set | ||
| 607 | */ | ||
| 608 | cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | | ||
| 609 | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK; | ||
| 610 | bmask = cmp_val; | ||
| 611 | usleep_range(2000, 3000); | ||
| 612 | } else { | ||
| 613 | /* Put device to sleep, turn off KSO */ | ||
| 614 | cmp_val = 0; | ||
| 615 | /* only check for bit0, bit1(dev on status) may not | ||
| 616 | * get cleared right away | ||
| 617 | */ | ||
| 618 | bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK; | ||
| 619 | } | ||
| 620 | |||
| 621 | do { | ||
| 622 | /* reliable KSO bit set/clr: | ||
| 623 | * the sdiod sleep write access is synced to PMU 32khz clk | ||
| 624 | * just one write attempt may fail, | ||
| 625 | * read it back until it matches written value | ||
| 626 | */ | ||
| 627 | rd_val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, | ||
| 628 | &err); | ||
| 629 | if (((rd_val & bmask) == cmp_val) && !err) | ||
| 630 | break; | ||
| 631 | brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n", | ||
| 632 | try_cnt, MAX_KSO_ATTEMPTS, err); | ||
| 633 | udelay(KSO_WAIT_US); | ||
| 634 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, | ||
| 635 | wr_val, &err); | ||
| 636 | } while (try_cnt++ < MAX_KSO_ATTEMPTS); | ||
| 637 | |||
| 638 | return err; | ||
| 639 | } | ||
| 640 | |||
| 668 | #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) | 641 | #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) |
| 669 | 642 | ||
| 670 | #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) | 643 | #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) |
| @@ -680,6 +653,11 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) | |||
| 680 | 653 | ||
| 681 | clkctl = 0; | 654 | clkctl = 0; |
| 682 | 655 | ||
| 656 | if (bus->sr_enabled) { | ||
| 657 | bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY); | ||
| 658 | return 0; | ||
| 659 | } | ||
| 660 | |||
| 683 | if (on) { | 661 | if (on) { |
| 684 | /* Request HT Avail */ | 662 | /* Request HT Avail */ |
| 685 | clkreq = | 663 | clkreq = |
| @@ -856,6 +834,63 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) | |||
| 856 | return 0; | 834 | return 0; |
| 857 | } | 835 | } |
| 858 | 836 | ||
| 837 | static int | ||
| 838 | brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) | ||
| 839 | { | ||
| 840 | int err = 0; | ||
| 841 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 842 | brcmf_dbg(SDIO, "request %s currently %s\n", | ||
| 843 | (sleep ? "SLEEP" : "WAKE"), | ||
| 844 | (bus->sleeping ? "SLEEP" : "WAKE")); | ||
| 845 | |||
| 846 | /* If SR is enabled control bus state with KSO */ | ||
| 847 | if (bus->sr_enabled) { | ||
| 848 | /* Done if we're already in the requested state */ | ||
| 849 | if (sleep == bus->sleeping) | ||
| 850 | goto end; | ||
| 851 | |||
| 852 | /* Going to sleep */ | ||
| 853 | if (sleep) { | ||
| 854 | /* Don't sleep if something is pending */ | ||
| 855 | if (atomic_read(&bus->intstatus) || | ||
| 856 | atomic_read(&bus->ipend) > 0 || | ||
| 857 | (!atomic_read(&bus->fcstate) && | ||
| 858 | brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && | ||
| 859 | data_ok(bus))) | ||
| 860 | return -EBUSY; | ||
| 861 | err = brcmf_sdbrcm_kso_control(bus, false); | ||
| 862 | /* disable watchdog */ | ||
| 863 | if (!err) | ||
| 864 | brcmf_sdbrcm_wd_timer(bus, 0); | ||
| 865 | } else { | ||
| 866 | bus->idlecount = 0; | ||
| 867 | err = brcmf_sdbrcm_kso_control(bus, true); | ||
| 868 | } | ||
| 869 | if (!err) { | ||
| 870 | /* Change state */ | ||
| 871 | bus->sleeping = sleep; | ||
| 872 | brcmf_dbg(SDIO, "new state %s\n", | ||
| 873 | (sleep ? "SLEEP" : "WAKE")); | ||
| 874 | } else { | ||
| 875 | brcmf_err("error while changing bus sleep state %d\n", | ||
| 876 | err); | ||
| 877 | return err; | ||
| 878 | } | ||
| 879 | } | ||
| 880 | |||
| 881 | end: | ||
| 882 | /* control clocks */ | ||
| 883 | if (sleep) { | ||
| 884 | if (!bus->sr_enabled) | ||
| 885 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, pendok); | ||
| 886 | } else { | ||
| 887 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, pendok); | ||
| 888 | } | ||
| 889 | |||
| 890 | return err; | ||
| 891 | |||
| 892 | } | ||
| 893 | |||
| 859 | static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) | 894 | static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) |
| 860 | { | 895 | { |
| 861 | u32 intstatus = 0; | 896 | u32 intstatus = 0; |
| @@ -1960,7 +1995,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
| 1960 | sdio_claim_host(bus->sdiodev->func[1]); | 1995 | sdio_claim_host(bus->sdiodev->func[1]); |
| 1961 | 1996 | ||
| 1962 | /* Enable clock for device interrupts */ | 1997 | /* Enable clock for device interrupts */ |
| 1963 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 1998 | brcmf_sdbrcm_bus_sleep(bus, false, false); |
| 1964 | 1999 | ||
| 1965 | /* Disable and clear interrupts at the chip level also */ | 2000 | /* Disable and clear interrupts at the chip level also */ |
| 1966 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); | 2001 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); |
| @@ -2012,23 +2047,19 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
| 2012 | bus->tx_seq = bus->rx_seq = 0; | 2047 | bus->tx_seq = bus->rx_seq = 0; |
| 2013 | } | 2048 | } |
| 2014 | 2049 | ||
| 2015 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | ||
| 2016 | static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) | 2050 | static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) |
| 2017 | { | 2051 | { |
| 2018 | unsigned long flags; | 2052 | unsigned long flags; |
| 2019 | 2053 | ||
| 2020 | spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); | 2054 | if (bus->sdiodev->oob_irq_requested) { |
| 2021 | if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { | 2055 | spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); |
| 2022 | enable_irq(bus->sdiodev->irq); | 2056 | if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { |
| 2023 | bus->sdiodev->irq_en = true; | 2057 | enable_irq(bus->sdiodev->pdata->oob_irq_nr); |
| 2058 | bus->sdiodev->irq_en = true; | ||
| 2059 | } | ||
| 2060 | spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); | ||
| 2024 | } | 2061 | } |
| 2025 | spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); | ||
| 2026 | } | ||
| 2027 | #else | ||
| 2028 | static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) | ||
| 2029 | { | ||
| 2030 | } | 2062 | } |
| 2031 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 2032 | 2063 | ||
| 2033 | static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) | 2064 | static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) |
| 2034 | { | 2065 | { |
| @@ -2096,7 +2127,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
| 2096 | sdio_claim_host(bus->sdiodev->func[1]); | 2127 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2097 | 2128 | ||
| 2098 | /* If waiting for HTAVAIL, check status */ | 2129 | /* If waiting for HTAVAIL, check status */ |
| 2099 | if (bus->clkstate == CLK_PENDING) { | 2130 | if (!bus->sr_enabled && bus->clkstate == CLK_PENDING) { |
| 2100 | u8 clkctl, devctl = 0; | 2131 | u8 clkctl, devctl = 0; |
| 2101 | 2132 | ||
| 2102 | #ifdef DEBUG | 2133 | #ifdef DEBUG |
| @@ -2142,7 +2173,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
| 2142 | } | 2173 | } |
| 2143 | 2174 | ||
| 2144 | /* Make sure backplane clock is on */ | 2175 | /* Make sure backplane clock is on */ |
| 2145 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); | 2176 | brcmf_sdbrcm_bus_sleep(bus, false, true); |
| 2146 | 2177 | ||
| 2147 | /* Pending interrupt indicates new device status */ | 2178 | /* Pending interrupt indicates new device status */ |
| 2148 | if (atomic_read(&bus->ipend) > 0) { | 2179 | if (atomic_read(&bus->ipend) > 0) { |
| @@ -2288,8 +2319,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
| 2288 | if ((bus->clkstate != CLK_PENDING) | 2319 | if ((bus->clkstate != CLK_PENDING) |
| 2289 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { | 2320 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { |
| 2290 | bus->activity = false; | 2321 | bus->activity = false; |
| 2322 | brcmf_dbg(SDIO, "idle state\n"); | ||
| 2291 | sdio_claim_host(bus->sdiodev->func[1]); | 2323 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2292 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 2324 | brcmf_sdbrcm_bus_sleep(bus, true, false); |
| 2293 | sdio_release_host(bus->sdiodev->func[1]); | 2325 | sdio_release_host(bus->sdiodev->func[1]); |
| 2294 | } | 2326 | } |
| 2295 | } | 2327 | } |
| @@ -2362,69 +2394,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
| 2362 | return ret; | 2394 | return ret; |
| 2363 | } | 2395 | } |
| 2364 | 2396 | ||
| 2365 | static int | ||
| 2366 | brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data, | ||
| 2367 | uint size) | ||
| 2368 | { | ||
| 2369 | int bcmerror = 0; | ||
| 2370 | u32 sdaddr; | ||
| 2371 | uint dsize; | ||
| 2372 | |||
| 2373 | /* Determine initial transfer parameters */ | ||
| 2374 | sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; | ||
| 2375 | if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) | ||
| 2376 | dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); | ||
| 2377 | else | ||
| 2378 | dsize = size; | ||
| 2379 | |||
| 2380 | sdio_claim_host(bus->sdiodev->func[1]); | ||
| 2381 | |||
| 2382 | /* Set the backplane window to include the start address */ | ||
| 2383 | bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address); | ||
| 2384 | if (bcmerror) { | ||
| 2385 | brcmf_err("window change failed\n"); | ||
| 2386 | goto xfer_done; | ||
| 2387 | } | ||
| 2388 | |||
| 2389 | /* Do the transfer(s) */ | ||
| 2390 | while (size) { | ||
| 2391 | brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", | ||
| 2392 | write ? "write" : "read", dsize, | ||
| 2393 | sdaddr, address & SBSDIO_SBWINDOW_MASK); | ||
| 2394 | bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write, | ||
| 2395 | sdaddr, data, dsize); | ||
| 2396 | if (bcmerror) { | ||
| 2397 | brcmf_err("membytes transfer failed\n"); | ||
| 2398 | break; | ||
| 2399 | } | ||
| 2400 | |||
| 2401 | /* Adjust for next transfer (if any) */ | ||
| 2402 | size -= dsize; | ||
| 2403 | if (size) { | ||
| 2404 | data += dsize; | ||
| 2405 | address += dsize; | ||
| 2406 | bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, | ||
| 2407 | address); | ||
| 2408 | if (bcmerror) { | ||
| 2409 | brcmf_err("window change failed\n"); | ||
| 2410 | break; | ||
| 2411 | } | ||
| 2412 | sdaddr = 0; | ||
| 2413 | dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); | ||
| 2414 | } | ||
| 2415 | } | ||
| 2416 | |||
| 2417 | xfer_done: | ||
| 2418 | /* Return the window to backplane enumeration space for core access */ | ||
| 2419 | if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad)) | ||
| 2420 | brcmf_err("FAILED to set window back to 0x%x\n", | ||
| 2421 | bus->sdiodev->sbwad); | ||
| 2422 | |||
| 2423 | sdio_release_host(bus->sdiodev->func[1]); | ||
| 2424 | |||
| 2425 | return bcmerror; | ||
| 2426 | } | ||
| 2427 | |||
| 2428 | #ifdef DEBUG | 2397 | #ifdef DEBUG |
| 2429 | #define CONSOLE_LINE_MAX 192 | 2398 | #define CONSOLE_LINE_MAX 192 |
| 2430 | 2399 | ||
| @@ -2441,8 +2410,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) | |||
| 2441 | 2410 | ||
| 2442 | /* Read console log struct */ | 2411 | /* Read console log struct */ |
| 2443 | addr = bus->console_addr + offsetof(struct rte_console, log_le); | 2412 | addr = bus->console_addr + offsetof(struct rte_console, log_le); |
| 2444 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le, | 2413 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le, |
| 2445 | sizeof(c->log_le)); | 2414 | sizeof(c->log_le)); |
| 2446 | if (rv < 0) | 2415 | if (rv < 0) |
| 2447 | return rv; | 2416 | return rv; |
| 2448 | 2417 | ||
| @@ -2467,7 +2436,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) | |||
| 2467 | 2436 | ||
| 2468 | /* Read the console buffer */ | 2437 | /* Read the console buffer */ |
| 2469 | addr = le32_to_cpu(c->log_le.buf); | 2438 | addr = le32_to_cpu(c->log_le.buf); |
| 2470 | rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize); | 2439 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize); |
| 2471 | if (rv < 0) | 2440 | if (rv < 0) |
| 2472 | return rv; | 2441 | return rv; |
| 2473 | 2442 | ||
| @@ -2592,7 +2561,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
| 2592 | 2561 | ||
| 2593 | /* Make sure backplane clock is on */ | 2562 | /* Make sure backplane clock is on */ |
| 2594 | sdio_claim_host(bus->sdiodev->func[1]); | 2563 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2595 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2564 | brcmf_sdbrcm_bus_sleep(bus, false, false); |
| 2596 | sdio_release_host(bus->sdiodev->func[1]); | 2565 | sdio_release_host(bus->sdiodev->func[1]); |
| 2597 | 2566 | ||
| 2598 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | 2567 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ |
| @@ -2650,6 +2619,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
| 2650 | 2619 | ||
| 2651 | bus->activity = false; | 2620 | bus->activity = false; |
| 2652 | sdio_claim_host(bus->sdiodev->func[1]); | 2621 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2622 | brcmf_dbg(INFO, "idle\n"); | ||
| 2653 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); | 2623 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); |
| 2654 | sdio_release_host(bus->sdiodev->func[1]); | 2624 | sdio_release_host(bus->sdiodev->func[1]); |
| 2655 | } else { | 2625 | } else { |
| @@ -2679,16 +2649,15 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
| 2679 | struct sdpcm_shared_le sh_le; | 2649 | struct sdpcm_shared_le sh_le; |
| 2680 | __le32 addr_le; | 2650 | __le32 addr_le; |
| 2681 | 2651 | ||
| 2682 | shaddr = bus->ramsize - 4; | 2652 | shaddr = bus->ci->rambase + bus->ramsize - 4; |
| 2683 | 2653 | ||
| 2684 | /* | 2654 | /* |
| 2685 | * Read last word in socram to determine | 2655 | * Read last word in socram to determine |
| 2686 | * address of sdpcm_shared structure | 2656 | * address of sdpcm_shared structure |
| 2687 | */ | 2657 | */ |
| 2688 | sdio_claim_host(bus->sdiodev->func[1]); | 2658 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2689 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2659 | brcmf_sdbrcm_bus_sleep(bus, false, false); |
| 2690 | rv = brcmf_sdbrcm_membytes(bus, false, shaddr, | 2660 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); |
| 2691 | (u8 *)&addr_le, 4); | ||
| 2692 | sdio_release_host(bus->sdiodev->func[1]); | 2661 | sdio_release_host(bus->sdiodev->func[1]); |
| 2693 | if (rv < 0) | 2662 | if (rv < 0) |
| 2694 | return rv; | 2663 | return rv; |
| @@ -2708,8 +2677,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
| 2708 | } | 2677 | } |
| 2709 | 2678 | ||
| 2710 | /* Read hndrte_shared structure */ | 2679 | /* Read hndrte_shared structure */ |
| 2711 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, | 2680 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, |
| 2712 | sizeof(struct sdpcm_shared_le)); | 2681 | sizeof(struct sdpcm_shared_le)); |
| 2713 | if (rv < 0) | 2682 | if (rv < 0) |
| 2714 | return rv; | 2683 | return rv; |
| 2715 | 2684 | ||
| @@ -2745,22 +2714,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, | |||
| 2745 | 2714 | ||
| 2746 | /* obtain console information from device memory */ | 2715 | /* obtain console information from device memory */ |
| 2747 | addr = sh->console_addr + offsetof(struct rte_console, log_le); | 2716 | addr = sh->console_addr + offsetof(struct rte_console, log_le); |
| 2748 | rv = brcmf_sdbrcm_membytes(bus, false, addr, | 2717 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, |
| 2749 | (u8 *)&sh_val, sizeof(u32)); | 2718 | (u8 *)&sh_val, sizeof(u32)); |
| 2750 | if (rv < 0) | 2719 | if (rv < 0) |
| 2751 | return rv; | 2720 | return rv; |
| 2752 | console_ptr = le32_to_cpu(sh_val); | 2721 | console_ptr = le32_to_cpu(sh_val); |
| 2753 | 2722 | ||
| 2754 | addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); | 2723 | addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); |
| 2755 | rv = brcmf_sdbrcm_membytes(bus, false, addr, | 2724 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, |
| 2756 | (u8 *)&sh_val, sizeof(u32)); | 2725 | (u8 *)&sh_val, sizeof(u32)); |
| 2757 | if (rv < 0) | 2726 | if (rv < 0) |
| 2758 | return rv; | 2727 | return rv; |
| 2759 | console_size = le32_to_cpu(sh_val); | 2728 | console_size = le32_to_cpu(sh_val); |
| 2760 | 2729 | ||
| 2761 | addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); | 2730 | addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); |
| 2762 | rv = brcmf_sdbrcm_membytes(bus, false, addr, | 2731 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, |
| 2763 | (u8 *)&sh_val, sizeof(u32)); | 2732 | (u8 *)&sh_val, sizeof(u32)); |
| 2764 | if (rv < 0) | 2733 | if (rv < 0) |
| 2765 | return rv; | 2734 | return rv; |
| 2766 | console_index = le32_to_cpu(sh_val); | 2735 | console_index = le32_to_cpu(sh_val); |
| @@ -2774,8 +2743,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, | |||
| 2774 | 2743 | ||
| 2775 | /* obtain the console data from device */ | 2744 | /* obtain the console data from device */ |
| 2776 | conbuf[console_size] = '\0'; | 2745 | conbuf[console_size] = '\0'; |
| 2777 | rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf, | 2746 | rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf, |
| 2778 | console_size); | 2747 | console_size); |
| 2779 | if (rv < 0) | 2748 | if (rv < 0) |
| 2780 | goto done; | 2749 | goto done; |
| 2781 | 2750 | ||
| @@ -2812,8 +2781,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, | |||
| 2812 | return 0; | 2781 | return 0; |
| 2813 | } | 2782 | } |
| 2814 | 2783 | ||
| 2815 | error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, | 2784 | error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr, |
| 2816 | sizeof(struct brcmf_trap_info)); | 2785 | sizeof(struct brcmf_trap_info)); |
| 2817 | if (error < 0) | 2786 | if (error < 0) |
| 2818 | return error; | 2787 | return error; |
| 2819 | 2788 | ||
| @@ -2856,14 +2825,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, | |||
| 2856 | 2825 | ||
| 2857 | sdio_claim_host(bus->sdiodev->func[1]); | 2826 | sdio_claim_host(bus->sdiodev->func[1]); |
| 2858 | if (sh->assert_file_addr != 0) { | 2827 | if (sh->assert_file_addr != 0) { |
| 2859 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, | 2828 | error = brcmf_sdio_ramrw(bus->sdiodev, false, |
| 2860 | (u8 *)file, 80); | 2829 | sh->assert_file_addr, (u8 *)file, 80); |
| 2861 | if (error < 0) | 2830 | if (error < 0) |
| 2862 | return error; | 2831 | return error; |
| 2863 | } | 2832 | } |
| 2864 | if (sh->assert_exp_addr != 0) { | 2833 | if (sh->assert_exp_addr != 0) { |
| 2865 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, | 2834 | error = brcmf_sdio_ramrw(bus->sdiodev, false, |
| 2866 | (u8 *)expr, 80); | 2835 | sh->assert_exp_addr, (u8 *)expr, 80); |
| 2867 | if (error < 0) | 2836 | if (error < 0) |
| 2868 | return error; | 2837 | return error; |
| 2869 | } | 2838 | } |
| @@ -3021,84 +2990,8 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
| 3021 | return rxlen ? (int)rxlen : -ETIMEDOUT; | 2990 | return rxlen ? (int)rxlen : -ETIMEDOUT; |
| 3022 | } | 2991 | } |
| 3023 | 2992 | ||
| 3024 | static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) | 2993 | static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) |
| 3025 | { | ||
| 3026 | int bcmerror = 0; | ||
| 3027 | u32 varaddr; | ||
| 3028 | u32 varsizew; | ||
| 3029 | __le32 varsizew_le; | ||
| 3030 | #ifdef DEBUG | ||
| 3031 | char *nvram_ularray; | ||
| 3032 | #endif /* DEBUG */ | ||
| 3033 | |||
| 3034 | /* Even if there are no vars are to be written, we still | ||
| 3035 | need to set the ramsize. */ | ||
| 3036 | varaddr = (bus->ramsize - 4) - bus->varsz; | ||
| 3037 | |||
| 3038 | if (bus->vars) { | ||
| 3039 | /* Write the vars list */ | ||
| 3040 | bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, | ||
| 3041 | bus->vars, bus->varsz); | ||
| 3042 | #ifdef DEBUG | ||
| 3043 | /* Verify NVRAM bytes */ | ||
| 3044 | brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", | ||
| 3045 | bus->varsz); | ||
| 3046 | nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC); | ||
| 3047 | if (!nvram_ularray) | ||
| 3048 | return -ENOMEM; | ||
| 3049 | |||
| 3050 | /* Upload image to verify downloaded contents. */ | ||
| 3051 | memset(nvram_ularray, 0xaa, bus->varsz); | ||
| 3052 | |||
| 3053 | /* Read the vars list to temp buffer for comparison */ | ||
| 3054 | bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr, | ||
| 3055 | nvram_ularray, bus->varsz); | ||
| 3056 | if (bcmerror) { | ||
| 3057 | brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", | ||
| 3058 | bcmerror, bus->varsz, varaddr); | ||
| 3059 | } | ||
| 3060 | /* Compare the org NVRAM with the one read from RAM */ | ||
| 3061 | if (memcmp(bus->vars, nvram_ularray, bus->varsz)) | ||
| 3062 | brcmf_err("Downloaded NVRAM image is corrupted\n"); | ||
| 3063 | else | ||
| 3064 | brcmf_err("Download/Upload/Compare of NVRAM ok\n"); | ||
| 3065 | |||
| 3066 | kfree(nvram_ularray); | ||
| 3067 | #endif /* DEBUG */ | ||
| 3068 | } | ||
| 3069 | |||
| 3070 | /* adjust to the user specified RAM */ | ||
| 3071 | brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize); | ||
| 3072 | brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n", | ||
| 3073 | varaddr, bus->varsz); | ||
| 3074 | |||
| 3075 | /* | ||
| 3076 | * Determine the length token: | ||
| 3077 | * Varsize, converted to words, in lower 16-bits, checksum | ||
| 3078 | * in upper 16-bits. | ||
| 3079 | */ | ||
| 3080 | if (bcmerror) { | ||
| 3081 | varsizew = 0; | ||
| 3082 | varsizew_le = cpu_to_le32(0); | ||
| 3083 | } else { | ||
| 3084 | varsizew = bus->varsz / 4; | ||
| 3085 | varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); | ||
| 3086 | varsizew_le = cpu_to_le32(varsizew); | ||
| 3087 | } | ||
| 3088 | |||
| 3089 | brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n", | ||
| 3090 | bus->varsz, varsizew); | ||
| 3091 | |||
| 3092 | /* Write the length token to the last word */ | ||
| 3093 | bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4), | ||
| 3094 | (u8 *)&varsizew_le, 4); | ||
| 3095 | |||
| 3096 | return bcmerror; | ||
| 3097 | } | ||
| 3098 | |||
| 3099 | static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) | ||
| 3100 | { | 2994 | { |
| 3101 | int bcmerror = 0; | ||
| 3102 | struct chip_info *ci = bus->ci; | 2995 | struct chip_info *ci = bus->ci; |
| 3103 | 2996 | ||
| 3104 | /* To enter download state, disable ARM and reset SOCRAM. | 2997 | /* To enter download state, disable ARM and reset SOCRAM. |
| @@ -3107,41 +3000,19 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) | |||
| 3107 | if (enter) { | 3000 | if (enter) { |
| 3108 | bus->alp_only = true; | 3001 | bus->alp_only = true; |
| 3109 | 3002 | ||
| 3110 | ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); | 3003 | brcmf_sdio_chip_enter_download(bus->sdiodev, ci); |
| 3111 | |||
| 3112 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM); | ||
| 3113 | |||
| 3114 | /* Clear the top bit of memory */ | ||
| 3115 | if (bus->ramsize) { | ||
| 3116 | u32 zeros = 0; | ||
| 3117 | brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4, | ||
| 3118 | (u8 *)&zeros, 4); | ||
| 3119 | } | ||
| 3120 | } else { | 3004 | } else { |
| 3121 | if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { | 3005 | if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars, |
| 3122 | brcmf_err("SOCRAM core is down after reset?\n"); | 3006 | bus->varsz)) |
| 3123 | bcmerror = -EBADE; | 3007 | return false; |
| 3124 | goto fail; | ||
| 3125 | } | ||
| 3126 | |||
| 3127 | bcmerror = brcmf_sdbrcm_write_vars(bus); | ||
| 3128 | if (bcmerror) { | ||
| 3129 | brcmf_err("no vars written to RAM\n"); | ||
| 3130 | bcmerror = 0; | ||
| 3131 | } | ||
| 3132 | |||
| 3133 | w_sdreg32(bus, 0xFFFFFFFF, | ||
| 3134 | offsetof(struct sdpcmd_regs, intstatus)); | ||
| 3135 | |||
| 3136 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); | ||
| 3137 | 3008 | ||
| 3138 | /* Allow HT Clock now that the ARM is running. */ | 3009 | /* Allow HT Clock now that the ARM is running. */ |
| 3139 | bus->alp_only = false; | 3010 | bus->alp_only = false; |
| 3140 | 3011 | ||
| 3141 | bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; | 3012 | bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; |
| 3142 | } | 3013 | } |
| 3143 | fail: | 3014 | |
| 3144 | return bcmerror; | 3015 | return true; |
| 3145 | } | 3016 | } |
| 3146 | 3017 | ||
| 3147 | static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus) | 3018 | static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus) |
| @@ -3156,10 +3027,11 @@ static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus) | |||
| 3156 | 3027 | ||
| 3157 | static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | 3028 | static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) |
| 3158 | { | 3029 | { |
| 3159 | int offset = 0; | 3030 | int offset; |
| 3160 | uint len; | 3031 | uint len; |
| 3161 | u8 *memblock = NULL, *memptr; | 3032 | u8 *memblock = NULL, *memptr; |
| 3162 | int ret; | 3033 | int ret; |
| 3034 | u8 idx; | ||
| 3163 | 3035 | ||
| 3164 | brcmf_dbg(INFO, "Enter\n"); | 3036 | brcmf_dbg(INFO, "Enter\n"); |
| 3165 | 3037 | ||
| @@ -3180,10 +3052,15 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | |||
| 3180 | memptr += (BRCMF_SDALIGN - | 3052 | memptr += (BRCMF_SDALIGN - |
| 3181 | ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); | 3053 | ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); |
| 3182 | 3054 | ||
| 3055 | offset = bus->ci->rambase; | ||
| 3056 | |||
| 3183 | /* Download image */ | 3057 | /* Download image */ |
| 3184 | while ((len = | 3058 | len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); |
| 3185 | brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { | 3059 | idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4); |
| 3186 | ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len); | 3060 | if (BRCMF_MAX_CORENUM != idx) |
| 3061 | memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec)); | ||
| 3062 | while (len) { | ||
| 3063 | ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len); | ||
| 3187 | if (ret) { | 3064 | if (ret) { |
| 3188 | brcmf_err("error %d on writing %d membytes at 0x%08x\n", | 3065 | brcmf_err("error %d on writing %d membytes at 0x%08x\n", |
| 3189 | ret, MEMBLOCK, offset); | 3066 | ret, MEMBLOCK, offset); |
| @@ -3191,6 +3068,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | |||
| 3191 | } | 3068 | } |
| 3192 | 3069 | ||
| 3193 | offset += MEMBLOCK; | 3070 | offset += MEMBLOCK; |
| 3071 | len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); | ||
| 3194 | } | 3072 | } |
| 3195 | 3073 | ||
| 3196 | err: | 3074 | err: |
| @@ -3298,7 +3176,7 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
| 3298 | int bcmerror = -1; | 3176 | int bcmerror = -1; |
| 3299 | 3177 | ||
| 3300 | /* Keep arm in reset */ | 3178 | /* Keep arm in reset */ |
| 3301 | if (brcmf_sdbrcm_download_state(bus, true)) { | 3179 | if (!brcmf_sdbrcm_download_state(bus, true)) { |
| 3302 | brcmf_err("error placing ARM core in reset\n"); | 3180 | brcmf_err("error placing ARM core in reset\n"); |
| 3303 | goto err; | 3181 | goto err; |
| 3304 | } | 3182 | } |
| @@ -3314,7 +3192,7 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
| 3314 | } | 3192 | } |
| 3315 | 3193 | ||
| 3316 | /* Take arm out of reset */ | 3194 | /* Take arm out of reset */ |
| 3317 | if (brcmf_sdbrcm_download_state(bus, false)) { | 3195 | if (!brcmf_sdbrcm_download_state(bus, false)) { |
| 3318 | brcmf_err("error getting out of ARM core reset\n"); | 3196 | brcmf_err("error getting out of ARM core reset\n"); |
| 3319 | goto err; | 3197 | goto err; |
| 3320 | } | 3198 | } |
| @@ -3325,6 +3203,103 @@ err: | |||
| 3325 | return bcmerror; | 3203 | return bcmerror; |
| 3326 | } | 3204 | } |
| 3327 | 3205 | ||
| 3206 | static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) | ||
| 3207 | { | ||
| 3208 | u32 addr, reg; | ||
| 3209 | |||
| 3210 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 3211 | |||
| 3212 | /* old chips with PMU version less than 17 don't support save restore */ | ||
| 3213 | if (bus->ci->pmurev < 17) | ||
| 3214 | return false; | ||
| 3215 | |||
| 3216 | /* read PMU chipcontrol register 3*/ | ||
| 3217 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); | ||
| 3218 | brcmf_sdio_regwl(bus->sdiodev, addr, 3, NULL); | ||
| 3219 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); | ||
| 3220 | reg = brcmf_sdio_regrl(bus->sdiodev, addr, NULL); | ||
| 3221 | |||
| 3222 | return (bool)reg; | ||
| 3223 | } | ||
| 3224 | |||
| 3225 | static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) | ||
| 3226 | { | ||
| 3227 | int err = 0; | ||
| 3228 | u8 val; | ||
| 3229 | |||
| 3230 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 3231 | |||
| 3232 | val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, | ||
| 3233 | &err); | ||
| 3234 | if (err) { | ||
| 3235 | brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); | ||
| 3236 | return; | ||
| 3237 | } | ||
| 3238 | |||
| 3239 | val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; | ||
| 3240 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, | ||
| 3241 | val, &err); | ||
| 3242 | if (err) { | ||
| 3243 | brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); | ||
| 3244 | return; | ||
| 3245 | } | ||
| 3246 | |||
| 3247 | /* Add CMD14 Support */ | ||
| 3248 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, | ||
| 3249 | (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | | ||
| 3250 | SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), | ||
| 3251 | &err); | ||
| 3252 | if (err) { | ||
| 3253 | brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); | ||
| 3254 | return; | ||
| 3255 | } | ||
| 3256 | |||
| 3257 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, | ||
| 3258 | SBSDIO_FORCE_HT, &err); | ||
| 3259 | if (err) { | ||
| 3260 | brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); | ||
| 3261 | return; | ||
| 3262 | } | ||
| 3263 | |||
| 3264 | /* set flag */ | ||
| 3265 | bus->sr_enabled = true; | ||
| 3266 | brcmf_dbg(INFO, "SR enabled\n"); | ||
| 3267 | } | ||
| 3268 | |||
| 3269 | /* enable KSO bit */ | ||
| 3270 | static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) | ||
| 3271 | { | ||
| 3272 | u8 val; | ||
| 3273 | int err = 0; | ||
| 3274 | |||
| 3275 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 3276 | |||
| 3277 | /* KSO bit added in SDIO core rev 12 */ | ||
| 3278 | if (bus->ci->c_inf[1].rev < 12) | ||
| 3279 | return 0; | ||
| 3280 | |||
| 3281 | val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, | ||
| 3282 | &err); | ||
| 3283 | if (err) { | ||
| 3284 | brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); | ||
| 3285 | return err; | ||
| 3286 | } | ||
| 3287 | |||
| 3288 | if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { | ||
| 3289 | val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << | ||
| 3290 | SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); | ||
| 3291 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, | ||
| 3292 | val, &err); | ||
| 3293 | if (err) { | ||
| 3294 | brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); | ||
| 3295 | return err; | ||
| 3296 | } | ||
| 3297 | } | ||
| 3298 | |||
| 3299 | return 0; | ||
| 3300 | } | ||
| 3301 | |||
| 3302 | |||
| 3328 | static bool | 3303 | static bool |
| 3329 | brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | 3304 | brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) |
| 3330 | { | 3305 | { |
| @@ -3423,8 +3398,13 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
| 3423 | ret = -ENODEV; | 3398 | ret = -ENODEV; |
| 3424 | } | 3399 | } |
| 3425 | 3400 | ||
| 3426 | /* Restore previous clock setting */ | 3401 | if (brcmf_sdbrcm_sr_capable(bus)) { |
| 3427 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); | 3402 | brcmf_sdbrcm_sr_init(bus); |
| 3403 | } else { | ||
| 3404 | /* Restore previous clock setting */ | ||
| 3405 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, | ||
| 3406 | saveclk, &err); | ||
| 3407 | } | ||
| 3428 | 3408 | ||
| 3429 | if (ret == 0) { | 3409 | if (ret == 0) { |
| 3430 | ret = brcmf_sdio_intr_register(bus->sdiodev); | 3410 | ret = brcmf_sdio_intr_register(bus->sdiodev); |
| @@ -3485,7 +3465,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
| 3485 | brcmf_dbg(TIMER, "Enter\n"); | 3465 | brcmf_dbg(TIMER, "Enter\n"); |
| 3486 | 3466 | ||
| 3487 | /* Poll period: check device if appropriate. */ | 3467 | /* Poll period: check device if appropriate. */ |
| 3488 | if (bus->poll && (++bus->polltick >= bus->pollrate)) { | 3468 | if (!bus->sr_enabled && |
| 3469 | bus->poll && (++bus->polltick >= bus->pollrate)) { | ||
| 3489 | u32 intstatus = 0; | 3470 | u32 intstatus = 0; |
| 3490 | 3471 | ||
| 3491 | /* Reset poll tick */ | 3472 | /* Reset poll tick */ |
| @@ -3536,7 +3517,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
| 3536 | bus->console.count -= bus->console_interval; | 3517 | bus->console.count -= bus->console_interval; |
| 3537 | sdio_claim_host(bus->sdiodev->func[1]); | 3518 | sdio_claim_host(bus->sdiodev->func[1]); |
| 3538 | /* Make sure backplane clock is on */ | 3519 | /* Make sure backplane clock is on */ |
| 3539 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3520 | brcmf_sdbrcm_bus_sleep(bus, false, false); |
| 3540 | if (brcmf_sdbrcm_readconsole(bus) < 0) | 3521 | if (brcmf_sdbrcm_readconsole(bus) < 0) |
| 3541 | /* stop on error */ | 3522 | /* stop on error */ |
| 3542 | bus->console_interval = 0; | 3523 | bus->console_interval = 0; |
| @@ -3553,8 +3534,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
| 3553 | bus->activity = false; | 3534 | bus->activity = false; |
| 3554 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3535 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
| 3555 | } else { | 3536 | } else { |
| 3537 | brcmf_dbg(SDIO, "idle\n"); | ||
| 3556 | sdio_claim_host(bus->sdiodev->func[1]); | 3538 | sdio_claim_host(bus->sdiodev->func[1]); |
| 3557 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3539 | brcmf_sdbrcm_bus_sleep(bus, true, false); |
| 3558 | sdio_release_host(bus->sdiodev->func[1]); | 3540 | sdio_release_host(bus->sdiodev->func[1]); |
| 3559 | } | 3541 | } |
| 3560 | } | 3542 | } |
| @@ -3565,6 +3547,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
| 3565 | 3547 | ||
| 3566 | static bool brcmf_sdbrcm_chipmatch(u16 chipid) | 3548 | static bool brcmf_sdbrcm_chipmatch(u16 chipid) |
| 3567 | { | 3549 | { |
| 3550 | if (chipid == BCM43143_CHIP_ID) | ||
| 3551 | return true; | ||
| 3568 | if (chipid == BCM43241_CHIP_ID) | 3552 | if (chipid == BCM43241_CHIP_ID) |
| 3569 | return true; | 3553 | return true; |
| 3570 | if (chipid == BCM4329_CHIP_ID) | 3554 | if (chipid == BCM4329_CHIP_ID) |
| @@ -3573,6 +3557,8 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid) | |||
| 3573 | return true; | 3557 | return true; |
| 3574 | if (chipid == BCM4334_CHIP_ID) | 3558 | if (chipid == BCM4334_CHIP_ID) |
| 3575 | return true; | 3559 | return true; |
| 3560 | if (chipid == BCM4335_CHIP_ID) | ||
| 3561 | return true; | ||
| 3576 | return false; | 3562 | return false; |
| 3577 | } | 3563 | } |
| 3578 | 3564 | ||
| @@ -3650,7 +3636,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
| 3650 | int err = 0; | 3636 | int err = 0; |
| 3651 | int reg_addr; | 3637 | int reg_addr; |
| 3652 | u32 reg_val; | 3638 | u32 reg_val; |
| 3653 | u8 idx; | 3639 | u32 drivestrength; |
| 3654 | 3640 | ||
| 3655 | bus->alp_only = true; | 3641 | bus->alp_only = true; |
| 3656 | 3642 | ||
| @@ -3686,8 +3672,16 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
| 3686 | goto fail; | 3672 | goto fail; |
| 3687 | } | 3673 | } |
| 3688 | 3674 | ||
| 3689 | brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, | 3675 | if (brcmf_sdbrcm_kso_init(bus)) { |
| 3690 | SDIO_DRIVE_STRENGTH); | 3676 | brcmf_err("error enabling KSO\n"); |
| 3677 | goto fail; | ||
| 3678 | } | ||
| 3679 | |||
| 3680 | if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) | ||
| 3681 | drivestrength = bus->sdiodev->pdata->drive_strength; | ||
| 3682 | else | ||
| 3683 | drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; | ||
| 3684 | brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); | ||
| 3691 | 3685 | ||
| 3692 | /* Get info on the SOCRAM cores... */ | 3686 | /* Get info on the SOCRAM cores... */ |
| 3693 | bus->ramsize = bus->ci->ramsize; | 3687 | bus->ramsize = bus->ci->ramsize; |
| @@ -3696,12 +3690,37 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
| 3696 | goto fail; | 3690 | goto fail; |
| 3697 | } | 3691 | } |
| 3698 | 3692 | ||
| 3699 | /* Set core control so an SDIO reset does a backplane reset */ | 3693 | /* Set card control so an SDIO card reset does a WLAN backplane reset */ |
| 3700 | idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | 3694 | reg_val = brcmf_sdio_regrb(bus->sdiodev, |
| 3701 | reg_addr = bus->ci->c_inf[idx].base + | 3695 | SDIO_CCCR_BRCM_CARDCTRL, &err); |
| 3702 | offsetof(struct sdpcmd_regs, corecontrol); | 3696 | if (err) |
| 3703 | reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); | 3697 | goto fail; |
| 3704 | brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); | 3698 | |
| 3699 | reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; | ||
| 3700 | |||
| 3701 | brcmf_sdio_regwb(bus->sdiodev, | ||
| 3702 | SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); | ||
| 3703 | if (err) | ||
| 3704 | goto fail; | ||
| 3705 | |||
| 3706 | /* set PMUControl so a backplane reset does PMU state reload */ | ||
| 3707 | reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base, | ||
| 3708 | pmucontrol); | ||
| 3709 | reg_val = brcmf_sdio_regrl(bus->sdiodev, | ||
| 3710 | reg_addr, | ||
| 3711 | &err); | ||
| 3712 | if (err) | ||
| 3713 | goto fail; | ||
| 3714 | |||
| 3715 | reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); | ||
| 3716 | |||
| 3717 | brcmf_sdio_regwl(bus->sdiodev, | ||
| 3718 | reg_addr, | ||
| 3719 | reg_val, | ||
| 3720 | &err); | ||
| 3721 | if (err) | ||
| 3722 | goto fail; | ||
| 3723 | |||
| 3705 | 3724 | ||
| 3706 | sdio_release_host(bus->sdiodev->func[1]); | 3725 | sdio_release_host(bus->sdiodev->func[1]); |
| 3707 | 3726 | ||
| @@ -3755,6 +3774,10 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
| 3755 | bus->use_rxchain = false; | 3774 | bus->use_rxchain = false; |
| 3756 | bus->sd_rxchain = false; | 3775 | bus->sd_rxchain = false; |
| 3757 | 3776 | ||
| 3777 | /* SR state */ | ||
| 3778 | bus->sleeping = false; | ||
| 3779 | bus->sr_enabled = false; | ||
| 3780 | |||
| 3758 | return true; | 3781 | return true; |
| 3759 | } | 3782 | } |
| 3760 | 3783 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index b3c608ee37cf..5352dc1fdf3c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
| 22 | #include <linux/etherdevice.h> | 22 | #include <linux/etherdevice.h> |
| 23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
| 24 | #include <linux/jiffies.h> | ||
| 24 | #include <uapi/linux/nl80211.h> | 25 | #include <uapi/linux/nl80211.h> |
| 25 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
| 26 | 27 | ||
| @@ -31,8 +32,11 @@ | |||
| 31 | #include "dhd_dbg.h" | 32 | #include "dhd_dbg.h" |
| 32 | #include "dhd_bus.h" | 33 | #include "dhd_bus.h" |
| 33 | #include "fwil.h" | 34 | #include "fwil.h" |
| 35 | #include "fwil_types.h" | ||
| 34 | #include "fweh.h" | 36 | #include "fweh.h" |
| 35 | #include "fwsignal.h" | 37 | #include "fwsignal.h" |
| 38 | #include "p2p.h" | ||
| 39 | #include "wl_cfg80211.h" | ||
| 36 | 40 | ||
| 37 | /** | 41 | /** |
| 38 | * DOC: Firmware Signalling | 42 | * DOC: Firmware Signalling |
| @@ -144,6 +148,9 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) | |||
| 144 | #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 | 148 | #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 |
| 145 | #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 | 149 | #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 |
| 146 | 150 | ||
| 151 | #define BRCMF_FWS_RET_OK_NOSCHEDULE 0 | ||
| 152 | #define BRCMF_FWS_RET_OK_SCHEDULE 1 | ||
| 153 | |||
| 147 | /** | 154 | /** |
| 148 | * enum brcmf_fws_skb_state - indicates processing state of skb. | 155 | * enum brcmf_fws_skb_state - indicates processing state of skb. |
| 149 | * | 156 | * |
| @@ -265,6 +272,9 @@ struct brcmf_skbuff_cb { | |||
| 265 | brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ | 272 | brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ |
| 266 | BRCMF_FWS_TXSTAT_ ## field ## _SHIFT) | 273 | BRCMF_FWS_TXSTAT_ ## field ## _SHIFT) |
| 267 | 274 | ||
| 275 | /* How long to defer borrowing in jiffies */ | ||
| 276 | #define BRCMF_FWS_BORROW_DEFER_PERIOD (HZ / 10) | ||
| 277 | |||
| 268 | /** | 278 | /** |
| 269 | * enum brcmf_fws_fifo - fifo indices used by dongle firmware. | 279 | * enum brcmf_fws_fifo - fifo indices used by dongle firmware. |
| 270 | * | 280 | * |
| @@ -419,9 +429,11 @@ struct brcmf_fws_info { | |||
| 419 | struct work_struct fws_dequeue_work; | 429 | struct work_struct fws_dequeue_work; |
| 420 | u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT]; | 430 | u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT]; |
| 421 | int fifo_credit[BRCMF_FWS_FIFO_COUNT]; | 431 | int fifo_credit[BRCMF_FWS_FIFO_COUNT]; |
| 432 | int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1]; | ||
| 422 | int deq_node_pos[BRCMF_FWS_FIFO_COUNT]; | 433 | int deq_node_pos[BRCMF_FWS_FIFO_COUNT]; |
| 423 | u32 fifo_credit_map; | 434 | u32 fifo_credit_map; |
| 424 | u32 fifo_delay_map; | 435 | u32 fifo_delay_map; |
| 436 | unsigned long borrow_defer_timestamp; | ||
| 425 | }; | 437 | }; |
| 426 | 438 | ||
| 427 | /* | 439 | /* |
| @@ -678,28 +690,28 @@ brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea) | |||
| 678 | } | 690 | } |
| 679 | 691 | ||
| 680 | static struct brcmf_fws_mac_descriptor* | 692 | static struct brcmf_fws_mac_descriptor* |
| 681 | brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, int ifidx, u8 *da) | 693 | brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, struct brcmf_if *ifp, |
| 694 | u8 *da) | ||
| 682 | { | 695 | { |
| 683 | struct brcmf_fws_mac_descriptor *entry = &fws->desc.other; | 696 | struct brcmf_fws_mac_descriptor *entry = &fws->desc.other; |
| 684 | struct brcmf_if *ifp; | ||
| 685 | bool multicast; | 697 | bool multicast; |
| 698 | enum nl80211_iftype iftype; | ||
| 686 | 699 | ||
| 687 | brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx); | 700 | brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx); |
| 688 | 701 | ||
| 689 | multicast = is_multicast_ether_addr(da); | 702 | multicast = is_multicast_ether_addr(da); |
| 690 | ifp = fws->drvr->iflist[ifidx ? ifidx + 1 : 0]; | 703 | iftype = brcmf_cfg80211_get_iftype(ifp); |
| 691 | if (WARN_ON(!ifp)) | ||
| 692 | goto done; | ||
| 693 | 704 | ||
| 694 | /* Multicast destination and P2P clients get the interface entry. | 705 | /* Multicast destination and P2P clients get the interface entry. |
| 695 | * STA gets the interface entry if there is no exact match. For | 706 | * STA gets the interface entry if there is no exact match. For |
| 696 | * example, TDLS destinations have their own entry. | 707 | * example, TDLS destinations have their own entry. |
| 697 | */ | 708 | */ |
| 698 | entry = NULL; | 709 | entry = NULL; |
| 699 | if (multicast && ifp->fws_desc) | 710 | if ((multicast || iftype == NL80211_IFTYPE_STATION || |
| 711 | iftype == NL80211_IFTYPE_P2P_CLIENT) && ifp->fws_desc) | ||
| 700 | entry = ifp->fws_desc; | 712 | entry = ifp->fws_desc; |
| 701 | 713 | ||
| 702 | if (entry != NULL && multicast) | 714 | if (entry != NULL && iftype != NL80211_IFTYPE_STATION) |
| 703 | goto done; | 715 | goto done; |
| 704 | 716 | ||
| 705 | entry = brcmf_fws_mac_descriptor_lookup(fws, da); | 717 | entry = brcmf_fws_mac_descriptor_lookup(fws, da); |
| @@ -711,26 +723,29 @@ done: | |||
| 711 | return entry; | 723 | return entry; |
| 712 | } | 724 | } |
| 713 | 725 | ||
| 714 | static bool brcmf_fws_mac_desc_ready(struct brcmf_fws_mac_descriptor *entry, | 726 | static bool brcmf_fws_mac_desc_closed(struct brcmf_fws_info *fws, |
| 715 | int fifo) | 727 | struct brcmf_fws_mac_descriptor *entry, |
| 728 | int fifo) | ||
| 716 | { | 729 | { |
| 717 | bool ready; | 730 | struct brcmf_fws_mac_descriptor *if_entry; |
| 731 | bool closed; | ||
| 718 | 732 | ||
| 719 | /* | 733 | /* for unique destination entries the related interface |
| 720 | * destination entry is ready when firmware says it is OPEN | 734 | * may be closed. |
| 721 | * and there are no packets enqueued for it. | ||
| 722 | */ | 735 | */ |
| 723 | ready = entry->state == BRCMF_FWS_STATE_OPEN && | 736 | if (entry->mac_handle) { |
| 724 | !entry->suppressed && | 737 | if_entry = &fws->desc.iface[entry->interface_id]; |
| 725 | brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0; | 738 | if (if_entry->state == BRCMF_FWS_STATE_CLOSE) |
| 726 | 739 | return true; | |
| 727 | /* | 740 | } |
| 728 | * Or when the destination entry is CLOSED, but firmware has | 741 | /* an entry is closed when the state is closed and |
| 729 | * specifically requested packets for this entry. | 742 | * the firmware did not request anything. |
| 730 | */ | 743 | */ |
| 731 | ready = ready || (entry->state == BRCMF_FWS_STATE_CLOSE && | 744 | closed = entry->state == BRCMF_FWS_STATE_CLOSE && |
| 732 | (entry->requested_credit + entry->requested_packet)); | 745 | !entry->requested_credit && !entry->requested_packet; |
| 733 | return ready; | 746 | |
| 747 | /* Or firmware does not allow traffic for given fifo */ | ||
| 748 | return closed || !(entry->ac_bitmap & BIT(fifo)); | ||
| 734 | } | 749 | } |
| 735 | 750 | ||
| 736 | static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_info *fws, | 751 | static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_info *fws, |
| @@ -825,11 +840,12 @@ brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq, | |||
| 825 | { | 840 | { |
| 826 | struct brcmf_if *ifp = fws->drvr->iflist[if_id]; | 841 | struct brcmf_if *ifp = fws->drvr->iflist[if_id]; |
| 827 | 842 | ||
| 828 | brcmf_dbg(TRACE, | ||
| 829 | "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx); | ||
| 830 | if (WARN_ON(!ifp)) | 843 | if (WARN_ON(!ifp)) |
| 831 | return; | 844 | return; |
| 832 | 845 | ||
| 846 | brcmf_dbg(TRACE, | ||
| 847 | "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx); | ||
| 848 | |||
| 833 | if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) && | 849 | if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) && |
| 834 | pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER) | 850 | pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER) |
| 835 | brcmf_txflowblock_if(ifp, | 851 | brcmf_txflowblock_if(ifp, |
| @@ -861,9 +877,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | |||
| 861 | entry = &fws->desc.nodes[mac_handle & 0x1F]; | 877 | entry = &fws->desc.nodes[mac_handle & 0x1F]; |
| 862 | if (type == BRCMF_FWS_TYPE_MACDESC_DEL) { | 878 | if (type == BRCMF_FWS_TYPE_MACDESC_DEL) { |
| 863 | brcmf_dbg(TRACE, "deleting mac %pM idx %d\n", addr, ifidx); | 879 | brcmf_dbg(TRACE, "deleting mac %pM idx %d\n", addr, ifidx); |
| 864 | if (entry->occupied) | 880 | if (entry->occupied) { |
| 881 | brcmf_fws_mac_desc_cleanup(fws, entry, -1); | ||
| 865 | brcmf_fws_clear_mac_descriptor(entry); | 882 | brcmf_fws_clear_mac_descriptor(entry); |
| 866 | else | 883 | } else |
| 867 | fws->stats.mac_update_failed++; | 884 | fws->stats.mac_update_failed++; |
| 868 | return 0; | 885 | return 0; |
| 869 | } | 886 | } |
| @@ -914,12 +931,13 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws, | |||
| 914 | entry->requested_credit = 0; | 931 | entry->requested_credit = 0; |
| 915 | if (type == BRCMF_FWS_TYPE_MAC_OPEN) { | 932 | if (type == BRCMF_FWS_TYPE_MAC_OPEN) { |
| 916 | entry->state = BRCMF_FWS_STATE_OPEN; | 933 | entry->state = BRCMF_FWS_STATE_OPEN; |
| 934 | return BRCMF_FWS_RET_OK_SCHEDULE; | ||
| 917 | } else { | 935 | } else { |
| 918 | entry->state = BRCMF_FWS_STATE_CLOSE; | 936 | entry->state = BRCMF_FWS_STATE_CLOSE; |
| 919 | for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++) | 937 | for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++) |
| 920 | brcmf_fws_tim_update(fws, entry, i); | 938 | brcmf_fws_tim_update(fws, entry, i); |
| 921 | } | 939 | } |
| 922 | return 0; | 940 | return BRCMF_FWS_RET_OK_NOSCHEDULE; |
| 923 | } | 941 | } |
| 924 | 942 | ||
| 925 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | 943 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, |
| @@ -946,10 +964,10 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | |||
| 946 | switch (type) { | 964 | switch (type) { |
| 947 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | 965 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: |
| 948 | entry->state = BRCMF_FWS_STATE_OPEN; | 966 | entry->state = BRCMF_FWS_STATE_OPEN; |
| 949 | return 0; | 967 | return BRCMF_FWS_RET_OK_SCHEDULE; |
| 950 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | 968 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: |
| 951 | entry->state = BRCMF_FWS_STATE_CLOSE; | 969 | entry->state = BRCMF_FWS_STATE_CLOSE; |
| 952 | return 0; | 970 | return BRCMF_FWS_RET_OK_NOSCHEDULE; |
| 953 | default: | 971 | default: |
| 954 | ret = -EINVAL; | 972 | ret = -EINVAL; |
| 955 | break; | 973 | break; |
| @@ -979,15 +997,40 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type, | |||
| 979 | entry->requested_packet = data[0]; | 997 | entry->requested_packet = data[0]; |
| 980 | 998 | ||
| 981 | entry->ac_bitmap = data[2]; | 999 | entry->ac_bitmap = data[2]; |
| 982 | return 0; | 1000 | return BRCMF_FWS_RET_OK_SCHEDULE; |
| 983 | } | 1001 | } |
| 984 | 1002 | ||
| 985 | static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, | 1003 | static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, |
| 986 | u8 fifo, u8 credits) | 1004 | u8 fifo, u8 credits) |
| 987 | { | 1005 | { |
| 1006 | int lender_ac; | ||
| 1007 | int *borrowed; | ||
| 1008 | int *fifo_credit; | ||
| 1009 | |||
| 988 | if (!credits) | 1010 | if (!credits) |
| 989 | return; | 1011 | return; |
| 990 | 1012 | ||
| 1013 | if ((fifo == BRCMF_FWS_FIFO_AC_BE) && | ||
| 1014 | (fws->credits_borrowed[0])) { | ||
| 1015 | for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0; | ||
| 1016 | lender_ac--) { | ||
| 1017 | borrowed = &fws->credits_borrowed[lender_ac]; | ||
| 1018 | if (*borrowed) { | ||
| 1019 | fws->fifo_credit_map |= (1 << lender_ac); | ||
| 1020 | fifo_credit = &fws->fifo_credit[lender_ac]; | ||
| 1021 | if (*borrowed >= credits) { | ||
| 1022 | *borrowed -= credits; | ||
| 1023 | *fifo_credit += credits; | ||
| 1024 | return; | ||
| 1025 | } else { | ||
| 1026 | credits -= *borrowed; | ||
| 1027 | *fifo_credit += *borrowed; | ||
| 1028 | *borrowed = 0; | ||
| 1029 | } | ||
| 1030 | } | ||
| 1031 | } | ||
| 1032 | } | ||
| 1033 | |||
| 991 | fws->fifo_credit_map |= 1 << fifo; | 1034 | fws->fifo_credit_map |= 1 << fifo; |
| 992 | fws->fifo_credit[fifo] += credits; | 1035 | fws->fifo_credit[fifo] += credits; |
| 993 | } | 1036 | } |
| @@ -1074,7 +1117,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo) | |||
| 1074 | int num_nodes; | 1117 | int num_nodes; |
| 1075 | int node_pos; | 1118 | int node_pos; |
| 1076 | int prec_out; | 1119 | int prec_out; |
| 1077 | int pmsk = 3; | 1120 | int pmsk; |
| 1078 | int i; | 1121 | int i; |
| 1079 | 1122 | ||
| 1080 | table = (struct brcmf_fws_mac_descriptor *)&fws->desc; | 1123 | table = (struct brcmf_fws_mac_descriptor *)&fws->desc; |
| @@ -1083,11 +1126,14 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo) | |||
| 1083 | 1126 | ||
| 1084 | for (i = 0; i < num_nodes; i++) { | 1127 | for (i = 0; i < num_nodes; i++) { |
| 1085 | entry = &table[(node_pos + i) % num_nodes]; | 1128 | entry = &table[(node_pos + i) % num_nodes]; |
| 1086 | if (!entry->occupied) | 1129 | if (!entry->occupied || |
| 1130 | brcmf_fws_mac_desc_closed(fws, entry, fifo)) | ||
| 1087 | continue; | 1131 | continue; |
| 1088 | 1132 | ||
| 1089 | if (entry->suppressed) | 1133 | if (entry->suppressed) |
| 1090 | pmsk = 2; | 1134 | pmsk = 2; |
| 1135 | else | ||
| 1136 | pmsk = 3; | ||
| 1091 | p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out); | 1137 | p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out); |
| 1092 | if (p == NULL) { | 1138 | if (p == NULL) { |
| 1093 | if (entry->suppressed) { | 1139 | if (entry->suppressed) { |
| @@ -1250,7 +1296,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, | |||
| 1250 | 1296 | ||
| 1251 | if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { | 1297 | if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { |
| 1252 | brcmf_dbg(INFO, "ignored\n"); | 1298 | brcmf_dbg(INFO, "ignored\n"); |
| 1253 | return 0; | 1299 | return BRCMF_FWS_RET_OK_NOSCHEDULE; |
| 1254 | } | 1300 | } |
| 1255 | 1301 | ||
| 1256 | brcmf_dbg(TRACE, "enter: data %pM\n", data); | 1302 | brcmf_dbg(TRACE, "enter: data %pM\n", data); |
| @@ -1259,8 +1305,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, | |||
| 1259 | 1305 | ||
| 1260 | brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map, | 1306 | brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map, |
| 1261 | fws->fifo_delay_map); | 1307 | fws->fifo_delay_map); |
| 1262 | brcmf_fws_schedule_deq(fws); | 1308 | return BRCMF_FWS_RET_OK_SCHEDULE; |
| 1263 | return 0; | ||
| 1264 | } | 1309 | } |
| 1265 | 1310 | ||
| 1266 | static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) | 1311 | static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) |
| @@ -1344,6 +1389,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1344 | u8 type; | 1389 | u8 type; |
| 1345 | u8 len; | 1390 | u8 len; |
| 1346 | u8 *data; | 1391 | u8 *data; |
| 1392 | s32 status; | ||
| 1393 | s32 err; | ||
| 1347 | 1394 | ||
| 1348 | brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n", | 1395 | brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n", |
| 1349 | ifidx, skb->len, signal_len); | 1396 | ifidx, skb->len, signal_len); |
| @@ -1363,6 +1410,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1363 | data_len = signal_len; | 1410 | data_len = signal_len; |
| 1364 | signal_data = skb->data; | 1411 | signal_data = skb->data; |
| 1365 | 1412 | ||
| 1413 | status = BRCMF_FWS_RET_OK_NOSCHEDULE; | ||
| 1366 | while (data_len > 0) { | 1414 | while (data_len > 0) { |
| 1367 | /* extract tlv info */ | 1415 | /* extract tlv info */ |
| 1368 | type = signal_data[0]; | 1416 | type = signal_data[0]; |
| @@ -1388,6 +1436,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1388 | if (len != brcmf_fws_get_tlv_len(fws, type)) | 1436 | if (len != brcmf_fws_get_tlv_len(fws, type)) |
| 1389 | break; | 1437 | break; |
| 1390 | 1438 | ||
| 1439 | err = BRCMF_FWS_RET_OK_NOSCHEDULE; | ||
| 1391 | switch (type) { | 1440 | switch (type) { |
| 1392 | case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: | 1441 | case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: |
| 1393 | case BRCMF_FWS_TYPE_COMP_TXSTATUS: | 1442 | case BRCMF_FWS_TYPE_COMP_TXSTATUS: |
| @@ -1398,21 +1447,22 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1398 | break; | 1447 | break; |
| 1399 | case BRCMF_FWS_TYPE_MAC_OPEN: | 1448 | case BRCMF_FWS_TYPE_MAC_OPEN: |
| 1400 | case BRCMF_FWS_TYPE_MAC_CLOSE: | 1449 | case BRCMF_FWS_TYPE_MAC_CLOSE: |
| 1401 | brcmf_fws_macdesc_state_indicate(fws, type, data); | 1450 | err = brcmf_fws_macdesc_state_indicate(fws, type, data); |
| 1402 | break; | 1451 | break; |
| 1403 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | 1452 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: |
| 1404 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | 1453 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: |
| 1405 | brcmf_fws_interface_state_indicate(fws, type, data); | 1454 | err = brcmf_fws_interface_state_indicate(fws, type, |
| 1455 | data); | ||
| 1406 | break; | 1456 | break; |
| 1407 | case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: | 1457 | case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: |
| 1408 | case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: | 1458 | case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: |
| 1409 | brcmf_fws_request_indicate(fws, type, data); | 1459 | err = brcmf_fws_request_indicate(fws, type, data); |
| 1410 | break; | 1460 | break; |
| 1411 | case BRCMF_FWS_TYPE_TXSTATUS: | 1461 | case BRCMF_FWS_TYPE_TXSTATUS: |
| 1412 | brcmf_fws_txstatus_indicate(fws, data); | 1462 | brcmf_fws_txstatus_indicate(fws, data); |
| 1413 | break; | 1463 | break; |
| 1414 | case BRCMF_FWS_TYPE_FIFO_CREDITBACK: | 1464 | case BRCMF_FWS_TYPE_FIFO_CREDITBACK: |
| 1415 | brcmf_fws_fifocreditback_indicate(fws, data); | 1465 | err = brcmf_fws_fifocreditback_indicate(fws, data); |
| 1416 | break; | 1466 | break; |
| 1417 | case BRCMF_FWS_TYPE_RSSI: | 1467 | case BRCMF_FWS_TYPE_RSSI: |
| 1418 | brcmf_fws_rssi_indicate(fws, *data); | 1468 | brcmf_fws_rssi_indicate(fws, *data); |
| @@ -1426,7 +1476,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1426 | fws->stats.tlv_invalid_type++; | 1476 | fws->stats.tlv_invalid_type++; |
| 1427 | break; | 1477 | break; |
| 1428 | } | 1478 | } |
| 1429 | 1479 | if (err == BRCMF_FWS_RET_OK_SCHEDULE) | |
| 1480 | status = BRCMF_FWS_RET_OK_SCHEDULE; | ||
| 1430 | signal_data += len + 2; | 1481 | signal_data += len + 2; |
| 1431 | data_len -= len + 2; | 1482 | data_len -= len + 2; |
| 1432 | } | 1483 | } |
| @@ -1434,6 +1485,9 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
| 1434 | if (data_len != 0) | 1485 | if (data_len != 0) |
| 1435 | fws->stats.tlv_parse_failed++; | 1486 | fws->stats.tlv_parse_failed++; |
| 1436 | 1487 | ||
| 1488 | if (status == BRCMF_FWS_RET_OK_SCHEDULE) | ||
| 1489 | brcmf_fws_schedule_deq(fws); | ||
| 1490 | |||
| 1437 | /* signalling processing result does | 1491 | /* signalling processing result does |
| 1438 | * not affect the actual ethernet packet. | 1492 | * not affect the actual ethernet packet. |
| 1439 | */ | 1493 | */ |
| @@ -1553,7 +1607,7 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, | |||
| 1553 | return rc; | 1607 | return rc; |
| 1554 | } | 1608 | } |
| 1555 | 1609 | ||
| 1556 | static int | 1610 | static void |
| 1557 | brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) | 1611 | brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) |
| 1558 | { | 1612 | { |
| 1559 | /* | 1613 | /* |
| @@ -1595,7 +1649,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) | |||
| 1595 | /* free the hanger slot */ | 1649 | /* free the hanger slot */ |
| 1596 | brcmf_fws_hanger_poppkt(&fws->hanger, hslot, | 1650 | brcmf_fws_hanger_poppkt(&fws->hanger, hslot, |
| 1597 | &pktout, true); | 1651 | &pktout, true); |
| 1598 | brcmf_txfinalize(fws->drvr, skb, false); | ||
| 1599 | rc = -EINVAL; | 1652 | rc = -EINVAL; |
| 1600 | goto fail; | 1653 | goto fail; |
| 1601 | } | 1654 | } |
| @@ -1629,11 +1682,31 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) | |||
| 1629 | 1682 | ||
| 1630 | 1683 | ||
| 1631 | fail: | 1684 | fail: |
| 1632 | if (rc) | 1685 | if (rc) { |
| 1686 | brcmf_txfinalize(fws->drvr, skb, false); | ||
| 1633 | fws->stats.rollback_failed++; | 1687 | fws->stats.rollback_failed++; |
| 1634 | else | 1688 | } else |
| 1635 | fws->stats.rollback_success++; | 1689 | fws->stats.rollback_success++; |
| 1636 | return rc; | 1690 | } |
| 1691 | |||
| 1692 | static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws) | ||
| 1693 | { | ||
| 1694 | int lender_ac; | ||
| 1695 | |||
| 1696 | if (time_after(fws->borrow_defer_timestamp, jiffies)) | ||
| 1697 | return -ENAVAIL; | ||
| 1698 | |||
| 1699 | for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) { | ||
| 1700 | if (fws->fifo_credit[lender_ac]) { | ||
| 1701 | fws->credits_borrowed[lender_ac]++; | ||
| 1702 | fws->fifo_credit[lender_ac]--; | ||
| 1703 | if (fws->fifo_credit[lender_ac] == 0) | ||
| 1704 | fws->fifo_credit_map &= ~(1 << lender_ac); | ||
| 1705 | brcmf_dbg(TRACE, "borrow credit from: %d\n", lender_ac); | ||
| 1706 | return 0; | ||
| 1707 | } | ||
| 1708 | } | ||
| 1709 | return -ENAVAIL; | ||
| 1637 | } | 1710 | } |
| 1638 | 1711 | ||
| 1639 | static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo, | 1712 | static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo, |
| @@ -1669,8 +1742,17 @@ static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo, | |||
| 1669 | return 0; | 1742 | return 0; |
| 1670 | } | 1743 | } |
| 1671 | 1744 | ||
| 1745 | if (fifo != BRCMF_FWS_FIFO_AC_BE) | ||
| 1746 | fws->borrow_defer_timestamp = jiffies + | ||
| 1747 | BRCMF_FWS_BORROW_DEFER_PERIOD; | ||
| 1748 | |||
| 1672 | if (!(*credit)) { | 1749 | if (!(*credit)) { |
| 1673 | brcmf_dbg(TRACE, "exit: credits depleted\n"); | 1750 | /* Try to borrow a credit from other queue */ |
| 1751 | if (fifo == BRCMF_FWS_FIFO_AC_BE && | ||
| 1752 | brcmf_fws_borrow_credit(fws) == 0) | ||
| 1753 | return 0; | ||
| 1754 | |||
| 1755 | brcmf_dbg(TRACE, "exit: ac=%d, credits depleted\n", fifo); | ||
| 1674 | return -ENAVAIL; | 1756 | return -ENAVAIL; |
| 1675 | } | 1757 | } |
| 1676 | (*credit)--; | 1758 | (*credit)--; |
| @@ -1712,17 +1794,17 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, | |||
| 1712 | return rc; | 1794 | return rc; |
| 1713 | 1795 | ||
| 1714 | rollback: | 1796 | rollback: |
| 1715 | rc = brcmf_fws_rollback_toq(fws, skb); | 1797 | brcmf_fws_rollback_toq(fws, skb); |
| 1716 | return rc; | 1798 | return rc; |
| 1717 | } | 1799 | } |
| 1718 | 1800 | ||
| 1719 | int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | 1801 | int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) |
| 1720 | { | 1802 | { |
| 1721 | struct brcmf_pub *drvr = ifp->drvr; | 1803 | struct brcmf_pub *drvr = ifp->drvr; |
| 1804 | struct brcmf_fws_info *fws = drvr->fws; | ||
| 1722 | struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); | 1805 | struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); |
| 1723 | struct ethhdr *eh = (struct ethhdr *)(skb->data); | 1806 | struct ethhdr *eh = (struct ethhdr *)(skb->data); |
| 1724 | ulong flags; | 1807 | ulong flags; |
| 1725 | u8 ifidx = ifp->ifidx; | ||
| 1726 | int fifo = BRCMF_FWS_FIFO_BCMC; | 1808 | int fifo = BRCMF_FWS_FIFO_BCMC; |
| 1727 | bool multicast = is_multicast_ether_addr(eh->h_dest); | 1809 | bool multicast = is_multicast_ether_addr(eh->h_dest); |
| 1728 | 1810 | ||
| @@ -1734,9 +1816,9 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
| 1734 | if (ntohs(eh->h_proto) == ETH_P_PAE) | 1816 | if (ntohs(eh->h_proto) == ETH_P_PAE) |
| 1735 | atomic_inc(&ifp->pend_8021x_cnt); | 1817 | atomic_inc(&ifp->pend_8021x_cnt); |
| 1736 | 1818 | ||
| 1737 | if (!brcmf_fws_fc_active(drvr->fws)) { | 1819 | if (!brcmf_fws_fc_active(fws)) { |
| 1738 | /* If the protocol uses a data header, apply it */ | 1820 | /* If the protocol uses a data header, apply it */ |
| 1739 | brcmf_proto_hdrpush(drvr, ifidx, 0, skb); | 1821 | brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb); |
| 1740 | 1822 | ||
| 1741 | /* Use bus module to send data frame */ | 1823 | /* Use bus module to send data frame */ |
| 1742 | return brcmf_bus_txdata(drvr->bus_if, skb); | 1824 | return brcmf_bus_txdata(drvr->bus_if, skb); |
| @@ -1744,9 +1826,9 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
| 1744 | 1826 | ||
| 1745 | /* set control buffer information */ | 1827 | /* set control buffer information */ |
| 1746 | skcb->if_flags = 0; | 1828 | skcb->if_flags = 0; |
| 1747 | skcb->mac = brcmf_fws_find_mac_desc(drvr->fws, ifidx, eh->h_dest); | 1829 | skcb->mac = brcmf_fws_find_mac_desc(fws, ifp, eh->h_dest); |
| 1748 | skcb->state = BRCMF_FWS_SKBSTATE_NEW; | 1830 | skcb->state = BRCMF_FWS_SKBSTATE_NEW; |
| 1749 | brcmf_skb_if_flags_set_field(skb, INDEX, ifidx); | 1831 | brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); |
| 1750 | if (!multicast) | 1832 | if (!multicast) |
| 1751 | fifo = brcmf_fws_prio2fifo[skb->priority]; | 1833 | fifo = brcmf_fws_prio2fifo[skb->priority]; |
| 1752 | brcmf_skb_if_flags_set_field(skb, FIFO, fifo); | 1834 | brcmf_skb_if_flags_set_field(skb, FIFO, fifo); |
| @@ -1755,14 +1837,18 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
| 1755 | multicast, fifo); | 1837 | multicast, fifo); |
| 1756 | 1838 | ||
| 1757 | brcmf_fws_lock(drvr, flags); | 1839 | brcmf_fws_lock(drvr, flags); |
| 1758 | if (!brcmf_fws_mac_desc_ready(skcb->mac, fifo) || | 1840 | if (skcb->mac->suppressed || |
| 1841 | brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) || | ||
| 1842 | brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) || | ||
| 1759 | (!multicast && | 1843 | (!multicast && |
| 1760 | brcmf_fws_consume_credit(drvr->fws, fifo, skb) < 0)) { | 1844 | brcmf_fws_consume_credit(fws, fifo, skb) < 0)) { |
| 1761 | /* enqueue the packet in delayQ */ | 1845 | /* enqueue the packet in delayQ */ |
| 1762 | drvr->fws->fifo_delay_map |= 1 << fifo; | 1846 | drvr->fws->fifo_delay_map |= 1 << fifo; |
| 1763 | brcmf_fws_enq(drvr->fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); | 1847 | brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); |
| 1764 | } else { | 1848 | } else { |
| 1765 | brcmf_fws_commit_skb(drvr->fws, fifo, skb); | 1849 | if (brcmf_fws_commit_skb(fws, fifo, skb)) |
| 1850 | if (!multicast) | ||
| 1851 | brcmf_skb_pick_up_credit(fws, fifo, skb); | ||
| 1766 | } | 1852 | } |
| 1767 | brcmf_fws_unlock(drvr, flags); | 1853 | brcmf_fws_unlock(drvr, flags); |
| 1768 | return 0; | 1854 | return 0; |
| @@ -1799,14 +1885,17 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp) | |||
| 1799 | void brcmf_fws_del_interface(struct brcmf_if *ifp) | 1885 | void brcmf_fws_del_interface(struct brcmf_if *ifp) |
| 1800 | { | 1886 | { |
| 1801 | struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc; | 1887 | struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc; |
| 1888 | ulong flags; | ||
| 1802 | 1889 | ||
| 1803 | brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx); | 1890 | brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx); |
| 1804 | if (!entry) | 1891 | if (!entry) |
| 1805 | return; | 1892 | return; |
| 1806 | 1893 | ||
| 1894 | brcmf_fws_lock(ifp->drvr, flags); | ||
| 1807 | ifp->fws_desc = NULL; | 1895 | ifp->fws_desc = NULL; |
| 1808 | brcmf_fws_clear_mac_descriptor(entry); | 1896 | brcmf_fws_clear_mac_descriptor(entry); |
| 1809 | brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx); | 1897 | brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx); |
| 1898 | brcmf_fws_unlock(ifp->drvr, flags); | ||
| 1810 | } | 1899 | } |
| 1811 | 1900 | ||
| 1812 | static void brcmf_fws_dequeue_worker(struct work_struct *worker) | 1901 | static void brcmf_fws_dequeue_worker(struct work_struct *worker) |
| @@ -1826,14 +1915,29 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) | |||
| 1826 | fws->fifo_credit[fifo]); | 1915 | fws->fifo_credit[fifo]); |
| 1827 | for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) { | 1916 | for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) { |
| 1828 | skb = brcmf_fws_deq(fws, fifo); | 1917 | skb = brcmf_fws_deq(fws, fifo); |
| 1829 | if (!skb) | 1918 | if (!skb || brcmf_fws_commit_skb(fws, fifo, skb)) |
| 1830 | break; | 1919 | break; |
| 1831 | if (!brcmf_fws_commit_skb(fws, fifo, skb) && | 1920 | if (brcmf_skbcb(skb)->if_flags & |
| 1832 | brcmf_skbcb(skb)->if_flags & | ||
| 1833 | BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) | 1921 | BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) |
| 1834 | credit++; | 1922 | credit++; |
| 1835 | } | 1923 | } |
| 1836 | fws->fifo_credit[fifo] -= credit; | 1924 | if ((fifo == BRCMF_FWS_FIFO_AC_BE) && |
| 1925 | (credit == fws->fifo_credit[fifo])) { | ||
| 1926 | fws->fifo_credit[fifo] -= credit; | ||
| 1927 | while (brcmf_fws_borrow_credit(fws) == 0) { | ||
| 1928 | skb = brcmf_fws_deq(fws, fifo); | ||
| 1929 | if (!skb) { | ||
| 1930 | brcmf_fws_return_credits(fws, fifo, 1); | ||
| 1931 | break; | ||
| 1932 | } | ||
| 1933 | if (brcmf_fws_commit_skb(fws, fifo, skb)) { | ||
| 1934 | brcmf_fws_return_credits(fws, fifo, 1); | ||
| 1935 | break; | ||
| 1936 | } | ||
| 1937 | } | ||
| 1938 | } else { | ||
| 1939 | fws->fifo_credit[fifo] -= credit; | ||
| 1940 | } | ||
| 1837 | } | 1941 | } |
| 1838 | brcmf_fws_unlock(fws->drvr, flags); | 1942 | brcmf_fws_unlock(fws->drvr, flags); |
| 1839 | } | 1943 | } |
| @@ -1872,16 +1976,20 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
| 1872 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | | 1976 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | |
| 1873 | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; | 1977 | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; |
| 1874 | 1978 | ||
| 1875 | rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); | 1979 | rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, |
| 1980 | brcmf_fws_notify_credit_map); | ||
| 1876 | if (rc < 0) { | 1981 | if (rc < 0) { |
| 1877 | brcmf_err("failed to set bdcv2 tlv signaling\n"); | 1982 | brcmf_err("register credit map handler failed\n"); |
| 1878 | goto fail; | 1983 | goto fail; |
| 1879 | } | 1984 | } |
| 1880 | 1985 | ||
| 1881 | if (brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, | 1986 | /* setting the iovar may fail if feature is unsupported |
| 1882 | brcmf_fws_notify_credit_map)) { | 1987 | * so leave the rc as is so driver initialization can |
| 1883 | brcmf_err("register credit map handler failed\n"); | 1988 | * continue. |
| 1884 | goto fail; | 1989 | */ |
| 1990 | if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) { | ||
| 1991 | brcmf_err("failed to set bdcv2 tlv signaling\n"); | ||
| 1992 | goto fail_event; | ||
| 1885 | } | 1993 | } |
| 1886 | 1994 | ||
| 1887 | brcmf_fws_hanger_init(&drvr->fws->hanger); | 1995 | brcmf_fws_hanger_init(&drvr->fws->hanger); |
| @@ -1897,9 +2005,9 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
| 1897 | drvr->fw_signals ? "enabled" : "disabled", tlv); | 2005 | drvr->fw_signals ? "enabled" : "disabled", tlv); |
| 1898 | return 0; | 2006 | return 0; |
| 1899 | 2007 | ||
| 2008 | fail_event: | ||
| 2009 | brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); | ||
| 1900 | fail: | 2010 | fail: |
| 1901 | /* disable flow control entirely */ | ||
| 1902 | drvr->fw_signals = false; | ||
| 1903 | brcmf_fws_deinit(drvr); | 2011 | brcmf_fws_deinit(drvr); |
| 1904 | return rc; | 2012 | return rc; |
| 1905 | } | 2013 | } |
| @@ -1912,6 +2020,14 @@ void brcmf_fws_deinit(struct brcmf_pub *drvr) | |||
| 1912 | if (!fws) | 2020 | if (!fws) |
| 1913 | return; | 2021 | return; |
| 1914 | 2022 | ||
| 2023 | /* disable firmware signalling entirely | ||
| 2024 | * to avoid using the workqueue. | ||
| 2025 | */ | ||
| 2026 | drvr->fw_signals = false; | ||
| 2027 | |||
| 2028 | if (drvr->fws->fws_wq) | ||
| 2029 | destroy_workqueue(drvr->fws->fws_wq); | ||
| 2030 | |||
| 1915 | /* cleanup */ | 2031 | /* cleanup */ |
| 1916 | brcmf_fws_lock(drvr, flags); | 2032 | brcmf_fws_lock(drvr, flags); |
| 1917 | brcmf_fws_cleanup(fws, -1); | 2033 | brcmf_fws_cleanup(fws, -1); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index 94ff045df2b3..2b90da0d85f3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c | |||
| @@ -424,29 +424,6 @@ static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len) | |||
| 424 | 424 | ||
| 425 | 425 | ||
| 426 | /** | 426 | /** |
| 427 | * brcmf_p2p_chnr_to_chspec() - convert channel number to chanspec. | ||
| 428 | * | ||
| 429 | * @channel: channel number | ||
| 430 | */ | ||
| 431 | static u16 brcmf_p2p_chnr_to_chspec(u16 channel) | ||
| 432 | { | ||
| 433 | u16 chanspec; | ||
| 434 | |||
| 435 | chanspec = channel & WL_CHANSPEC_CHAN_MASK; | ||
| 436 | |||
| 437 | if (channel <= CH_MAX_2G_CHANNEL) | ||
| 438 | chanspec |= WL_CHANSPEC_BAND_2G; | ||
| 439 | else | ||
| 440 | chanspec |= WL_CHANSPEC_BAND_5G; | ||
| 441 | |||
| 442 | chanspec |= WL_CHANSPEC_BW_20; | ||
| 443 | chanspec |= WL_CHANSPEC_CTL_SB_NONE; | ||
| 444 | |||
| 445 | return chanspec; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | /** | ||
| 450 | * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation. | 427 | * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation. |
| 451 | * | 428 | * |
| 452 | * @ifp: ifp to use for iovars (primary). | 429 | * @ifp: ifp to use for iovars (primary). |
| @@ -837,7 +814,8 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, | |||
| 837 | IEEE80211_CHAN_PASSIVE_SCAN)) | 814 | IEEE80211_CHAN_PASSIVE_SCAN)) |
| 838 | continue; | 815 | continue; |
| 839 | 816 | ||
| 840 | chanspecs[i] = channel_to_chanspec(chan); | 817 | chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, |
| 818 | chan); | ||
| 841 | brcmf_dbg(INFO, "%d: chan=%d, channel spec=%x\n", | 819 | brcmf_dbg(INFO, "%d: chan=%d, channel spec=%x\n", |
| 842 | num_nodfs, chan->hw_value, chanspecs[i]); | 820 | num_nodfs, chan->hw_value, chanspecs[i]); |
| 843 | num_nodfs++; | 821 | num_nodfs++; |
| @@ -945,8 +923,8 @@ static s32 | |||
| 945 | brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) | 923 | brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) |
| 946 | { | 924 | { |
| 947 | struct brcmf_cfg80211_vif *vif; | 925 | struct brcmf_cfg80211_vif *vif; |
| 926 | struct brcmu_chan ch; | ||
| 948 | s32 err = 0; | 927 | s32 err = 0; |
| 949 | u16 chanspec; | ||
| 950 | 928 | ||
| 951 | vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; | 929 | vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; |
| 952 | if (!vif) { | 930 | if (!vif) { |
| @@ -961,9 +939,11 @@ brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) | |||
| 961 | goto exit; | 939 | goto exit; |
| 962 | } | 940 | } |
| 963 | 941 | ||
| 964 | chanspec = brcmf_p2p_chnr_to_chspec(channel); | 942 | ch.chnum = channel; |
| 943 | ch.bw = BRCMU_CHAN_BW_20; | ||
| 944 | p2p->cfg->d11inf.encchspec(&ch); | ||
| 965 | err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN, | 945 | err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN, |
| 966 | chanspec, (u16)duration); | 946 | ch.chspec, (u16)duration); |
| 967 | if (!err) { | 947 | if (!err) { |
| 968 | set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status); | 948 | set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status); |
| 969 | p2p->remain_on_channel_cookie++; | 949 | p2p->remain_on_channel_cookie++; |
| @@ -1075,6 +1055,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) | |||
| 1075 | u32 channel_cnt; | 1055 | u32 channel_cnt; |
| 1076 | u16 *default_chan_list; | 1056 | u16 *default_chan_list; |
| 1077 | u32 i; | 1057 | u32 i; |
| 1058 | struct brcmu_chan ch; | ||
| 1078 | 1059 | ||
| 1079 | brcmf_dbg(TRACE, "Enter\n"); | 1060 | brcmf_dbg(TRACE, "Enter\n"); |
| 1080 | 1061 | ||
| @@ -1089,15 +1070,23 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) | |||
| 1089 | err = -ENOMEM; | 1070 | err = -ENOMEM; |
| 1090 | goto exit; | 1071 | goto exit; |
| 1091 | } | 1072 | } |
| 1073 | ch.bw = BRCMU_CHAN_BW_20; | ||
| 1092 | if (channel) { | 1074 | if (channel) { |
| 1075 | ch.chnum = channel; | ||
| 1076 | p2p->cfg->d11inf.encchspec(&ch); | ||
| 1093 | /* insert same channel to the chan_list */ | 1077 | /* insert same channel to the chan_list */ |
| 1094 | for (i = 0; i < channel_cnt; i++) | 1078 | for (i = 0; i < channel_cnt; i++) |
| 1095 | default_chan_list[i] = | 1079 | default_chan_list[i] = ch.chspec; |
| 1096 | brcmf_p2p_chnr_to_chspec(channel); | ||
| 1097 | } else { | 1080 | } else { |
| 1098 | default_chan_list[0] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_1); | 1081 | ch.chnum = SOCIAL_CHAN_1; |
| 1099 | default_chan_list[1] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_2); | 1082 | p2p->cfg->d11inf.encchspec(&ch); |
| 1100 | default_chan_list[2] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_3); | 1083 | default_chan_list[0] = ch.chspec; |
| 1084 | ch.chnum = SOCIAL_CHAN_2; | ||
| 1085 | p2p->cfg->d11inf.encchspec(&ch); | ||
| 1086 | default_chan_list[1] = ch.chspec; | ||
| 1087 | ch.chnum = SOCIAL_CHAN_3; | ||
| 1088 | p2p->cfg->d11inf.encchspec(&ch); | ||
| 1089 | default_chan_list[2] = ch.chspec; | ||
| 1101 | } | 1090 | } |
| 1102 | err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list, | 1091 | err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list, |
| 1103 | WL_P2P_DISC_ST_SEARCH, WL_ESCAN_ACTION_START, | 1092 | WL_P2P_DISC_ST_SEARCH, WL_ESCAN_ACTION_START, |
| @@ -1227,6 +1216,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, | |||
| 1227 | { | 1216 | { |
| 1228 | struct brcmf_p2p_info *p2p = &cfg->p2p; | 1217 | struct brcmf_p2p_info *p2p = &cfg->p2p; |
| 1229 | struct afx_hdl *afx_hdl = &p2p->afx_hdl; | 1218 | struct afx_hdl *afx_hdl = &p2p->afx_hdl; |
| 1219 | struct brcmu_chan ch; | ||
| 1230 | u8 *ie; | 1220 | u8 *ie; |
| 1231 | s32 err; | 1221 | s32 err; |
| 1232 | u8 p2p_dev_addr[ETH_ALEN]; | 1222 | u8 p2p_dev_addr[ETH_ALEN]; |
| @@ -1252,8 +1242,12 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, | |||
| 1252 | p2p_dev_addr, sizeof(p2p_dev_addr)); | 1242 | p2p_dev_addr, sizeof(p2p_dev_addr)); |
| 1253 | if ((err >= 0) && | 1243 | if ((err >= 0) && |
| 1254 | (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) { | 1244 | (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) { |
| 1255 | afx_hdl->peer_chan = bi->ctl_ch ? bi->ctl_ch : | 1245 | if (!bi->ctl_ch) { |
| 1256 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 1246 | ch.chspec = le16_to_cpu(bi->chanspec); |
| 1247 | cfg->d11inf.decchspec(&ch); | ||
| 1248 | bi->ctl_ch = ch.chnum; | ||
| 1249 | } | ||
| 1250 | afx_hdl->peer_chan = bi->ctl_ch; | ||
| 1257 | brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", | 1251 | brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", |
| 1258 | afx_hdl->tx_dst_addr, afx_hdl->peer_chan); | 1252 | afx_hdl->tx_dst_addr, afx_hdl->peer_chan); |
| 1259 | complete(&afx_hdl->act_frm_scan); | 1253 | complete(&afx_hdl->act_frm_scan); |
| @@ -1360,12 +1354,14 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |||
| 1360 | u8 *frame = (u8 *)(rxframe + 1); | 1354 | u8 *frame = (u8 *)(rxframe + 1); |
| 1361 | struct brcmf_p2p_pub_act_frame *act_frm; | 1355 | struct brcmf_p2p_pub_act_frame *act_frm; |
| 1362 | struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm; | 1356 | struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm; |
| 1363 | u16 chanspec = be16_to_cpu(rxframe->chanspec); | 1357 | struct brcmu_chan ch; |
| 1364 | struct ieee80211_mgmt *mgmt_frame; | 1358 | struct ieee80211_mgmt *mgmt_frame; |
| 1365 | s32 freq; | 1359 | s32 freq; |
| 1366 | u16 mgmt_type; | 1360 | u16 mgmt_type; |
| 1367 | u8 action; | 1361 | u8 action; |
| 1368 | 1362 | ||
| 1363 | ch.chspec = be16_to_cpu(rxframe->chanspec); | ||
| 1364 | cfg->d11inf.decchspec(&ch); | ||
| 1369 | /* Check if wpa_supplicant has registered for this frame */ | 1365 | /* Check if wpa_supplicant has registered for this frame */ |
| 1370 | brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg); | 1366 | brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg); |
| 1371 | mgmt_type = (IEEE80211_STYPE_ACTION & IEEE80211_FCTL_STYPE) >> 4; | 1367 | mgmt_type = (IEEE80211_STYPE_ACTION & IEEE80211_FCTL_STYPE) >> 4; |
| @@ -1384,7 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |||
| 1384 | &p2p->status) && | 1380 | &p2p->status) && |
| 1385 | (memcmp(afx_hdl->tx_dst_addr, e->addr, | 1381 | (memcmp(afx_hdl->tx_dst_addr, e->addr, |
| 1386 | ETH_ALEN) == 0)) { | 1382 | ETH_ALEN) == 0)) { |
| 1387 | afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec); | 1383 | afx_hdl->peer_chan = ch.chnum; |
| 1388 | brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", | 1384 | brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", |
| 1389 | afx_hdl->peer_chan); | 1385 | afx_hdl->peer_chan); |
| 1390 | complete(&afx_hdl->act_frm_scan); | 1386 | complete(&afx_hdl->act_frm_scan); |
| @@ -1427,8 +1423,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, | |||
| 1427 | memcpy(&mgmt_frame->u, frame, mgmt_frame_len); | 1423 | memcpy(&mgmt_frame->u, frame, mgmt_frame_len); |
| 1428 | mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); | 1424 | mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); |
| 1429 | 1425 | ||
| 1430 | freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec), | 1426 | freq = ieee80211_channel_to_frequency(ch.chnum, |
| 1431 | CHSPEC_IS2G(chanspec) ? | 1427 | ch.band == BRCMU_CHAN_BAND_2G ? |
| 1432 | IEEE80211_BAND_2GHZ : | 1428 | IEEE80211_BAND_2GHZ : |
| 1433 | IEEE80211_BAND_5GHZ); | 1429 | IEEE80211_BAND_5GHZ); |
| 1434 | 1430 | ||
| @@ -1854,6 +1850,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |||
| 1854 | struct brcmf_cfg80211_vif *vif = ifp->vif; | 1850 | struct brcmf_cfg80211_vif *vif = ifp->vif; |
| 1855 | struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; | 1851 | struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; |
| 1856 | u16 chanspec = be16_to_cpu(rxframe->chanspec); | 1852 | u16 chanspec = be16_to_cpu(rxframe->chanspec); |
| 1853 | struct brcmu_chan ch; | ||
| 1857 | u8 *mgmt_frame; | 1854 | u8 *mgmt_frame; |
| 1858 | u32 mgmt_frame_len; | 1855 | u32 mgmt_frame_len; |
| 1859 | s32 freq; | 1856 | s32 freq; |
| @@ -1862,9 +1859,12 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |||
| 1862 | brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, | 1859 | brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, |
| 1863 | e->reason); | 1860 | e->reason); |
| 1864 | 1861 | ||
| 1862 | ch.chspec = be16_to_cpu(rxframe->chanspec); | ||
| 1863 | cfg->d11inf.decchspec(&ch); | ||
| 1864 | |||
| 1865 | if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && | 1865 | if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && |
| 1866 | (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { | 1866 | (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { |
| 1867 | afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec); | 1867 | afx_hdl->peer_chan = ch.chnum; |
| 1868 | brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", | 1868 | brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", |
| 1869 | afx_hdl->peer_chan); | 1869 | afx_hdl->peer_chan); |
| 1870 | complete(&afx_hdl->act_frm_scan); | 1870 | complete(&afx_hdl->act_frm_scan); |
| @@ -1889,8 +1889,8 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, | |||
| 1889 | 1889 | ||
| 1890 | mgmt_frame = (u8 *)(rxframe + 1); | 1890 | mgmt_frame = (u8 *)(rxframe + 1); |
| 1891 | mgmt_frame_len = e->datalen - sizeof(*rxframe); | 1891 | mgmt_frame_len = e->datalen - sizeof(*rxframe); |
| 1892 | freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec), | 1892 | freq = ieee80211_channel_to_frequency(ch.chnum, |
| 1893 | CHSPEC_IS2G(chanspec) ? | 1893 | ch.band == BRCMU_CHAN_BAND_2G ? |
| 1894 | IEEE80211_BAND_2GHZ : | 1894 | IEEE80211_BAND_2GHZ : |
| 1895 | IEEE80211_BAND_5GHZ); | 1895 | IEEE80211_BAND_5GHZ); |
| 1896 | 1896 | ||
| @@ -2014,21 +2014,19 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p, | |||
| 2014 | { | 2014 | { |
| 2015 | struct brcmf_if *ifp; | 2015 | struct brcmf_if *ifp; |
| 2016 | struct brcmf_fil_chan_info_le ci; | 2016 | struct brcmf_fil_chan_info_le ci; |
| 2017 | struct brcmu_chan ch; | ||
| 2017 | s32 err; | 2018 | s32 err; |
| 2018 | 2019 | ||
| 2019 | ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; | 2020 | ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; |
| 2020 | 2021 | ||
| 2021 | *chanspec = 11 & WL_CHANSPEC_CHAN_MASK; | 2022 | ch.chnum = 11; |
| 2022 | 2023 | ||
| 2023 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci)); | 2024 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci)); |
| 2024 | if (!err) { | 2025 | if (!err) |
| 2025 | *chanspec = le32_to_cpu(ci.hw_channel) & WL_CHANSPEC_CHAN_MASK; | 2026 | ch.chnum = le32_to_cpu(ci.hw_channel); |
| 2026 | if (*chanspec < CH_MAX_2G_CHANNEL) | 2027 | ch.bw = BRCMU_CHAN_BW_20; |
| 2027 | *chanspec |= WL_CHANSPEC_BAND_2G; | 2028 | p2p->cfg->d11inf.encchspec(&ch); |
| 2028 | else | 2029 | *chanspec = ch.chspec; |
| 2029 | *chanspec |= WL_CHANSPEC_BAND_5G; | ||
| 2030 | } | ||
| 2031 | *chanspec |= WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; | ||
| 2032 | } | 2030 | } |
| 2033 | 2031 | ||
| 2034 | /** | 2032 | /** |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 14be2d5530ce..ca72177388b9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
| @@ -40,6 +40,15 @@ | |||
| 40 | #define BCM4329_CORE_ARM_BASE 0x18002000 | 40 | #define BCM4329_CORE_ARM_BASE 0x18002000 |
| 41 | #define BCM4329_RAMSIZE 0x48000 | 41 | #define BCM4329_RAMSIZE 0x48000 |
| 42 | 42 | ||
| 43 | /* bcm43143 */ | ||
| 44 | /* SDIO device core */ | ||
| 45 | #define BCM43143_CORE_BUS_BASE 0x18002000 | ||
| 46 | /* internal memory core */ | ||
| 47 | #define BCM43143_CORE_SOCRAM_BASE 0x18004000 | ||
| 48 | /* ARM Cortex M3 core, ID 0x82a */ | ||
| 49 | #define BCM43143_CORE_ARM_BASE 0x18003000 | ||
| 50 | #define BCM43143_RAMSIZE 0x70000 | ||
| 51 | |||
| 43 | #define SBCOREREV(sbidh) \ | 52 | #define SBCOREREV(sbidh) \ |
| 44 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ | 53 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ |
| 45 | ((sbidh) & SSB_IDHIGH_RCLO)) | 54 | ((sbidh) & SSB_IDHIGH_RCLO)) |
| @@ -52,6 +61,9 @@ | |||
| 52 | #define CIB_REV_MASK 0xff000000 | 61 | #define CIB_REV_MASK 0xff000000 |
| 53 | #define CIB_REV_SHIFT 24 | 62 | #define CIB_REV_SHIFT 24 |
| 54 | 63 | ||
| 64 | /* ARM CR4 core specific control flag bits */ | ||
| 65 | #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 | ||
| 66 | |||
| 55 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | 67 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) |
| 56 | /* SDIO Pad drive strength to select value mappings */ | 68 | /* SDIO Pad drive strength to select value mappings */ |
| 57 | struct sdiod_drive_str { | 69 | struct sdiod_drive_str { |
| @@ -70,6 +82,14 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = { | |||
| 70 | {0, 0x1} | 82 | {0, 0x1} |
| 71 | }; | 83 | }; |
| 72 | 84 | ||
| 85 | /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ | ||
| 86 | static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { | ||
| 87 | {16, 0x7}, | ||
| 88 | {12, 0x5}, | ||
| 89 | {8, 0x3}, | ||
| 90 | {4, 0x1} | ||
| 91 | }; | ||
| 92 | |||
| 73 | u8 | 93 | u8 |
| 74 | brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) | 94 | brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) |
| 75 | { | 95 | { |
| @@ -149,7 +169,7 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | |||
| 149 | 169 | ||
| 150 | static void | 170 | static void |
| 151 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | 171 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, |
| 152 | struct chip_info *ci, u16 coreid) | 172 | struct chip_info *ci, u16 coreid, u32 core_bits) |
| 153 | { | 173 | { |
| 154 | u32 regdata, base; | 174 | u32 regdata, base; |
| 155 | u8 idx; | 175 | u8 idx; |
| @@ -235,7 +255,7 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | |||
| 235 | 255 | ||
| 236 | static void | 256 | static void |
| 237 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | 257 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, |
| 238 | struct chip_info *ci, u16 coreid) | 258 | struct chip_info *ci, u16 coreid, u32 core_bits) |
| 239 | { | 259 | { |
| 240 | u8 idx; | 260 | u8 idx; |
| 241 | u32 regdata; | 261 | u32 regdata; |
| @@ -249,19 +269,36 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | |||
| 249 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | 269 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) |
| 250 | return; | 270 | return; |
| 251 | 271 | ||
| 252 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL); | 272 | /* ensure no pending backplane operation |
| 253 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 273 | * 300uc should be sufficient for backplane ops to be finish |
| 274 | * extra 10ms is taken into account for firmware load stage | ||
| 275 | * after 10300us carry on disabling the core anyway | ||
| 276 | */ | ||
| 277 | SPINWAIT(brcmf_sdio_regrl(sdiodev, | ||
| 278 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
| 279 | NULL), 10300); | ||
| 280 | regdata = brcmf_sdio_regrl(sdiodev, | ||
| 281 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
| 254 | NULL); | 282 | NULL); |
| 255 | udelay(10); | 283 | if (regdata) |
| 284 | brcmf_err("disabling core 0x%x with reset status %x\n", | ||
| 285 | coreid, regdata); | ||
| 256 | 286 | ||
| 257 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | 287 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, |
| 258 | BCMA_RESET_CTL_RESET, NULL); | 288 | BCMA_RESET_CTL_RESET, NULL); |
| 259 | udelay(1); | 289 | udelay(1); |
| 290 | |||
| 291 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
| 292 | core_bits, NULL); | ||
| 293 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
| 294 | NULL); | ||
| 295 | usleep_range(10, 20); | ||
| 296 | |||
| 260 | } | 297 | } |
| 261 | 298 | ||
| 262 | static void | 299 | static void |
| 263 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | 300 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, |
| 264 | struct chip_info *ci, u16 coreid) | 301 | struct chip_info *ci, u16 coreid, u32 core_bits) |
| 265 | { | 302 | { |
| 266 | u32 regdata; | 303 | u32 regdata; |
| 267 | u8 idx; | 304 | u8 idx; |
| @@ -272,7 +309,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
| 272 | * Must do the disable sequence first to work for | 309 | * Must do the disable sequence first to work for |
| 273 | * arbitrary current core state. | 310 | * arbitrary current core state. |
| 274 | */ | 311 | */ |
| 275 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid); | 312 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); |
| 276 | 313 | ||
| 277 | /* | 314 | /* |
| 278 | * Now do the initialization sequence. | 315 | * Now do the initialization sequence. |
| @@ -325,7 +362,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
| 325 | 362 | ||
| 326 | static void | 363 | static void |
| 327 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | 364 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, |
| 328 | struct chip_info *ci, u16 coreid) | 365 | struct chip_info *ci, u16 coreid, u32 core_bits) |
| 329 | { | 366 | { |
| 330 | u8 idx; | 367 | u8 idx; |
| 331 | u32 regdata; | 368 | u32 regdata; |
| @@ -333,31 +370,69 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
| 333 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | 370 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); |
| 334 | 371 | ||
| 335 | /* must disable first to work for arbitrary current core state */ | 372 | /* must disable first to work for arbitrary current core state */ |
| 336 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); | 373 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); |
| 337 | 374 | ||
| 338 | /* now do initialization sequence */ | 375 | /* now do initialization sequence */ |
| 339 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 376 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
| 340 | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); | 377 | core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); |
| 341 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 378 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
| 342 | NULL); | 379 | NULL); |
| 343 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | 380 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, |
| 344 | 0, NULL); | 381 | 0, NULL); |
| 382 | regdata = brcmf_sdio_regrl(sdiodev, | ||
| 383 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
| 384 | NULL); | ||
| 345 | udelay(1); | 385 | udelay(1); |
| 346 | 386 | ||
| 347 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 387 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
| 348 | BCMA_IOCTL_CLK, NULL); | 388 | core_bits | BCMA_IOCTL_CLK, NULL); |
| 349 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 389 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
| 350 | NULL); | 390 | NULL); |
| 351 | udelay(1); | 391 | udelay(1); |
| 352 | } | 392 | } |
| 353 | 393 | ||
| 394 | #ifdef DEBUG | ||
| 395 | /* safety check for chipinfo */ | ||
| 396 | static int brcmf_sdio_chip_cichk(struct chip_info *ci) | ||
| 397 | { | ||
| 398 | u8 core_idx; | ||
| 399 | |||
| 400 | /* check RAM core presence for ARM CM3 core */ | ||
| 401 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
| 402 | if (BRCMF_MAX_CORENUM != core_idx) { | ||
| 403 | core_idx = brcmf_sdio_chip_getinfidx(ci, | ||
| 404 | BCMA_CORE_INTERNAL_MEM); | ||
| 405 | if (BRCMF_MAX_CORENUM == core_idx) { | ||
| 406 | brcmf_err("RAM core not provided with ARM CM3 core\n"); | ||
| 407 | return -ENODEV; | ||
| 408 | } | ||
| 409 | } | ||
| 410 | |||
| 411 | /* check RAM base for ARM CR4 core */ | ||
| 412 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4); | ||
| 413 | if (BRCMF_MAX_CORENUM != core_idx) { | ||
| 414 | if (ci->rambase == 0) { | ||
| 415 | brcmf_err("RAM base not provided with ARM CR4 core\n"); | ||
| 416 | return -ENOMEM; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 | return 0; | ||
| 421 | } | ||
| 422 | #else /* DEBUG */ | ||
| 423 | static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) | ||
| 424 | { | ||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | #endif | ||
| 428 | |||
| 354 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | 429 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, |
| 355 | struct chip_info *ci, u32 regs) | 430 | struct chip_info *ci, u32 regs) |
| 356 | { | 431 | { |
| 357 | u32 regdata; | 432 | u32 regdata; |
| 433 | int ret; | ||
| 358 | 434 | ||
| 359 | /* | 435 | /* Get CC core rev |
| 360 | * Get CC core rev | ||
| 361 | * Chipid is assume to be at offset 0 from regs arg | 436 | * Chipid is assume to be at offset 0 from regs arg |
| 362 | * For different chiptypes or old sdio hosts w/o chipcommon, | 437 | * For different chiptypes or old sdio hosts w/o chipcommon, |
| 363 | * other ways of recognition should be added here. | 438 | * other ways of recognition should be added here. |
| @@ -375,6 +450,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
| 375 | 450 | ||
| 376 | /* Address of cores for new chips should be added here */ | 451 | /* Address of cores for new chips should be added here */ |
| 377 | switch (ci->chip) { | 452 | switch (ci->chip) { |
| 453 | case BCM43143_CHIP_ID: | ||
| 454 | ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; | ||
| 455 | ci->c_inf[0].cib = 0x2b000000; | ||
| 456 | ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; | ||
| 457 | ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; | ||
| 458 | ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; | ||
| 459 | ci->c_inf[1].cib = 0x18000000; | ||
| 460 | ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; | ||
| 461 | ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; | ||
| 462 | ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; | ||
| 463 | ci->c_inf[2].cib = 0x14000000; | ||
| 464 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; | ||
| 465 | ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; | ||
| 466 | ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; | ||
| 467 | ci->c_inf[3].cib = 0x07000000; | ||
| 468 | ci->ramsize = BCM43143_RAMSIZE; | ||
| 469 | break; | ||
| 378 | case BCM43241_CHIP_ID: | 470 | case BCM43241_CHIP_ID: |
| 379 | ci->c_inf[0].wrapbase = 0x18100000; | 471 | ci->c_inf[0].wrapbase = 0x18100000; |
| 380 | ci->c_inf[0].cib = 0x2a084411; | 472 | ci->c_inf[0].cib = 0x2a084411; |
| @@ -435,11 +527,29 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
| 435 | ci->c_inf[3].cib = 0x07004211; | 527 | ci->c_inf[3].cib = 0x07004211; |
| 436 | ci->ramsize = 0x80000; | 528 | ci->ramsize = 0x80000; |
| 437 | break; | 529 | break; |
| 530 | case BCM4335_CHIP_ID: | ||
| 531 | ci->c_inf[0].wrapbase = 0x18100000; | ||
| 532 | ci->c_inf[0].cib = 0x2b084411; | ||
| 533 | ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; | ||
| 534 | ci->c_inf[1].base = 0x18005000; | ||
| 535 | ci->c_inf[1].wrapbase = 0x18105000; | ||
| 536 | ci->c_inf[1].cib = 0x0f004211; | ||
| 537 | ci->c_inf[2].id = BCMA_CORE_ARM_CR4; | ||
| 538 | ci->c_inf[2].base = 0x18002000; | ||
| 539 | ci->c_inf[2].wrapbase = 0x18102000; | ||
| 540 | ci->c_inf[2].cib = 0x01084411; | ||
| 541 | ci->ramsize = 0xc0000; | ||
| 542 | ci->rambase = 0x180000; | ||
| 543 | break; | ||
| 438 | default: | 544 | default: |
| 439 | brcmf_err("chipid 0x%x is not supported\n", ci->chip); | 545 | brcmf_err("chipid 0x%x is not supported\n", ci->chip); |
| 440 | return -ENODEV; | 546 | return -ENODEV; |
| 441 | } | 547 | } |
| 442 | 548 | ||
| 549 | ret = brcmf_sdio_chip_cichk(ci); | ||
| 550 | if (ret) | ||
| 551 | return ret; | ||
| 552 | |||
| 443 | switch (ci->socitype) { | 553 | switch (ci->socitype) { |
| 444 | case SOCI_SB: | 554 | case SOCI_SB: |
| 445 | ci->iscoreup = brcmf_sdio_sb_iscoreup; | 555 | ci->iscoreup = brcmf_sdio_sb_iscoreup; |
| @@ -539,7 +649,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | |||
| 539 | * Make sure any on-chip ARM is off (in case strapping is wrong), | 649 | * Make sure any on-chip ARM is off (in case strapping is wrong), |
| 540 | * or downloaded code was already running. | 650 | * or downloaded code was already running. |
| 541 | */ | 651 | */ |
| 542 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); | 652 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); |
| 543 | } | 653 | } |
| 544 | 654 | ||
| 545 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 655 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, |
| @@ -600,21 +710,37 @@ void | |||
| 600 | brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | 710 | brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, |
| 601 | struct chip_info *ci, u32 drivestrength) | 711 | struct chip_info *ci, u32 drivestrength) |
| 602 | { | 712 | { |
| 603 | struct sdiod_drive_str *str_tab = NULL; | 713 | const struct sdiod_drive_str *str_tab = NULL; |
| 604 | u32 str_mask = 0; | 714 | u32 str_mask; |
| 605 | u32 str_shift = 0; | 715 | u32 str_shift; |
| 606 | char chn[8]; | 716 | char chn[8]; |
| 607 | u32 base = ci->c_inf[0].base; | 717 | u32 base = ci->c_inf[0].base; |
| 718 | u32 i; | ||
| 719 | u32 drivestrength_sel = 0; | ||
| 720 | u32 cc_data_temp; | ||
| 721 | u32 addr; | ||
| 608 | 722 | ||
| 609 | if (!(ci->c_inf[0].caps & CC_CAP_PMU)) | 723 | if (!(ci->c_inf[0].caps & CC_CAP_PMU)) |
| 610 | return; | 724 | return; |
| 611 | 725 | ||
| 612 | switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { | 726 | switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { |
| 613 | case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): | 727 | case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): |
| 614 | str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8; | 728 | str_tab = sdiod_drvstr_tab1_1v8; |
| 615 | str_mask = 0x00003800; | 729 | str_mask = 0x00003800; |
| 616 | str_shift = 11; | 730 | str_shift = 11; |
| 617 | break; | 731 | break; |
| 732 | case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): | ||
| 733 | /* note: 43143 does not support tristate */ | ||
| 734 | i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; | ||
| 735 | if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) { | ||
| 736 | str_tab = sdiod_drvstr_tab2_3v3; | ||
| 737 | str_mask = 0x00000007; | ||
| 738 | str_shift = 0; | ||
| 739 | } else | ||
| 740 | brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n", | ||
| 741 | brcmf_sdio_chip_name(ci->chip, chn, 8), | ||
| 742 | drivestrength); | ||
| 743 | break; | ||
| 618 | default: | 744 | default: |
| 619 | brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | 745 | brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", |
| 620 | brcmf_sdio_chip_name(ci->chip, chn, 8), | 746 | brcmf_sdio_chip_name(ci->chip, chn, 8), |
| @@ -623,30 +749,207 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | |||
| 623 | } | 749 | } |
| 624 | 750 | ||
| 625 | if (str_tab != NULL) { | 751 | if (str_tab != NULL) { |
| 626 | u32 drivestrength_sel = 0; | ||
| 627 | u32 cc_data_temp; | ||
| 628 | int i; | ||
| 629 | |||
| 630 | for (i = 0; str_tab[i].strength != 0; i++) { | 752 | for (i = 0; str_tab[i].strength != 0; i++) { |
| 631 | if (drivestrength >= str_tab[i].strength) { | 753 | if (drivestrength >= str_tab[i].strength) { |
| 632 | drivestrength_sel = str_tab[i].sel; | 754 | drivestrength_sel = str_tab[i].sel; |
| 633 | break; | 755 | break; |
| 634 | } | 756 | } |
| 635 | } | 757 | } |
| 636 | 758 | addr = CORE_CC_REG(base, chipcontrol_addr); | |
| 637 | brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), | 759 | brcmf_sdio_regwl(sdiodev, addr, 1, NULL); |
| 638 | 1, NULL); | 760 | cc_data_temp = brcmf_sdio_regrl(sdiodev, addr, NULL); |
| 639 | cc_data_temp = | ||
| 640 | brcmf_sdio_regrl(sdiodev, | ||
| 641 | CORE_CC_REG(base, chipcontrol_addr), | ||
| 642 | NULL); | ||
| 643 | cc_data_temp &= ~str_mask; | 761 | cc_data_temp &= ~str_mask; |
| 644 | drivestrength_sel <<= str_shift; | 762 | drivestrength_sel <<= str_shift; |
| 645 | cc_data_temp |= drivestrength_sel; | 763 | cc_data_temp |= drivestrength_sel; |
| 646 | brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), | 764 | brcmf_sdio_regwl(sdiodev, addr, cc_data_temp, NULL); |
| 647 | cc_data_temp, NULL); | ||
| 648 | 765 | ||
| 649 | brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", | 766 | brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", |
| 650 | drivestrength, cc_data_temp); | 767 | str_tab[i].strength, drivestrength, cc_data_temp); |
| 651 | } | 768 | } |
| 652 | } | 769 | } |
| 770 | |||
| 771 | #ifdef DEBUG | ||
| 772 | static bool | ||
| 773 | brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, | ||
| 774 | char *nvram_dat, uint nvram_sz) | ||
| 775 | { | ||
| 776 | char *nvram_ularray; | ||
| 777 | int err; | ||
| 778 | bool ret = true; | ||
| 779 | |||
| 780 | /* read back and verify */ | ||
| 781 | brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz); | ||
| 782 | nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL); | ||
| 783 | /* do not proceed while no memory but */ | ||
| 784 | if (!nvram_ularray) | ||
| 785 | return true; | ||
| 786 | |||
| 787 | /* Upload image to verify downloaded contents. */ | ||
| 788 | memset(nvram_ularray, 0xaa, nvram_sz); | ||
| 789 | |||
| 790 | /* Read the vars list to temp buffer for comparison */ | ||
| 791 | err = brcmf_sdio_ramrw(sdiodev, false, nvram_addr, nvram_ularray, | ||
| 792 | nvram_sz); | ||
| 793 | if (err) { | ||
| 794 | brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", | ||
| 795 | err, nvram_sz, nvram_addr); | ||
| 796 | } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) { | ||
| 797 | brcmf_err("Downloaded NVRAM image is corrupted\n"); | ||
| 798 | ret = false; | ||
| 799 | } | ||
| 800 | kfree(nvram_ularray); | ||
| 801 | |||
| 802 | return ret; | ||
| 803 | } | ||
| 804 | #else /* DEBUG */ | ||
| 805 | static inline bool | ||
| 806 | brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, | ||
| 807 | char *nvram_dat, uint nvram_sz) | ||
| 808 | { | ||
| 809 | return true; | ||
| 810 | } | ||
| 811 | #endif /* DEBUG */ | ||
| 812 | |||
| 813 | static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, | ||
| 814 | struct chip_info *ci, | ||
| 815 | char *nvram_dat, uint nvram_sz) | ||
| 816 | { | ||
| 817 | int err; | ||
| 818 | u32 nvram_addr; | ||
| 819 | u32 token; | ||
| 820 | __le32 token_le; | ||
| 821 | |||
| 822 | nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase; | ||
| 823 | |||
| 824 | /* Write the vars list */ | ||
| 825 | err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); | ||
| 826 | if (err) { | ||
| 827 | brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n", | ||
| 828 | err, nvram_sz, nvram_addr); | ||
| 829 | return false; | ||
| 830 | } | ||
| 831 | |||
| 832 | if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr, | ||
| 833 | nvram_dat, nvram_sz)) | ||
| 834 | return false; | ||
| 835 | |||
| 836 | /* generate token: | ||
| 837 | * nvram size, converted to words, in lower 16-bits, checksum | ||
| 838 | * in upper 16-bits. | ||
| 839 | */ | ||
| 840 | token = nvram_sz / 4; | ||
| 841 | token = (~token << 16) | (token & 0x0000FFFF); | ||
| 842 | token_le = cpu_to_le32(token); | ||
| 843 | |||
| 844 | brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize); | ||
| 845 | brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n", | ||
| 846 | nvram_addr, nvram_sz, token); | ||
| 847 | |||
| 848 | /* Write the length token to the last word */ | ||
| 849 | if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), | ||
| 850 | (u8 *)&token_le, 4)) | ||
| 851 | return false; | ||
| 852 | |||
| 853 | return true; | ||
| 854 | } | ||
| 855 | |||
| 856 | static void | ||
| 857 | brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, | ||
| 858 | struct chip_info *ci) | ||
| 859 | { | ||
| 860 | u32 zeros = 0; | ||
| 861 | |||
| 862 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); | ||
| 863 | ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); | ||
| 864 | |||
| 865 | /* clear length token */ | ||
| 866 | brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); | ||
| 867 | } | ||
| 868 | |||
| 869 | static bool | ||
| 870 | brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
| 871 | char *nvram_dat, uint nvram_sz) | ||
| 872 | { | ||
| 873 | u8 core_idx; | ||
| 874 | u32 reg_addr; | ||
| 875 | |||
| 876 | if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { | ||
| 877 | brcmf_err("SOCRAM core is down after reset?\n"); | ||
| 878 | return false; | ||
| 879 | } | ||
| 880 | |||
| 881 | if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) | ||
| 882 | return false; | ||
| 883 | |||
| 884 | /* clear all interrupts */ | ||
| 885 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); | ||
| 886 | reg_addr = ci->c_inf[core_idx].base; | ||
| 887 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); | ||
| 888 | brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); | ||
| 889 | |||
| 890 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); | ||
| 891 | |||
| 892 | return true; | ||
| 893 | } | ||
| 894 | |||
| 895 | static inline void | ||
| 896 | brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, | ||
| 897 | struct chip_info *ci) | ||
| 898 | { | ||
| 899 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, | ||
| 900 | ARMCR4_BCMA_IOCTL_CPUHALT); | ||
| 901 | } | ||
| 902 | |||
| 903 | static bool | ||
| 904 | brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
| 905 | char *nvram_dat, uint nvram_sz) | ||
| 906 | { | ||
| 907 | u8 core_idx; | ||
| 908 | u32 reg_addr; | ||
| 909 | |||
| 910 | if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) | ||
| 911 | return false; | ||
| 912 | |||
| 913 | /* clear all interrupts */ | ||
| 914 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); | ||
| 915 | reg_addr = ci->c_inf[core_idx].base; | ||
| 916 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); | ||
| 917 | brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); | ||
| 918 | |||
| 919 | /* Write reset vector to address 0 */ | ||
| 920 | brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, | ||
| 921 | sizeof(ci->rst_vec)); | ||
| 922 | |||
| 923 | /* restore ARM */ | ||
| 924 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); | ||
| 925 | |||
| 926 | return true; | ||
| 927 | } | ||
| 928 | |||
| 929 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, | ||
| 930 | struct chip_info *ci) | ||
| 931 | { | ||
| 932 | u8 arm_core_idx; | ||
| 933 | |||
| 934 | arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
| 935 | if (BRCMF_MAX_CORENUM != arm_core_idx) { | ||
| 936 | brcmf_sdio_chip_cm3_enterdl(sdiodev, ci); | ||
| 937 | return; | ||
| 938 | } | ||
| 939 | |||
| 940 | brcmf_sdio_chip_cr4_enterdl(sdiodev, ci); | ||
| 941 | } | ||
| 942 | |||
| 943 | bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, | ||
| 944 | struct chip_info *ci, char *nvram_dat, | ||
| 945 | uint nvram_sz) | ||
| 946 | { | ||
| 947 | u8 arm_core_idx; | ||
| 948 | |||
| 949 | arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
| 950 | if (BRCMF_MAX_CORENUM != arm_core_idx) | ||
| 951 | return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, | ||
| 952 | nvram_sz); | ||
| 953 | |||
| 954 | return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); | ||
| 955 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index ce974d76bd92..83c041f1bf4a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
| @@ -73,15 +73,17 @@ struct chip_info { | |||
| 73 | u32 pmurev; | 73 | u32 pmurev; |
| 74 | u32 pmucaps; | 74 | u32 pmucaps; |
| 75 | u32 ramsize; | 75 | u32 ramsize; |
| 76 | u32 rambase; | ||
| 77 | u32 rst_vec; /* reset vertor for ARM CR4 core */ | ||
| 76 | 78 | ||
| 77 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | 79 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, |
| 78 | u16 coreid); | 80 | u16 coreid); |
| 79 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | 81 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, |
| 80 | u16 coreid); | 82 | u16 coreid); |
| 81 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, | 83 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, |
| 82 | struct chip_info *ci, u16 coreid); | 84 | struct chip_info *ci, u16 coreid, u32 core_bits); |
| 83 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, | 85 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, |
| 84 | struct chip_info *ci, u16 coreid); | 86 | struct chip_info *ci, u16 coreid, u32 core_bits); |
| 85 | }; | 87 | }; |
| 86 | 88 | ||
| 87 | struct sbconfig { | 89 | struct sbconfig { |
| @@ -124,6 +126,95 @@ struct sbconfig { | |||
| 124 | u32 sbidhigh; /* identification */ | 126 | u32 sbidhigh; /* identification */ |
| 125 | }; | 127 | }; |
| 126 | 128 | ||
| 129 | /* sdio core registers */ | ||
| 130 | struct sdpcmd_regs { | ||
| 131 | u32 corecontrol; /* 0x00, rev8 */ | ||
| 132 | u32 corestatus; /* rev8 */ | ||
| 133 | u32 PAD[1]; | ||
| 134 | u32 biststatus; /* rev8 */ | ||
| 135 | |||
| 136 | /* PCMCIA access */ | ||
| 137 | u16 pcmciamesportaladdr; /* 0x010, rev8 */ | ||
| 138 | u16 PAD[1]; | ||
| 139 | u16 pcmciamesportalmask; /* rev8 */ | ||
| 140 | u16 PAD[1]; | ||
| 141 | u16 pcmciawrframebc; /* rev8 */ | ||
| 142 | u16 PAD[1]; | ||
| 143 | u16 pcmciaunderflowtimer; /* rev8 */ | ||
| 144 | u16 PAD[1]; | ||
| 145 | |||
| 146 | /* interrupt */ | ||
| 147 | u32 intstatus; /* 0x020, rev8 */ | ||
| 148 | u32 hostintmask; /* rev8 */ | ||
| 149 | u32 intmask; /* rev8 */ | ||
| 150 | u32 sbintstatus; /* rev8 */ | ||
| 151 | u32 sbintmask; /* rev8 */ | ||
| 152 | u32 funcintmask; /* rev4 */ | ||
| 153 | u32 PAD[2]; | ||
| 154 | u32 tosbmailbox; /* 0x040, rev8 */ | ||
| 155 | u32 tohostmailbox; /* rev8 */ | ||
| 156 | u32 tosbmailboxdata; /* rev8 */ | ||
| 157 | u32 tohostmailboxdata; /* rev8 */ | ||
| 158 | |||
| 159 | /* synchronized access to registers in SDIO clock domain */ | ||
| 160 | u32 sdioaccess; /* 0x050, rev8 */ | ||
| 161 | u32 PAD[3]; | ||
| 162 | |||
| 163 | /* PCMCIA frame control */ | ||
| 164 | u8 pcmciaframectrl; /* 0x060, rev8 */ | ||
| 165 | u8 PAD[3]; | ||
| 166 | u8 pcmciawatermark; /* rev8 */ | ||
| 167 | u8 PAD[155]; | ||
| 168 | |||
| 169 | /* interrupt batching control */ | ||
| 170 | u32 intrcvlazy; /* 0x100, rev8 */ | ||
| 171 | u32 PAD[3]; | ||
| 172 | |||
| 173 | /* counters */ | ||
| 174 | u32 cmd52rd; /* 0x110, rev8 */ | ||
| 175 | u32 cmd52wr; /* rev8 */ | ||
| 176 | u32 cmd53rd; /* rev8 */ | ||
| 177 | u32 cmd53wr; /* rev8 */ | ||
| 178 | u32 abort; /* rev8 */ | ||
| 179 | u32 datacrcerror; /* rev8 */ | ||
| 180 | u32 rdoutofsync; /* rev8 */ | ||
| 181 | u32 wroutofsync; /* rev8 */ | ||
| 182 | u32 writebusy; /* rev8 */ | ||
| 183 | u32 readwait; /* rev8 */ | ||
| 184 | u32 readterm; /* rev8 */ | ||
| 185 | u32 writeterm; /* rev8 */ | ||
| 186 | u32 PAD[40]; | ||
| 187 | u32 clockctlstatus; /* rev8 */ | ||
| 188 | u32 PAD[7]; | ||
| 189 | |||
| 190 | u32 PAD[128]; /* DMA engines */ | ||
| 191 | |||
| 192 | /* SDIO/PCMCIA CIS region */ | ||
| 193 | char cis[512]; /* 0x400-0x5ff, rev6 */ | ||
| 194 | |||
| 195 | /* PCMCIA function control registers */ | ||
| 196 | char pcmciafcr[256]; /* 0x600-6ff, rev6 */ | ||
| 197 | u16 PAD[55]; | ||
| 198 | |||
| 199 | /* PCMCIA backplane access */ | ||
| 200 | u16 backplanecsr; /* 0x76E, rev6 */ | ||
| 201 | u16 backplaneaddr0; /* rev6 */ | ||
| 202 | u16 backplaneaddr1; /* rev6 */ | ||
| 203 | u16 backplaneaddr2; /* rev6 */ | ||
| 204 | u16 backplaneaddr3; /* rev6 */ | ||
| 205 | u16 backplanedata0; /* rev6 */ | ||
| 206 | u16 backplanedata1; /* rev6 */ | ||
| 207 | u16 backplanedata2; /* rev6 */ | ||
| 208 | u16 backplanedata3; /* rev6 */ | ||
| 209 | u16 PAD[31]; | ||
| 210 | |||
| 211 | /* sprom "size" & "blank" info */ | ||
| 212 | u16 spromstatus; /* 0x7BE, rev2 */ | ||
| 213 | u32 PAD[464]; | ||
| 214 | |||
| 215 | u16 PAD[0x80]; | ||
| 216 | }; | ||
| 217 | |||
| 127 | extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 218 | extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, |
| 128 | struct chip_info **ci_ptr, u32 regs); | 219 | struct chip_info **ci_ptr, u32 regs); |
| 129 | extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); | 220 | extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); |
| @@ -131,6 +222,10 @@ extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | |||
| 131 | struct chip_info *ci, | 222 | struct chip_info *ci, |
| 132 | u32 drivestrength); | 223 | u32 drivestrength); |
| 133 | extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); | 224 | extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); |
| 134 | 225 | extern void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, | |
| 226 | struct chip_info *ci); | ||
| 227 | extern bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, | ||
| 228 | struct chip_info *ci, char *nvram_dat, | ||
| 229 | uint nvram_sz); | ||
| 135 | 230 | ||
| 136 | #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ | 231 | #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 0d30afd8c672..7c1b6332747e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
| @@ -48,7 +48,13 @@ | |||
| 48 | #define SBSDIO_NUM_FUNCTION 3 | 48 | #define SBSDIO_NUM_FUNCTION 3 |
| 49 | 49 | ||
| 50 | /* function 0 vendor specific CCCR registers */ | 50 | /* function 0 vendor specific CCCR registers */ |
| 51 | #define SDIO_CCCR_BRCM_SEPINT 0xf2 | 51 | #define SDIO_CCCR_BRCM_CARDCAP 0xf0 |
| 52 | #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 | ||
| 53 | #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 | ||
| 54 | #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 | ||
| 55 | #define SDIO_CCCR_BRCM_CARDCTRL 0xf1 | ||
| 56 | #define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 | ||
| 57 | #define SDIO_CCCR_BRCM_SEPINT 0xf2 | ||
| 52 | 58 | ||
| 53 | #define SDIO_SEPINT_MASK 0x01 | 59 | #define SDIO_SEPINT_MASK 0x01 |
| 54 | #define SDIO_SEPINT_OE 0x02 | 60 | #define SDIO_SEPINT_OE 0x02 |
| @@ -97,9 +103,23 @@ | |||
| 97 | #define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B | 103 | #define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B |
| 98 | /* Read Frame Byte Count High */ | 104 | /* Read Frame Byte Count High */ |
| 99 | #define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C | 105 | #define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C |
| 106 | /* MesBusyCtl (rev 11) */ | ||
| 107 | #define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D | ||
| 108 | /* Sdio Core Rev 12 */ | ||
| 109 | #define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E | ||
| 110 | #define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 | ||
| 111 | #define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0 | ||
| 112 | #define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2 | ||
| 113 | #define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1 | ||
| 114 | #define SBSDIO_FUNC1_SLEEPCSR 0x1001F | ||
| 115 | #define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1 | ||
| 116 | #define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0 | ||
| 117 | #define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1 | ||
| 118 | #define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2 | ||
| 119 | #define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1 | ||
| 100 | 120 | ||
| 101 | #define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ | 121 | #define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ |
| 102 | #define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ | 122 | #define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001F /* f1 misc register end */ |
| 103 | 123 | ||
| 104 | /* function 1 OCP space */ | 124 | /* function 1 OCP space */ |
| 105 | 125 | ||
| @@ -154,13 +174,11 @@ struct brcmf_sdio_dev { | |||
| 154 | wait_queue_head_t request_buffer_wait; | 174 | wait_queue_head_t request_buffer_wait; |
| 155 | struct device *dev; | 175 | struct device *dev; |
| 156 | struct brcmf_bus *bus_if; | 176 | struct brcmf_bus *bus_if; |
| 157 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 177 | struct brcmfmac_sdio_platform_data *pdata; |
| 158 | unsigned int irq; /* oob interrupt number */ | 178 | bool oob_irq_requested; |
| 159 | unsigned long irq_flags; /* board specific oob flags */ | ||
| 160 | bool irq_en; /* irq enable flags */ | 179 | bool irq_en; /* irq enable flags */ |
| 161 | spinlock_t irq_en_lock; | 180 | spinlock_t irq_en_lock; |
| 162 | bool irq_wake; /* irq wake enable flags */ | 181 | bool irq_wake; /* irq wake enable flags */ |
| 163 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | ||
| 164 | }; | 182 | }; |
| 165 | 183 | ||
| 166 | /* Register/deregister interrupt handler. */ | 184 | /* Register/deregister interrupt handler. */ |
| @@ -224,6 +242,8 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
| 224 | */ | 242 | */ |
| 225 | extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, | 243 | extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, |
| 226 | u32 addr, u8 *buf, uint nbytes); | 244 | u32 addr, u8 *buf, uint nbytes); |
| 245 | extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, | ||
| 246 | u32 address, u8 *data, uint size); | ||
| 227 | 247 | ||
| 228 | /* Issue an abort to the specified function */ | 248 | /* Issue an abort to the specified function */ |
| 229 | extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); | 249 | extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index e4f1f3c9575a..6d758f285352 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "tracepoint.h" | 29 | #include "tracepoint.h" |
| 30 | #include "fwil_types.h" | 30 | #include "fwil_types.h" |
| 31 | #include "p2p.h" | 31 | #include "p2p.h" |
| 32 | #include "btcoex.h" | ||
| 32 | #include "wl_cfg80211.h" | 33 | #include "wl_cfg80211.h" |
| 33 | #include "fwil.h" | 34 | #include "fwil.h" |
| 34 | 35 | ||
| @@ -334,22 +335,16 @@ static u8 brcmf_mw_to_qdbm(u16 mw) | |||
| 334 | return qdbm; | 335 | return qdbm; |
| 335 | } | 336 | } |
| 336 | 337 | ||
| 337 | u16 channel_to_chanspec(struct ieee80211_channel *ch) | 338 | u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, |
| 339 | struct ieee80211_channel *ch) | ||
| 338 | { | 340 | { |
| 339 | u16 chanspec; | 341 | struct brcmu_chan ch_inf; |
| 340 | |||
| 341 | chanspec = ieee80211_frequency_to_channel(ch->center_freq); | ||
| 342 | chanspec &= WL_CHANSPEC_CHAN_MASK; | ||
| 343 | |||
| 344 | if (ch->band == IEEE80211_BAND_2GHZ) | ||
| 345 | chanspec |= WL_CHANSPEC_BAND_2G; | ||
| 346 | else | ||
| 347 | chanspec |= WL_CHANSPEC_BAND_5G; | ||
| 348 | 342 | ||
| 349 | chanspec |= WL_CHANSPEC_BW_20; | 343 | ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq); |
| 350 | chanspec |= WL_CHANSPEC_CTL_SB_NONE; | 344 | ch_inf.bw = BRCMU_CHAN_BW_20; |
| 345 | d11inf->encchspec(&ch_inf); | ||
| 351 | 346 | ||
| 352 | return chanspec; | 347 | return ch_inf.chspec; |
| 353 | } | 348 | } |
| 354 | 349 | ||
| 355 | /* Traverse a string of 1-byte tag/1-byte length/variable-length value | 350 | /* Traverse a string of 1-byte tag/1-byte length/variable-length value |
| @@ -680,7 +675,8 @@ done: | |||
| 680 | return err; | 675 | return err; |
| 681 | } | 676 | } |
| 682 | 677 | ||
| 683 | static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, | 678 | static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, |
| 679 | struct brcmf_scan_params_le *params_le, | ||
| 684 | struct cfg80211_scan_request *request) | 680 | struct cfg80211_scan_request *request) |
| 685 | { | 681 | { |
| 686 | u32 n_ssids; | 682 | u32 n_ssids; |
| @@ -712,7 +708,8 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, | |||
| 712 | n_channels); | 708 | n_channels); |
| 713 | if (n_channels > 0) { | 709 | if (n_channels > 0) { |
| 714 | for (i = 0; i < n_channels; i++) { | 710 | for (i = 0; i < n_channels; i++) { |
| 715 | chanspec = channel_to_chanspec(request->channels[i]); | 711 | chanspec = channel_to_chanspec(&cfg->d11inf, |
| 712 | request->channels[i]); | ||
| 716 | brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n", | 713 | brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n", |
| 717 | request->channels[i]->hw_value, chanspec); | 714 | request->channels[i]->hw_value, chanspec); |
| 718 | params_le->channel_list[i] = cpu_to_le16(chanspec); | 715 | params_le->channel_list[i] = cpu_to_le16(chanspec); |
| @@ -784,7 +781,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, | |||
| 784 | goto exit; | 781 | goto exit; |
| 785 | } | 782 | } |
| 786 | BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN); | 783 | BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN); |
| 787 | brcmf_escan_prep(¶ms->params_le, request); | 784 | brcmf_escan_prep(cfg, ¶ms->params_le, request); |
| 788 | params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); | 785 | params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); |
| 789 | params->action = cpu_to_le16(action); | 786 | params->action = cpu_to_le16(action); |
| 790 | params->sync_id = cpu_to_le16(0x1234); | 787 | params->sync_id = cpu_to_le16(0x1234); |
| @@ -860,6 +857,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, | |||
| 860 | cfg->scan_status); | 857 | cfg->scan_status); |
| 861 | return -EAGAIN; | 858 | return -EAGAIN; |
| 862 | } | 859 | } |
| 860 | if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { | ||
| 861 | brcmf_err("Scanning suppressed: status (%lu)\n", | ||
| 862 | cfg->scan_status); | ||
| 863 | return -EAGAIN; | ||
| 864 | } | ||
| 863 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { | 865 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { |
| 864 | brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); | 866 | brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); |
| 865 | return -EAGAIN; | 867 | return -EAGAIN; |
| @@ -1050,6 +1052,7 @@ static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) | |||
| 1050 | 1052 | ||
| 1051 | static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) | 1053 | static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) |
| 1052 | { | 1054 | { |
| 1055 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); | ||
| 1053 | s32 err = 0; | 1056 | s32 err = 0; |
| 1054 | 1057 | ||
| 1055 | brcmf_dbg(TRACE, "Enter\n"); | 1058 | brcmf_dbg(TRACE, "Enter\n"); |
| @@ -1063,6 +1066,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) | |||
| 1063 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); | 1066 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); |
| 1064 | } | 1067 | } |
| 1065 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); | 1068 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); |
| 1069 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | ||
| 1070 | brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); | ||
| 1066 | brcmf_dbg(TRACE, "Exit\n"); | 1071 | brcmf_dbg(TRACE, "Exit\n"); |
| 1067 | } | 1072 | } |
| 1068 | 1073 | ||
| @@ -1182,7 +1187,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
| 1182 | params->chandef.chan->center_freq); | 1187 | params->chandef.chan->center_freq); |
| 1183 | if (params->channel_fixed) { | 1188 | if (params->channel_fixed) { |
| 1184 | /* adding chanspec */ | 1189 | /* adding chanspec */ |
| 1185 | chanspec = channel_to_chanspec(params->chandef.chan); | 1190 | chanspec = channel_to_chanspec(&cfg->d11inf, |
| 1191 | params->chandef.chan); | ||
| 1186 | join_params.params_le.chanspec_list[0] = | 1192 | join_params.params_le.chanspec_list[0] = |
| 1187 | cpu_to_le16(chanspec); | 1193 | cpu_to_le16(chanspec); |
| 1188 | join_params.params_le.chanspec_num = cpu_to_le32(1); | 1194 | join_params.params_le.chanspec_num = cpu_to_le32(1); |
| @@ -1572,7 +1578,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, | |||
| 1572 | if (chan) { | 1578 | if (chan) { |
| 1573 | cfg->channel = | 1579 | cfg->channel = |
| 1574 | ieee80211_frequency_to_channel(chan->center_freq); | 1580 | ieee80211_frequency_to_channel(chan->center_freq); |
| 1575 | chanspec = channel_to_chanspec(chan); | 1581 | chanspec = channel_to_chanspec(&cfg->d11inf, chan); |
| 1576 | brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n", | 1582 | brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n", |
| 1577 | cfg->channel, chan->center_freq, chanspec); | 1583 | cfg->channel, chan->center_freq, chanspec); |
| 1578 | } else { | 1584 | } else { |
| @@ -2231,6 +2237,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, | |||
| 2231 | struct ieee80211_channel *notify_channel; | 2237 | struct ieee80211_channel *notify_channel; |
| 2232 | struct cfg80211_bss *bss; | 2238 | struct cfg80211_bss *bss; |
| 2233 | struct ieee80211_supported_band *band; | 2239 | struct ieee80211_supported_band *band; |
| 2240 | struct brcmu_chan ch; | ||
| 2234 | s32 err = 0; | 2241 | s32 err = 0; |
| 2235 | u16 channel; | 2242 | u16 channel; |
| 2236 | u32 freq; | 2243 | u32 freq; |
| @@ -2245,8 +2252,12 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, | |||
| 2245 | return 0; | 2252 | return 0; |
| 2246 | } | 2253 | } |
| 2247 | 2254 | ||
| 2248 | channel = bi->ctl_ch ? bi->ctl_ch : | 2255 | if (!bi->ctl_ch) { |
| 2249 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 2256 | ch.chspec = le16_to_cpu(bi->chanspec); |
| 2257 | cfg->d11inf.decchspec(&ch); | ||
| 2258 | bi->ctl_ch = ch.chnum; | ||
| 2259 | } | ||
| 2260 | channel = bi->ctl_ch; | ||
| 2250 | 2261 | ||
| 2251 | if (channel <= CH_MAX_2G_CHANNEL) | 2262 | if (channel <= CH_MAX_2G_CHANNEL) |
| 2252 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; | 2263 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; |
| @@ -2321,9 +2332,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, | |||
| 2321 | struct brcmf_bss_info_le *bi = NULL; | 2332 | struct brcmf_bss_info_le *bi = NULL; |
| 2322 | struct ieee80211_supported_band *band; | 2333 | struct ieee80211_supported_band *band; |
| 2323 | struct cfg80211_bss *bss; | 2334 | struct cfg80211_bss *bss; |
| 2335 | struct brcmu_chan ch; | ||
| 2324 | u8 *buf = NULL; | 2336 | u8 *buf = NULL; |
| 2325 | s32 err = 0; | 2337 | s32 err = 0; |
| 2326 | u16 channel; | ||
| 2327 | u32 freq; | 2338 | u32 freq; |
| 2328 | u16 notify_capability; | 2339 | u16 notify_capability; |
| 2329 | u16 notify_interval; | 2340 | u16 notify_interval; |
| @@ -2350,15 +2361,15 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, | |||
| 2350 | 2361 | ||
| 2351 | bi = (struct brcmf_bss_info_le *)(buf + 4); | 2362 | bi = (struct brcmf_bss_info_le *)(buf + 4); |
| 2352 | 2363 | ||
| 2353 | channel = bi->ctl_ch ? bi->ctl_ch : | 2364 | ch.chspec = le16_to_cpu(bi->chanspec); |
| 2354 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 2365 | cfg->d11inf.decchspec(&ch); |
| 2355 | 2366 | ||
| 2356 | if (channel <= CH_MAX_2G_CHANNEL) | 2367 | if (ch.band == BRCMU_CHAN_BAND_2G) |
| 2357 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; | 2368 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; |
| 2358 | else | 2369 | else |
| 2359 | band = wiphy->bands[IEEE80211_BAND_5GHZ]; | 2370 | band = wiphy->bands[IEEE80211_BAND_5GHZ]; |
| 2360 | 2371 | ||
| 2361 | freq = ieee80211_channel_to_frequency(channel, band->band); | 2372 | freq = ieee80211_channel_to_frequency(ch.chnum, band->band); |
| 2362 | notify_channel = ieee80211_get_channel(wiphy, freq); | 2373 | notify_channel = ieee80211_get_channel(wiphy, freq); |
| 2363 | 2374 | ||
| 2364 | notify_capability = le16_to_cpu(bi->capability); | 2375 | notify_capability = le16_to_cpu(bi->capability); |
| @@ -2367,7 +2378,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, | |||
| 2367 | notify_ielen = le32_to_cpu(bi->ie_length); | 2378 | notify_ielen = le32_to_cpu(bi->ie_length); |
| 2368 | notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; | 2379 | notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; |
| 2369 | 2380 | ||
| 2370 | brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq); | 2381 | brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq); |
| 2371 | brcmf_dbg(CONN, "capability: %X\n", notify_capability); | 2382 | brcmf_dbg(CONN, "capability: %X\n", notify_capability); |
| 2372 | brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); | 2383 | brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); |
| 2373 | brcmf_dbg(CONN, "signal: %d\n", notify_signal); | 2384 | brcmf_dbg(CONN, "signal: %d\n", notify_signal); |
| @@ -2490,12 +2501,19 @@ static void brcmf_escan_timeout(unsigned long data) | |||
| 2490 | } | 2501 | } |
| 2491 | 2502 | ||
| 2492 | static s32 | 2503 | static s32 |
| 2493 | brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, | 2504 | brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg, |
| 2505 | struct brcmf_bss_info_le *bss, | ||
| 2494 | struct brcmf_bss_info_le *bss_info_le) | 2506 | struct brcmf_bss_info_le *bss_info_le) |
| 2495 | { | 2507 | { |
| 2508 | struct brcmu_chan ch_bss, ch_bss_info_le; | ||
| 2509 | |||
| 2510 | ch_bss.chspec = le16_to_cpu(bss->chanspec); | ||
| 2511 | cfg->d11inf.decchspec(&ch_bss); | ||
| 2512 | ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec); | ||
| 2513 | cfg->d11inf.decchspec(&ch_bss_info_le); | ||
| 2514 | |||
| 2496 | if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) && | 2515 | if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) && |
| 2497 | (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) == | 2516 | ch_bss.band == ch_bss_info_le.band && |
| 2498 | CHSPEC_BAND(le16_to_cpu(bss->chanspec))) && | ||
| 2499 | bss_info_le->SSID_len == bss->SSID_len && | 2517 | bss_info_le->SSID_len == bss->SSID_len && |
| 2500 | !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { | 2518 | !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { |
| 2501 | if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == | 2519 | if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == |
| @@ -2593,7 +2611,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, | |||
| 2593 | bss = bss ? (struct brcmf_bss_info_le *) | 2611 | bss = bss ? (struct brcmf_bss_info_le *) |
| 2594 | ((unsigned char *)bss + | 2612 | ((unsigned char *)bss + |
| 2595 | le32_to_cpu(bss->length)) : list->bss_info_le; | 2613 | le32_to_cpu(bss->length)) : list->bss_info_le; |
| 2596 | if (brcmf_compare_update_same_bss(bss, bss_info_le)) | 2614 | if (brcmf_compare_update_same_bss(cfg, bss, |
| 2615 | bss_info_le)) | ||
| 2597 | goto exit; | 2616 | goto exit; |
| 2598 | } | 2617 | } |
| 2599 | memcpy(&(cfg->escan_info.escan_buf[list->buflen]), | 2618 | memcpy(&(cfg->escan_info.escan_buf[list->buflen]), |
| @@ -3007,6 +3026,11 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, | |||
| 3007 | brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); | 3026 | brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); |
| 3008 | return -EAGAIN; | 3027 | return -EAGAIN; |
| 3009 | } | 3028 | } |
| 3029 | if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { | ||
| 3030 | brcmf_err("Scanning suppressed: status (%lu)\n", | ||
| 3031 | cfg->scan_status); | ||
| 3032 | return -EAGAIN; | ||
| 3033 | } | ||
| 3010 | 3034 | ||
| 3011 | if (!request->n_ssids || !request->n_match_sets) { | 3035 | if (!request->n_ssids || !request->n_match_sets) { |
| 3012 | brcmf_err("Invalid sched scan req!! n_ssids:%d\n", | 3036 | brcmf_err("Invalid sched scan req!! n_ssids:%d\n", |
| @@ -3993,6 +4017,39 @@ exit: | |||
| 3993 | return err; | 4017 | return err; |
| 3994 | } | 4018 | } |
| 3995 | 4019 | ||
| 4020 | static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, | ||
| 4021 | struct wireless_dev *wdev, | ||
| 4022 | enum nl80211_crit_proto_id proto, | ||
| 4023 | u16 duration) | ||
| 4024 | { | ||
| 4025 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
| 4026 | struct brcmf_cfg80211_vif *vif; | ||
| 4027 | |||
| 4028 | vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); | ||
| 4029 | |||
| 4030 | /* only DHCP support for now */ | ||
| 4031 | if (proto != NL80211_CRIT_PROTO_DHCP) | ||
| 4032 | return -EINVAL; | ||
| 4033 | |||
| 4034 | /* suppress and abort scanning */ | ||
| 4035 | set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | ||
| 4036 | brcmf_abort_scanning(cfg); | ||
| 4037 | |||
| 4038 | return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration); | ||
| 4039 | } | ||
| 4040 | |||
| 4041 | static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy, | ||
| 4042 | struct wireless_dev *wdev) | ||
| 4043 | { | ||
| 4044 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
| 4045 | struct brcmf_cfg80211_vif *vif; | ||
| 4046 | |||
| 4047 | vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); | ||
| 4048 | |||
| 4049 | brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); | ||
| 4050 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | ||
| 4051 | } | ||
| 4052 | |||
| 3996 | static struct cfg80211_ops wl_cfg80211_ops = { | 4053 | static struct cfg80211_ops wl_cfg80211_ops = { |
| 3997 | .add_virtual_intf = brcmf_cfg80211_add_iface, | 4054 | .add_virtual_intf = brcmf_cfg80211_add_iface, |
| 3998 | .del_virtual_intf = brcmf_cfg80211_del_iface, | 4055 | .del_virtual_intf = brcmf_cfg80211_del_iface, |
| @@ -4029,6 +4086,8 @@ static struct cfg80211_ops wl_cfg80211_ops = { | |||
| 4029 | .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, | 4086 | .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, |
| 4030 | .start_p2p_device = brcmf_p2p_start_device, | 4087 | .start_p2p_device = brcmf_p2p_start_device, |
| 4031 | .stop_p2p_device = brcmf_p2p_stop_device, | 4088 | .stop_p2p_device = brcmf_p2p_stop_device, |
| 4089 | .crit_proto_start = brcmf_cfg80211_crit_proto_start, | ||
| 4090 | .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, | ||
| 4032 | #ifdef CONFIG_NL80211_TESTMODE | 4091 | #ifdef CONFIG_NL80211_TESTMODE |
| 4033 | .testmode_cmd = brcmf_cfg80211_testmode | 4092 | .testmode_cmd = brcmf_cfg80211_testmode |
| 4034 | #endif | 4093 | #endif |
| @@ -4337,9 +4396,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4337 | struct ieee80211_channel *notify_channel = NULL; | 4396 | struct ieee80211_channel *notify_channel = NULL; |
| 4338 | struct ieee80211_supported_band *band; | 4397 | struct ieee80211_supported_band *band; |
| 4339 | struct brcmf_bss_info_le *bi; | 4398 | struct brcmf_bss_info_le *bi; |
| 4399 | struct brcmu_chan ch; | ||
| 4340 | u32 freq; | 4400 | u32 freq; |
| 4341 | s32 err = 0; | 4401 | s32 err = 0; |
| 4342 | u32 target_channel; | ||
| 4343 | u8 *buf; | 4402 | u8 *buf; |
| 4344 | 4403 | ||
| 4345 | brcmf_dbg(TRACE, "Enter\n"); | 4404 | brcmf_dbg(TRACE, "Enter\n"); |
| @@ -4363,15 +4422,15 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, | |||
| 4363 | goto done; | 4422 | goto done; |
| 4364 | 4423 | ||
| 4365 | bi = (struct brcmf_bss_info_le *)(buf + 4); | 4424 | bi = (struct brcmf_bss_info_le *)(buf + 4); |
| 4366 | target_channel = bi->ctl_ch ? bi->ctl_ch : | 4425 | ch.chspec = le16_to_cpu(bi->chanspec); |
| 4367 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 4426 | cfg->d11inf.decchspec(&ch); |
| 4368 | 4427 | ||
| 4369 | if (target_channel <= CH_MAX_2G_CHANNEL) | 4428 | if (ch.band == BRCMU_CHAN_BAND_2G) |
| 4370 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; | 4429 | band = wiphy->bands[IEEE80211_BAND_2GHZ]; |
| 4371 | else | 4430 | else |
| 4372 | band = wiphy->bands[IEEE80211_BAND_5GHZ]; | 4431 | band = wiphy->bands[IEEE80211_BAND_5GHZ]; |
| 4373 | 4432 | ||
| 4374 | freq = ieee80211_channel_to_frequency(target_channel, band->band); | 4433 | freq = ieee80211_channel_to_frequency(ch.chnum, band->band); |
| 4375 | notify_channel = ieee80211_get_channel(wiphy, freq); | 4434 | notify_channel = ieee80211_get_channel(wiphy, freq); |
| 4376 | 4435 | ||
| 4377 | done: | 4436 | done: |
| @@ -4725,6 +4784,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
| 4725 | struct brcmf_cfg80211_vif *vif; | 4784 | struct brcmf_cfg80211_vif *vif; |
| 4726 | struct brcmf_if *ifp; | 4785 | struct brcmf_if *ifp; |
| 4727 | s32 err = 0; | 4786 | s32 err = 0; |
| 4787 | s32 io_type; | ||
| 4728 | 4788 | ||
| 4729 | if (!ndev) { | 4789 | if (!ndev) { |
| 4730 | brcmf_err("ndev is invalid\n"); | 4790 | brcmf_err("ndev is invalid\n"); |
| @@ -4765,6 +4825,21 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
| 4765 | brcmf_err("P2P initilisation failed (%d)\n", err); | 4825 | brcmf_err("P2P initilisation failed (%d)\n", err); |
| 4766 | goto cfg80211_p2p_attach_out; | 4826 | goto cfg80211_p2p_attach_out; |
| 4767 | } | 4827 | } |
| 4828 | err = brcmf_btcoex_attach(cfg); | ||
| 4829 | if (err) { | ||
| 4830 | brcmf_err("BT-coex initialisation failed (%d)\n", err); | ||
| 4831 | brcmf_p2p_detach(&cfg->p2p); | ||
| 4832 | goto cfg80211_p2p_attach_out; | ||
| 4833 | } | ||
| 4834 | |||
| 4835 | err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, | ||
| 4836 | &io_type); | ||
| 4837 | if (err) { | ||
| 4838 | brcmf_err("Failed to get D11 version (%d)\n", err); | ||
| 4839 | goto cfg80211_p2p_attach_out; | ||
| 4840 | } | ||
| 4841 | cfg->d11inf.io_type = (u8)io_type; | ||
| 4842 | brcmu_d11_attach(&cfg->d11inf); | ||
| 4768 | 4843 | ||
| 4769 | return cfg; | 4844 | return cfg; |
| 4770 | 4845 | ||
| @@ -4783,6 +4858,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | |||
| 4783 | struct brcmf_cfg80211_vif *tmp; | 4858 | struct brcmf_cfg80211_vif *tmp; |
| 4784 | 4859 | ||
| 4785 | wl_deinit_priv(cfg); | 4860 | wl_deinit_priv(cfg); |
| 4861 | brcmf_btcoex_detach(cfg); | ||
| 4786 | list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { | 4862 | list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { |
| 4787 | brcmf_free_vif(vif); | 4863 | brcmf_free_vif(vif); |
| 4788 | } | 4864 | } |
| @@ -4885,11 +4961,11 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
| 4885 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 4961 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
| 4886 | struct ieee80211_channel *band_chan_arr; | 4962 | struct ieee80211_channel *band_chan_arr; |
| 4887 | struct brcmf_chanspec_list *list; | 4963 | struct brcmf_chanspec_list *list; |
| 4964 | struct brcmu_chan ch; | ||
| 4888 | s32 err; | 4965 | s32 err; |
| 4889 | u8 *pbuf; | 4966 | u8 *pbuf; |
| 4890 | u32 i, j; | 4967 | u32 i, j; |
| 4891 | u32 total; | 4968 | u32 total; |
| 4892 | u16 chanspec; | ||
| 4893 | enum ieee80211_band band; | 4969 | enum ieee80211_band band; |
| 4894 | u32 channel; | 4970 | u32 channel; |
| 4895 | u32 *n_cnt; | 4971 | u32 *n_cnt; |
| @@ -4918,42 +4994,30 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
| 4918 | 4994 | ||
| 4919 | total = le32_to_cpu(list->count); | 4995 | total = le32_to_cpu(list->count); |
| 4920 | for (i = 0; i < total; i++) { | 4996 | for (i = 0; i < total; i++) { |
| 4921 | chanspec = (u16)le32_to_cpu(list->element[i]); | 4997 | ch.chspec = (u16)le32_to_cpu(list->element[i]); |
| 4922 | channel = CHSPEC_CHANNEL(chanspec); | 4998 | cfg->d11inf.decchspec(&ch); |
| 4923 | 4999 | ||
| 4924 | if (CHSPEC_IS40(chanspec)) { | 5000 | if (ch.band == BRCMU_CHAN_BAND_2G) { |
| 4925 | if (CHSPEC_SB_UPPER(chanspec)) | ||
| 4926 | channel += CH_10MHZ_APART; | ||
| 4927 | else | ||
| 4928 | channel -= CH_10MHZ_APART; | ||
| 4929 | } else if (CHSPEC_IS80(chanspec)) { | ||
| 4930 | brcmf_dbg(INFO, "HT80 center channel : %d\n", | ||
| 4931 | channel); | ||
| 4932 | continue; | ||
| 4933 | } | ||
| 4934 | if (CHSPEC_IS2G(chanspec) && (channel >= CH_MIN_2G_CHANNEL) && | ||
| 4935 | (channel <= CH_MAX_2G_CHANNEL)) { | ||
| 4936 | band_chan_arr = __wl_2ghz_channels; | 5001 | band_chan_arr = __wl_2ghz_channels; |
| 4937 | array_size = ARRAY_SIZE(__wl_2ghz_channels); | 5002 | array_size = ARRAY_SIZE(__wl_2ghz_channels); |
| 4938 | n_cnt = &__wl_band_2ghz.n_channels; | 5003 | n_cnt = &__wl_band_2ghz.n_channels; |
| 4939 | band = IEEE80211_BAND_2GHZ; | 5004 | band = IEEE80211_BAND_2GHZ; |
| 4940 | ht40_allowed = (bw_cap == WLC_N_BW_40ALL); | 5005 | ht40_allowed = (bw_cap == WLC_N_BW_40ALL); |
| 4941 | } else if (CHSPEC_IS5G(chanspec) && | 5006 | } else if (ch.band == BRCMU_CHAN_BAND_5G) { |
| 4942 | channel >= CH_MIN_5G_CHANNEL) { | ||
| 4943 | band_chan_arr = __wl_5ghz_a_channels; | 5007 | band_chan_arr = __wl_5ghz_a_channels; |
| 4944 | array_size = ARRAY_SIZE(__wl_5ghz_a_channels); | 5008 | array_size = ARRAY_SIZE(__wl_5ghz_a_channels); |
| 4945 | n_cnt = &__wl_band_5ghz_a.n_channels; | 5009 | n_cnt = &__wl_band_5ghz_a.n_channels; |
| 4946 | band = IEEE80211_BAND_5GHZ; | 5010 | band = IEEE80211_BAND_5GHZ; |
| 4947 | ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); | 5011 | ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); |
| 4948 | } else { | 5012 | } else { |
| 4949 | brcmf_err("Invalid channel Sepc. 0x%x.\n", chanspec); | 5013 | brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec); |
| 4950 | continue; | 5014 | continue; |
| 4951 | } | 5015 | } |
| 4952 | if (!ht40_allowed && CHSPEC_IS40(chanspec)) | 5016 | if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40) |
| 4953 | continue; | 5017 | continue; |
| 4954 | update = false; | 5018 | update = false; |
| 4955 | for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { | 5019 | for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { |
| 4956 | if (band_chan_arr[j].hw_value == channel) { | 5020 | if (band_chan_arr[j].hw_value == ch.chnum) { |
| 4957 | update = true; | 5021 | update = true; |
| 4958 | break; | 5022 | break; |
| 4959 | } | 5023 | } |
| @@ -4964,16 +5028,16 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
| 4964 | index = *n_cnt; | 5028 | index = *n_cnt; |
| 4965 | if (index < array_size) { | 5029 | if (index < array_size) { |
| 4966 | band_chan_arr[index].center_freq = | 5030 | band_chan_arr[index].center_freq = |
| 4967 | ieee80211_channel_to_frequency(channel, band); | 5031 | ieee80211_channel_to_frequency(ch.chnum, band); |
| 4968 | band_chan_arr[index].hw_value = channel; | 5032 | band_chan_arr[index].hw_value = ch.chnum; |
| 4969 | 5033 | ||
| 4970 | if (CHSPEC_IS40(chanspec) && ht40_allowed) { | 5034 | if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) { |
| 4971 | /* assuming the order is HT20, HT40 Upper, | 5035 | /* assuming the order is HT20, HT40 Upper, |
| 4972 | * HT40 lower from chanspecs | 5036 | * HT40 lower from chanspecs |
| 4973 | */ | 5037 | */ |
| 4974 | ht40_flag = band_chan_arr[index].flags & | 5038 | ht40_flag = band_chan_arr[index].flags & |
| 4975 | IEEE80211_CHAN_NO_HT40; | 5039 | IEEE80211_CHAN_NO_HT40; |
| 4976 | if (CHSPEC_SB_UPPER(chanspec)) { | 5040 | if (ch.sb == BRCMU_CHAN_SB_U) { |
| 4977 | if (ht40_flag == IEEE80211_CHAN_NO_HT40) | 5041 | if (ht40_flag == IEEE80211_CHAN_NO_HT40) |
| 4978 | band_chan_arr[index].flags &= | 5042 | band_chan_arr[index].flags &= |
| 4979 | ~IEEE80211_CHAN_NO_HT40; | 5043 | ~IEEE80211_CHAN_NO_HT40; |
| @@ -4993,11 +5057,9 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
| 4993 | } else { | 5057 | } else { |
| 4994 | band_chan_arr[index].flags = | 5058 | band_chan_arr[index].flags = |
| 4995 | IEEE80211_CHAN_NO_HT40; | 5059 | IEEE80211_CHAN_NO_HT40; |
| 4996 | if (band == IEEE80211_BAND_2GHZ) | 5060 | ch.bw = BRCMU_CHAN_BW_20; |
| 4997 | channel |= WL_CHANSPEC_BAND_2G; | 5061 | cfg->d11inf.encchspec(&ch); |
| 4998 | else | 5062 | channel = ch.chspec; |
| 4999 | channel |= WL_CHANSPEC_BAND_5G; | ||
| 5000 | channel |= WL_CHANSPEC_BW_20; | ||
| 5001 | err = brcmf_fil_bsscfg_int_get(ifp, | 5063 | err = brcmf_fil_bsscfg_int_get(ifp, |
| 5002 | "per_chan_info", | 5064 | "per_chan_info", |
| 5003 | &channel); | 5065 | &channel); |
| @@ -5226,6 +5288,13 @@ s32 brcmf_cfg80211_down(struct net_device *ndev) | |||
| 5226 | return err; | 5288 | return err; |
| 5227 | } | 5289 | } |
| 5228 | 5290 | ||
| 5291 | enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp) | ||
| 5292 | { | ||
| 5293 | struct wireless_dev *wdev = &ifp->vif->wdev; | ||
| 5294 | |||
| 5295 | return wdev->iftype; | ||
| 5296 | } | ||
| 5297 | |||
| 5229 | u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state) | 5298 | u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state) |
| 5230 | { | 5299 | { |
| 5231 | struct brcmf_cfg80211_vif *vif; | 5300 | struct brcmf_cfg80211_vif *vif; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 2907437ef438..a71cff84cdcf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
| @@ -17,6 +17,9 @@ | |||
| 17 | #ifndef _wl_cfg80211_h_ | 17 | #ifndef _wl_cfg80211_h_ |
| 18 | #define _wl_cfg80211_h_ | 18 | #define _wl_cfg80211_h_ |
| 19 | 19 | ||
| 20 | /* for brcmu_d11inf */ | ||
| 21 | #include <brcmu_d11.h> | ||
| 22 | |||
| 20 | #define WL_NUM_SCAN_MAX 10 | 23 | #define WL_NUM_SCAN_MAX 10 |
| 21 | #define WL_NUM_PMKIDS_MAX MAXPMKID | 24 | #define WL_NUM_PMKIDS_MAX MAXPMKID |
| 22 | #define WL_TLV_INFO_MAX 1024 | 25 | #define WL_TLV_INFO_MAX 1024 |
| @@ -74,14 +77,16 @@ | |||
| 74 | 77 | ||
| 75 | 78 | ||
| 76 | /** | 79 | /** |
| 77 | * enum brcmf_scan_status - dongle scan status | 80 | * enum brcmf_scan_status - scan engine status |
| 78 | * | 81 | * |
| 79 | * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle. | 82 | * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle. |
| 80 | * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle. | 83 | * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle. |
| 84 | * @BRCMF_SCAN_STATUS_SUPPRESS: scanning is suppressed in driver. | ||
| 81 | */ | 85 | */ |
| 82 | enum brcmf_scan_status { | 86 | enum brcmf_scan_status { |
| 83 | BRCMF_SCAN_STATUS_BUSY, | 87 | BRCMF_SCAN_STATUS_BUSY, |
| 84 | BRCMF_SCAN_STATUS_ABORT, | 88 | BRCMF_SCAN_STATUS_ABORT, |
| 89 | BRCMF_SCAN_STATUS_SUPPRESS, | ||
| 85 | }; | 90 | }; |
| 86 | 91 | ||
| 87 | /** | 92 | /** |
| @@ -346,6 +351,7 @@ struct brcmf_cfg80211_vif_event { | |||
| 346 | * @wiphy: wiphy object for cfg80211 interface. | 351 | * @wiphy: wiphy object for cfg80211 interface. |
| 347 | * @conf: dongle configuration. | 352 | * @conf: dongle configuration. |
| 348 | * @p2p: peer-to-peer specific information. | 353 | * @p2p: peer-to-peer specific information. |
| 354 | * @btcoex: Bluetooth coexistence information. | ||
| 349 | * @scan_request: cfg80211 scan request object. | 355 | * @scan_request: cfg80211 scan request object. |
| 350 | * @usr_sync: mainly for dongle up/down synchronization. | 356 | * @usr_sync: mainly for dongle up/down synchronization. |
| 351 | * @bss_list: bss_list holding scanned ap information. | 357 | * @bss_list: bss_list holding scanned ap information. |
| @@ -379,6 +385,7 @@ struct brcmf_cfg80211_info { | |||
| 379 | struct wiphy *wiphy; | 385 | struct wiphy *wiphy; |
| 380 | struct brcmf_cfg80211_conf *conf; | 386 | struct brcmf_cfg80211_conf *conf; |
| 381 | struct brcmf_p2p_info p2p; | 387 | struct brcmf_p2p_info p2p; |
| 388 | struct brcmf_btcoex_info *btcoex; | ||
| 382 | struct cfg80211_scan_request *scan_request; | 389 | struct cfg80211_scan_request *scan_request; |
| 383 | struct mutex usr_sync; | 390 | struct mutex usr_sync; |
| 384 | struct brcmf_scan_results *bss_list; | 391 | struct brcmf_scan_results *bss_list; |
| @@ -408,6 +415,7 @@ struct brcmf_cfg80211_info { | |||
| 408 | u8 vif_cnt; | 415 | u8 vif_cnt; |
| 409 | struct brcmf_cfg80211_vif_event vif_event; | 416 | struct brcmf_cfg80211_vif_event vif_event; |
| 410 | struct completion vif_disabled; | 417 | struct completion vif_disabled; |
| 418 | struct brcmu_d11inf d11inf; | ||
| 411 | }; | 419 | }; |
| 412 | 420 | ||
| 413 | /** | 421 | /** |
| @@ -474,6 +482,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, | |||
| 474 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | 482 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); |
| 475 | s32 brcmf_cfg80211_up(struct net_device *ndev); | 483 | s32 brcmf_cfg80211_up(struct net_device *ndev); |
| 476 | s32 brcmf_cfg80211_down(struct net_device *ndev); | 484 | s32 brcmf_cfg80211_down(struct net_device *ndev); |
| 485 | enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); | ||
| 477 | 486 | ||
| 478 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | 487 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, |
| 479 | enum nl80211_iftype type, | 488 | enum nl80211_iftype type, |
| @@ -484,7 +493,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, | |||
| 484 | const u8 *vndr_ie_buf, u32 vndr_ie_len); | 493 | const u8 *vndr_ie_buf, u32 vndr_ie_len); |
| 485 | s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); | 494 | s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); |
| 486 | struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key); | 495 | struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key); |
| 487 | u16 channel_to_chanspec(struct ieee80211_channel *ch); | 496 | u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, |
| 497 | struct ieee80211_channel *ch); | ||
| 488 | u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state); | 498 | u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state); |
| 489 | void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, | 499 | void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, |
| 490 | struct brcmf_cfg80211_vif *vif); | 500 | struct brcmf_cfg80211_vif *vif); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile index cba19d839b77..32464acccd90 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile | |||
| @@ -21,7 +21,7 @@ ccflags-y := \ | |||
| 21 | -Idrivers/net/wireless/brcm80211/brcmsmac/phy \ | 21 | -Idrivers/net/wireless/brcm80211/brcmsmac/phy \ |
| 22 | -Idrivers/net/wireless/brcm80211/include | 22 | -Idrivers/net/wireless/brcm80211/include |
| 23 | 23 | ||
| 24 | BRCMSMAC_OFILES := \ | 24 | brcmsmac-y := \ |
| 25 | mac80211_if.o \ | 25 | mac80211_if.o \ |
| 26 | ucode_loader.o \ | 26 | ucode_loader.o \ |
| 27 | ampdu.o \ | 27 | ampdu.o \ |
| @@ -43,11 +43,6 @@ BRCMSMAC_OFILES := \ | |||
| 43 | brcms_trace_events.o \ | 43 | brcms_trace_events.o \ |
| 44 | debug.o | 44 | debug.o |
| 45 | 45 | ||
| 46 | ifdef CONFIG_BCMA_DRIVER_GPIO | 46 | brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o |
| 47 | BRCMSMAC_OFILES += led.o | ||
| 48 | endif | ||
| 49 | 47 | ||
| 50 | MODULEPFX := brcmsmac | 48 | obj-$(CONFIG_BRCMSMAC) += brcmsmac.o |
| 51 | |||
| 52 | obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o | ||
| 53 | $(MODULEPFX)-objs = $(BRCMSMAC_OFILES) | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 10ee314c4229..cc87926f5055 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
| @@ -379,7 +379,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
| 379 | u8 local_constraint_qdbm) | 379 | u8 local_constraint_qdbm) |
| 380 | { | 380 | { |
| 381 | struct brcms_c_info *wlc = wlc_cm->wlc; | 381 | struct brcms_c_info *wlc = wlc_cm->wlc; |
| 382 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 382 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; |
| 383 | struct txpwr_limits txpwr; | 383 | struct txpwr_limits txpwr; |
| 384 | 384 | ||
| 385 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); | 385 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); |
| @@ -404,7 +404,7 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
| 404 | struct txpwr_limits *txpwr) | 404 | struct txpwr_limits *txpwr) |
| 405 | { | 405 | { |
| 406 | struct brcms_c_info *wlc = wlc_cm->wlc; | 406 | struct brcms_c_info *wlc = wlc_cm->wlc; |
| 407 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 407 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; |
| 408 | uint i; | 408 | uint i; |
| 409 | uint chan; | 409 | uint chan; |
| 410 | int maxpwr; | 410 | int maxpwr; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index c837be242cba..2346821667e6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
| @@ -556,10 +556,10 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
| 556 | new_int); | 556 | new_int); |
| 557 | } | 557 | } |
| 558 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 558 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 559 | if (conf->channel_type == NL80211_CHAN_HT20 || | 559 | if (conf->chandef.width == NL80211_CHAN_WIDTH_20 || |
| 560 | conf->channel_type == NL80211_CHAN_NO_HT) | 560 | conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) |
| 561 | err = brcms_c_set_channel(wl->wlc, | 561 | err = brcms_c_set_channel(wl->wlc, |
| 562 | conf->channel->hw_value); | 562 | conf->chandef.chan->hw_value); |
| 563 | else | 563 | else |
| 564 | err = -ENOTSUPP; | 564 | err = -ENOTSUPP; |
| 565 | } | 565 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 59d438409dfb..28e7aeedd184 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
| @@ -5135,7 +5135,7 @@ int brcms_c_up(struct brcms_c_info *wlc) | |||
| 5135 | wlc->pub->up = true; | 5135 | wlc->pub->up = true; |
| 5136 | 5136 | ||
| 5137 | if (wlc->bandinit_pending) { | 5137 | if (wlc->bandinit_pending) { |
| 5138 | ch = wlc->pub->ieee_hw->conf.channel; | 5138 | ch = wlc->pub->ieee_hw->conf.chandef.chan; |
| 5139 | brcms_c_suspend_mac_and_wait(wlc); | 5139 | brcms_c_suspend_mac_and_wait(wlc); |
| 5140 | brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); | 5140 | brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); |
| 5141 | wlc->bandinit_pending = false; | 5141 | wlc->bandinit_pending = false; |
| @@ -7919,7 +7919,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
| 7919 | void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | 7919 | void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) |
| 7920 | { | 7920 | { |
| 7921 | struct bcma_device *core = wlc->hw->d11core; | 7921 | struct bcma_device *core = wlc->hw->d11core; |
| 7922 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 7922 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; |
| 7923 | u16 chanspec; | 7923 | u16 chanspec; |
| 7924 | 7924 | ||
| 7925 | brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); | 7925 | brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); |
diff --git a/drivers/net/wireless/brcm80211/brcmutil/Makefile b/drivers/net/wireless/brcm80211/brcmutil/Makefile index 6281c416289e..8a928184016a 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/Makefile +++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile | |||
| @@ -19,10 +19,5 @@ ccflags-y := \ | |||
| 19 | -Idrivers/net/wireless/brcm80211/brcmutil \ | 19 | -Idrivers/net/wireless/brcm80211/brcmutil \ |
| 20 | -Idrivers/net/wireless/brcm80211/include | 20 | -Idrivers/net/wireless/brcm80211/include |
| 21 | 21 | ||
| 22 | BRCMUTIL_OFILES := \ | 22 | obj-$(CONFIG_BRCMUTIL) += brcmutil.o |
| 23 | utils.o | 23 | brcmutil-objs = utils.o d11.o |
| 24 | |||
| 25 | MODULEPFX := brcmutil | ||
| 26 | |||
| 27 | obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o | ||
| 28 | $(MODULEPFX)-objs = $(BRCMUTIL_OFILES) | ||
diff --git a/drivers/net/wireless/brcm80211/brcmutil/d11.c b/drivers/net/wireless/brcm80211/brcmutil/d11.c new file mode 100644 index 000000000000..30e54e2c6c9b --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmutil/d11.c | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | /*********************channel spec common functions*********************/ | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | |||
| 20 | #include <brcmu_utils.h> | ||
| 21 | #include <brcmu_wifi.h> | ||
| 22 | #include <brcmu_d11.h> | ||
| 23 | |||
| 24 | static void brcmu_d11n_encchspec(struct brcmu_chan *ch) | ||
| 25 | { | ||
| 26 | ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; | ||
| 27 | |||
| 28 | switch (ch->bw) { | ||
| 29 | case BRCMU_CHAN_BW_20: | ||
| 30 | ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N; | ||
| 31 | break; | ||
| 32 | case BRCMU_CHAN_BW_40: | ||
| 33 | default: | ||
| 34 | WARN_ON_ONCE(1); | ||
| 35 | break; | ||
| 36 | } | ||
| 37 | |||
| 38 | if (ch->chnum <= CH_MAX_2G_CHANNEL) | ||
| 39 | ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G; | ||
| 40 | else | ||
| 41 | ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G; | ||
| 42 | } | ||
| 43 | |||
| 44 | static void brcmu_d11ac_encchspec(struct brcmu_chan *ch) | ||
| 45 | { | ||
| 46 | ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; | ||
| 47 | |||
| 48 | switch (ch->bw) { | ||
| 49 | case BRCMU_CHAN_BW_20: | ||
| 50 | ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20; | ||
| 51 | break; | ||
| 52 | case BRCMU_CHAN_BW_40: | ||
| 53 | case BRCMU_CHAN_BW_80: | ||
| 54 | case BRCMU_CHAN_BW_80P80: | ||
| 55 | case BRCMU_CHAN_BW_160: | ||
| 56 | default: | ||
| 57 | WARN_ON_ONCE(1); | ||
| 58 | break; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (ch->chnum <= CH_MAX_2G_CHANNEL) | ||
| 62 | ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; | ||
| 63 | else | ||
| 64 | ch->chspec |= BRCMU_CHSPEC_D11AC_BND_5G; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void brcmu_d11n_decchspec(struct brcmu_chan *ch) | ||
| 68 | { | ||
| 69 | u16 val; | ||
| 70 | |||
| 71 | ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); | ||
| 72 | |||
| 73 | switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { | ||
| 74 | case BRCMU_CHSPEC_D11N_BW_20: | ||
| 75 | ch->bw = BRCMU_CHAN_BW_20; | ||
| 76 | break; | ||
| 77 | case BRCMU_CHSPEC_D11N_BW_40: | ||
| 78 | ch->bw = BRCMU_CHAN_BW_40; | ||
| 79 | val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK; | ||
| 80 | if (val == BRCMU_CHSPEC_D11N_SB_L) { | ||
| 81 | ch->sb = BRCMU_CHAN_SB_L; | ||
| 82 | ch->chnum -= CH_10MHZ_APART; | ||
| 83 | } else { | ||
| 84 | ch->sb = BRCMU_CHAN_SB_U; | ||
| 85 | ch->chnum += CH_10MHZ_APART; | ||
| 86 | } | ||
| 87 | break; | ||
| 88 | default: | ||
| 89 | WARN_ON_ONCE(1); | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | |||
| 93 | switch (ch->chspec & BRCMU_CHSPEC_D11N_BND_MASK) { | ||
| 94 | case BRCMU_CHSPEC_D11N_BND_5G: | ||
| 95 | ch->band = BRCMU_CHAN_BAND_5G; | ||
| 96 | break; | ||
| 97 | case BRCMU_CHSPEC_D11N_BND_2G: | ||
| 98 | ch->band = BRCMU_CHAN_BAND_2G; | ||
| 99 | break; | ||
| 100 | default: | ||
| 101 | WARN_ON_ONCE(1); | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) | ||
| 107 | { | ||
| 108 | u16 val; | ||
| 109 | |||
| 110 | ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); | ||
| 111 | |||
| 112 | switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { | ||
| 113 | case BRCMU_CHSPEC_D11AC_BW_20: | ||
| 114 | ch->bw = BRCMU_CHAN_BW_20; | ||
| 115 | break; | ||
| 116 | case BRCMU_CHSPEC_D11AC_BW_40: | ||
| 117 | ch->bw = BRCMU_CHAN_BW_40; | ||
| 118 | val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK; | ||
| 119 | if (val == BRCMU_CHSPEC_D11AC_SB_L) { | ||
| 120 | ch->sb = BRCMU_CHAN_SB_L; | ||
| 121 | ch->chnum -= CH_10MHZ_APART; | ||
| 122 | } else if (val == BRCMU_CHSPEC_D11AC_SB_U) { | ||
| 123 | ch->sb = BRCMU_CHAN_SB_U; | ||
| 124 | ch->chnum += CH_10MHZ_APART; | ||
| 125 | } else { | ||
| 126 | WARN_ON_ONCE(1); | ||
| 127 | } | ||
| 128 | break; | ||
| 129 | case BRCMU_CHSPEC_D11AC_BW_80: | ||
| 130 | ch->bw = BRCMU_CHAN_BW_80; | ||
| 131 | break; | ||
| 132 | case BRCMU_CHSPEC_D11AC_BW_8080: | ||
| 133 | case BRCMU_CHSPEC_D11AC_BW_160: | ||
| 134 | default: | ||
| 135 | WARN_ON_ONCE(1); | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | |||
| 139 | switch (ch->chspec & BRCMU_CHSPEC_D11AC_BND_MASK) { | ||
| 140 | case BRCMU_CHSPEC_D11AC_BND_5G: | ||
| 141 | ch->band = BRCMU_CHAN_BAND_5G; | ||
| 142 | break; | ||
| 143 | case BRCMU_CHSPEC_D11AC_BND_2G: | ||
| 144 | ch->band = BRCMU_CHAN_BAND_2G; | ||
| 145 | break; | ||
| 146 | default: | ||
| 147 | WARN_ON_ONCE(1); | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | void brcmu_d11_attach(struct brcmu_d11inf *d11inf) | ||
| 153 | { | ||
| 154 | if (d11inf->io_type == BRCMU_D11N_IOTYPE) { | ||
| 155 | d11inf->encchspec = brcmu_d11n_encchspec; | ||
| 156 | d11inf->decchspec = brcmu_d11n_decchspec; | ||
| 157 | } else { | ||
| 158 | d11inf->encchspec = brcmu_d11ac_encchspec; | ||
| 159 | d11inf->decchspec = brcmu_d11ac_decchspec; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | EXPORT_SYMBOL(brcmu_d11_attach); | ||
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index bf5e50fc21ba..0f7e1c7b6f58 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c | |||
| @@ -45,17 +45,9 @@ void brcmu_pkt_buf_free_skb(struct sk_buff *skb) | |||
| 45 | { | 45 | { |
| 46 | if (!skb) | 46 | if (!skb) |
| 47 | return; | 47 | return; |
| 48 | |||
| 48 | WARN_ON(skb->next); | 49 | WARN_ON(skb->next); |
| 49 | if (skb->destructor) | 50 | dev_kfree_skb_any(skb); |
| 50 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | ||
| 51 | * destructor exists | ||
| 52 | */ | ||
| 53 | dev_kfree_skb_any(skb); | ||
| 54 | else | ||
| 55 | /* can free immediately (even in_irq()) if destructor | ||
| 56 | * does not exist | ||
| 57 | */ | ||
| 58 | dev_kfree_skb(skb); | ||
| 59 | } | 51 | } |
| 60 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); | 52 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); |
| 61 | 53 | ||
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index e8682855b73a..c1fe245bb07e 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | /* Chipcommon Core Chip IDs */ | 30 | /* Chipcommon Core Chip IDs */ |
| 31 | #define BCM4313_CHIP_ID 0x4313 | 31 | #define BCM4313_CHIP_ID 0x4313 |
| 32 | #define BCM43143_CHIP_ID 43143 | ||
| 32 | #define BCM43224_CHIP_ID 43224 | 33 | #define BCM43224_CHIP_ID 43224 |
| 33 | #define BCM43225_CHIP_ID 43225 | 34 | #define BCM43225_CHIP_ID 43225 |
| 34 | #define BCM43235_CHIP_ID 43235 | 35 | #define BCM43235_CHIP_ID 43235 |
| @@ -39,5 +40,6 @@ | |||
| 39 | #define BCM4330_CHIP_ID 0x4330 | 40 | #define BCM4330_CHIP_ID 0x4330 |
| 40 | #define BCM4331_CHIP_ID 0x4331 | 41 | #define BCM4331_CHIP_ID 0x4331 |
| 41 | #define BCM4334_CHIP_ID 0x4334 | 42 | #define BCM4334_CHIP_ID 0x4334 |
| 43 | #define BCM4335_CHIP_ID 0x4335 | ||
| 42 | 44 | ||
| 43 | #endif /* _BRCM_HW_IDS_H_ */ | 45 | #endif /* _BRCM_HW_IDS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/brcm80211/include/brcmu_d11.h new file mode 100644 index 000000000000..92623f02b1c0 --- /dev/null +++ b/drivers/net/wireless/brcm80211/include/brcmu_d11.h | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2010 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _BRCMU_D11_H_ | ||
| 18 | #define _BRCMU_D11_H_ | ||
| 19 | |||
| 20 | /* d11 io type */ | ||
| 21 | #define BRCMU_D11N_IOTYPE 1 | ||
| 22 | #define BRCMU_D11AC_IOTYPE 2 | ||
| 23 | |||
| 24 | /* A chanspec (channel specification) holds the channel number, band, | ||
| 25 | * bandwidth and control sideband | ||
| 26 | */ | ||
| 27 | |||
| 28 | /* chanspec binary format */ | ||
| 29 | |||
| 30 | #define BRCMU_CHSPEC_INVALID 255 | ||
| 31 | /* bit 0~7 channel number | ||
| 32 | * for 80+80 channels: bit 0~3 low channel id, bit 4~7 high channel id | ||
| 33 | */ | ||
| 34 | #define BRCMU_CHSPEC_CH_MASK 0x00ff | ||
| 35 | #define BRCMU_CHSPEC_CH_SHIFT 0 | ||
| 36 | #define BRCMU_CHSPEC_CHL_MASK 0x000f | ||
| 37 | #define BRCMU_CHSPEC_CHL_SHIFT 0 | ||
| 38 | #define BRCMU_CHSPEC_CHH_MASK 0x00f0 | ||
| 39 | #define BRCMU_CHSPEC_CHH_SHIFT 4 | ||
| 40 | |||
| 41 | /* bit 8~16 for dot 11n IO types | ||
| 42 | * bit 8~9 sideband | ||
| 43 | * bit 10~11 bandwidth | ||
| 44 | * bit 12~13 spectral band | ||
| 45 | * bit 14~15 not used | ||
| 46 | */ | ||
| 47 | #define BRCMU_CHSPEC_D11N_SB_MASK 0x0300 | ||
| 48 | #define BRCMU_CHSPEC_D11N_SB_SHIFT 8 | ||
| 49 | #define BRCMU_CHSPEC_D11N_SB_L 0x0100 /* control lower */ | ||
| 50 | #define BRCMU_CHSPEC_D11N_SB_U 0x0200 /* control upper */ | ||
| 51 | #define BRCMU_CHSPEC_D11N_SB_N 0x0300 /* none */ | ||
| 52 | #define BRCMU_CHSPEC_D11N_BW_MASK 0x0c00 | ||
| 53 | #define BRCMU_CHSPEC_D11N_BW_SHIFT 10 | ||
| 54 | #define BRCMU_CHSPEC_D11N_BW_10 0x0400 | ||
| 55 | #define BRCMU_CHSPEC_D11N_BW_20 0x0800 | ||
| 56 | #define BRCMU_CHSPEC_D11N_BW_40 0x0c00 | ||
| 57 | #define BRCMU_CHSPEC_D11N_BND_MASK 0x3000 | ||
| 58 | #define BRCMU_CHSPEC_D11N_BND_SHIFT 12 | ||
| 59 | #define BRCMU_CHSPEC_D11N_BND_5G 0x1000 | ||
| 60 | #define BRCMU_CHSPEC_D11N_BND_2G 0x2000 | ||
| 61 | |||
| 62 | /* bit 8~16 for dot 11ac IO types | ||
| 63 | * bit 8~10 sideband | ||
| 64 | * bit 11~13 bandwidth | ||
| 65 | * bit 14~15 spectral band | ||
| 66 | */ | ||
| 67 | #define BRCMU_CHSPEC_D11AC_SB_MASK 0x0700 | ||
| 68 | #define BRCMU_CHSPEC_D11AC_SB_SHIFT 8 | ||
| 69 | #define BRCMU_CHSPEC_D11AC_SB_LLL 0x0000 | ||
| 70 | #define BRCMU_CHSPEC_D11AC_SB_LLU 0x0100 | ||
| 71 | #define BRCMU_CHSPEC_D11AC_SB_LUL 0x0200 | ||
| 72 | #define BRCMU_CHSPEC_D11AC_SB_LUU 0x0300 | ||
| 73 | #define BRCMU_CHSPEC_D11AC_SB_ULL 0x0400 | ||
| 74 | #define BRCMU_CHSPEC_D11AC_SB_ULU 0x0500 | ||
| 75 | #define BRCMU_CHSPEC_D11AC_SB_UUL 0x0600 | ||
| 76 | #define BRCMU_CHSPEC_D11AC_SB_UUU 0x0700 | ||
| 77 | #define BRCMU_CHSPEC_D11AC_SB_LL BRCMU_CHSPEC_D11AC_SB_LLL | ||
| 78 | #define BRCMU_CHSPEC_D11AC_SB_LU BRCMU_CHSPEC_D11AC_SB_LLU | ||
| 79 | #define BRCMU_CHSPEC_D11AC_SB_UL BRCMU_CHSPEC_D11AC_SB_LUL | ||
| 80 | #define BRCMU_CHSPEC_D11AC_SB_UU BRCMU_CHSPEC_D11AC_SB_LUU | ||
| 81 | #define BRCMU_CHSPEC_D11AC_SB_L BRCMU_CHSPEC_D11AC_SB_LLL | ||
| 82 | #define BRCMU_CHSPEC_D11AC_SB_U BRCMU_CHSPEC_D11AC_SB_LLU | ||
| 83 | #define BRCMU_CHSPEC_D11AC_BW_MASK 0x3800 | ||
| 84 | #define BRCMU_CHSPEC_D11AC_BW_SHIFT 11 | ||
| 85 | #define BRCMU_CHSPEC_D11AC_BW_5 0x0000 | ||
| 86 | #define BRCMU_CHSPEC_D11AC_BW_10 0x0800 | ||
| 87 | #define BRCMU_CHSPEC_D11AC_BW_20 0x1000 | ||
| 88 | #define BRCMU_CHSPEC_D11AC_BW_40 0x1800 | ||
| 89 | #define BRCMU_CHSPEC_D11AC_BW_80 0x2000 | ||
| 90 | #define BRCMU_CHSPEC_D11AC_BW_160 0x2800 | ||
| 91 | #define BRCMU_CHSPEC_D11AC_BW_8080 0x3000 | ||
| 92 | #define BRCMU_CHSPEC_D11AC_BND_MASK 0xc000 | ||
| 93 | #define BRCMU_CHSPEC_D11AC_BND_SHIFT 14 | ||
| 94 | #define BRCMU_CHSPEC_D11AC_BND_2G 0x0000 | ||
| 95 | #define BRCMU_CHSPEC_D11AC_BND_3G 0x4000 | ||
| 96 | #define BRCMU_CHSPEC_D11AC_BND_4G 0x8000 | ||
| 97 | #define BRCMU_CHSPEC_D11AC_BND_5G 0xc000 | ||
| 98 | |||
| 99 | #define BRCMU_CHAN_BAND_2G 0 | ||
| 100 | #define BRCMU_CHAN_BAND_5G 1 | ||
| 101 | |||
| 102 | enum brcmu_chan_bw { | ||
| 103 | BRCMU_CHAN_BW_20, | ||
| 104 | BRCMU_CHAN_BW_40, | ||
| 105 | BRCMU_CHAN_BW_80, | ||
| 106 | BRCMU_CHAN_BW_80P80, | ||
| 107 | BRCMU_CHAN_BW_160, | ||
| 108 | }; | ||
| 109 | |||
| 110 | enum brcmu_chan_sb { | ||
| 111 | BRCMU_CHAN_SB_NONE = 0, | ||
| 112 | BRCMU_CHAN_SB_L, | ||
| 113 | BRCMU_CHAN_SB_U, | ||
| 114 | BRCMU_CHAN_SB_LL, | ||
| 115 | BRCMU_CHAN_SB_LU, | ||
| 116 | BRCMU_CHAN_SB_UL, | ||
| 117 | BRCMU_CHAN_SB_UU, | ||
| 118 | BRCMU_CHAN_SB_LLL, | ||
| 119 | BRCMU_CHAN_SB_LLU, | ||
| 120 | BRCMU_CHAN_SB_LUL, | ||
| 121 | BRCMU_CHAN_SB_LUU, | ||
| 122 | BRCMU_CHAN_SB_ULL, | ||
| 123 | BRCMU_CHAN_SB_ULU, | ||
| 124 | BRCMU_CHAN_SB_UUL, | ||
| 125 | BRCMU_CHAN_SB_UUU, | ||
| 126 | }; | ||
| 127 | |||
| 128 | struct brcmu_chan { | ||
| 129 | u16 chspec; | ||
| 130 | u8 chnum; | ||
| 131 | u8 band; | ||
| 132 | enum brcmu_chan_bw bw; | ||
| 133 | enum brcmu_chan_sb sb; | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct brcmu_d11inf { | ||
| 137 | u8 io_type; | ||
| 138 | |||
| 139 | void (*encchspec)(struct brcmu_chan *ch); | ||
| 140 | void (*decchspec)(struct brcmu_chan *ch); | ||
| 141 | }; | ||
| 142 | |||
| 143 | extern void brcmu_d11_attach(struct brcmu_d11inf *d11inf); | ||
| 144 | |||
| 145 | #endif /* _BRCMU_CHANNELS_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h index f96834a7c055..d242333b7559 100644 --- a/drivers/net/wireless/brcm80211/include/chipcommon.h +++ b/drivers/net/wireless/brcm80211/include/chipcommon.h | |||
| @@ -205,7 +205,7 @@ struct chipcregs { | |||
| 205 | u32 res_req_timer_sel; | 205 | u32 res_req_timer_sel; |
| 206 | u32 res_req_timer; | 206 | u32 res_req_timer; |
| 207 | u32 res_req_mask; | 207 | u32 res_req_mask; |
| 208 | u32 PAD; | 208 | u32 pmucapabilities_ext; /* 0x64c, pmurev >=15 */ |
| 209 | u32 chipcontrol_addr; /* 0x650 */ | 209 | u32 chipcontrol_addr; /* 0x650 */ |
| 210 | u32 chipcontrol_data; /* 0x654 */ | 210 | u32 chipcontrol_data; /* 0x654 */ |
| 211 | u32 regcontrol_addr; | 211 | u32 regcontrol_addr; |
| @@ -214,7 +214,11 @@ struct chipcregs { | |||
| 214 | u32 pllcontrol_data; | 214 | u32 pllcontrol_data; |
| 215 | u32 pmustrapopt; /* 0x668, corerev >= 28 */ | 215 | u32 pmustrapopt; /* 0x668, corerev >= 28 */ |
| 216 | u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ | 216 | u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ |
| 217 | u32 PAD[100]; | 217 | u32 retention_ctl; /* 0x670, pmurev >= 15 */ |
| 218 | u32 PAD[3]; | ||
| 219 | u32 retention_grpidx; /* 0x680 */ | ||
| 220 | u32 retention_grpctl; /* 0x684 */ | ||
| 221 | u32 PAD[94]; | ||
| 218 | u16 sromotp[768]; | 222 | u16 sromotp[768]; |
| 219 | }; | 223 | }; |
| 220 | 224 | ||
| @@ -276,6 +280,12 @@ struct chipcregs { | |||
| 276 | #define PCAP5_VC_SHIFT 22 | 280 | #define PCAP5_VC_SHIFT 22 |
| 277 | #define PCAP5_CC_MASK 0xf8000000 | 281 | #define PCAP5_CC_MASK 0xf8000000 |
| 278 | #define PCAP5_CC_SHIFT 27 | 282 | #define PCAP5_CC_SHIFT 27 |
| 283 | /* pmucapabilites_ext PMU rev >= 15 */ | ||
| 284 | #define PCAPEXT_SR_SUPPORTED_MASK (1 << 1) | ||
| 285 | /* retention_ctl PMU rev >= 15 */ | ||
| 286 | #define PMU_RCTL_MACPHY_DISABLE_MASK (1 << 26) | ||
| 287 | #define PMU_RCTL_LOGIC_DISABLE_MASK (1 << 27) | ||
| 288 | |||
| 279 | 289 | ||
| 280 | /* | 290 | /* |
| 281 | * Maximum delay for the PMU state transition in us. | 291 | * Maximum delay for the PMU state transition in us. |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index cb066f62879d..15920aaa5dd6 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
| @@ -4167,17 +4167,11 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf) | |||
| 4167 | static ssize_t store_debug_level(struct device_driver *d, | 4167 | static ssize_t store_debug_level(struct device_driver *d, |
| 4168 | const char *buf, size_t count) | 4168 | const char *buf, size_t count) |
| 4169 | { | 4169 | { |
| 4170 | char *p = (char *)buf; | ||
| 4171 | u32 val; | 4170 | u32 val; |
| 4171 | int ret; | ||
| 4172 | 4172 | ||
| 4173 | if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { | 4173 | ret = kstrtou32(buf, 0, &val); |
| 4174 | p++; | 4174 | if (ret) |
| 4175 | if (p[0] == 'x' || p[0] == 'X') | ||
| 4176 | p++; | ||
| 4177 | val = simple_strtoul(p, &p, 16); | ||
| 4178 | } else | ||
| 4179 | val = simple_strtoul(p, &p, 10); | ||
| 4180 | if (p == buf) | ||
| 4181 | IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf); | 4175 | IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf); |
| 4182 | else | 4176 | else |
| 4183 | ipw2100_debug_level = val; | 4177 | ipw2100_debug_level = val; |
| @@ -4238,27 +4232,15 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, | |||
| 4238 | { | 4232 | { |
| 4239 | struct ipw2100_priv *priv = dev_get_drvdata(d); | 4233 | struct ipw2100_priv *priv = dev_get_drvdata(d); |
| 4240 | struct net_device *dev = priv->net_dev; | 4234 | struct net_device *dev = priv->net_dev; |
| 4241 | char buffer[] = "00000000"; | ||
| 4242 | unsigned long len = | ||
| 4243 | (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; | ||
| 4244 | unsigned long val; | 4235 | unsigned long val; |
| 4245 | char *p = buffer; | 4236 | int ret; |
| 4246 | 4237 | ||
| 4247 | (void)dev; /* kill unused-var warning for debug-only code */ | 4238 | (void)dev; /* kill unused-var warning for debug-only code */ |
| 4248 | 4239 | ||
| 4249 | IPW_DEBUG_INFO("enter\n"); | 4240 | IPW_DEBUG_INFO("enter\n"); |
| 4250 | 4241 | ||
| 4251 | strncpy(buffer, buf, len); | 4242 | ret = kstrtoul(buf, 0, &val); |
| 4252 | buffer[len] = 0; | 4243 | if (ret) { |
| 4253 | |||
| 4254 | if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { | ||
| 4255 | p++; | ||
| 4256 | if (p[0] == 'x' || p[0] == 'X') | ||
| 4257 | p++; | ||
| 4258 | val = simple_strtoul(p, &p, 16); | ||
| 4259 | } else | ||
| 4260 | val = simple_strtoul(p, &p, 10); | ||
| 4261 | if (p == buffer) { | ||
| 4262 | IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name); | 4244 | IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name); |
| 4263 | } else { | 4245 | } else { |
| 4264 | priv->ieee->scan_age = val; | 4246 | priv->ieee->scan_age = val; |
| @@ -4266,7 +4248,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, | |||
| 4266 | } | 4248 | } |
| 4267 | 4249 | ||
| 4268 | IPW_DEBUG_INFO("exit\n"); | 4250 | IPW_DEBUG_INFO("exit\n"); |
| 4269 | return len; | 4251 | return strnlen(buf, count); |
| 4270 | } | 4252 | } |
| 4271 | 4253 | ||
| 4272 | static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); | 4254 | static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); |
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index d4fd29ad90dc..c9f197d9ca1e 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c | |||
| @@ -347,7 +347,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) | |||
| 347 | 347 | ||
| 348 | psta = (struct il3945_sta_priv *)sta->drv_priv; | 348 | psta = (struct il3945_sta_priv *)sta->drv_priv; |
| 349 | rs_sta = &psta->rs_sta; | 349 | rs_sta = &psta->rs_sta; |
| 350 | sband = hw->wiphy->bands[conf->channel->band]; | 350 | sband = hw->wiphy->bands[conf->chandef.chan->band]; |
| 351 | 351 | ||
| 352 | rs_sta->il = il; | 352 | rs_sta->il = il; |
| 353 | 353 | ||
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 6affa7e8f017..b8f82e688c72 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
| @@ -6057,7 +6057,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 6057 | struct il_priv *il = hw->priv; | 6057 | struct il_priv *il = hw->priv; |
| 6058 | const struct il_channel_info *ch_info; | 6058 | const struct il_channel_info *ch_info; |
| 6059 | struct ieee80211_conf *conf = &hw->conf; | 6059 | struct ieee80211_conf *conf = &hw->conf; |
| 6060 | struct ieee80211_channel *channel = ch_switch->channel; | 6060 | struct ieee80211_channel *channel = ch_switch->chandef.chan; |
| 6061 | struct il_ht_config *ht_conf = &il->current_ht_config; | 6061 | struct il_ht_config *ht_conf = &il->current_ht_config; |
| 6062 | u16 ch; | 6062 | u16 ch; |
| 6063 | 6063 | ||
| @@ -6094,23 +6094,21 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 6094 | il->current_ht_config.smps = conf->smps_mode; | 6094 | il->current_ht_config.smps = conf->smps_mode; |
| 6095 | 6095 | ||
| 6096 | /* Configure HT40 channels */ | 6096 | /* Configure HT40 channels */ |
| 6097 | il->ht.enabled = conf_is_ht(conf); | 6097 | switch (cfg80211_get_chandef_type(&ch_switch->chandef)) { |
| 6098 | if (il->ht.enabled) { | 6098 | case NL80211_CHAN_NO_HT: |
| 6099 | if (conf_is_ht40_minus(conf)) { | 6099 | case NL80211_CHAN_HT20: |
| 6100 | il->ht.extension_chan_offset = | ||
| 6101 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 6102 | il->ht.is_40mhz = true; | ||
| 6103 | } else if (conf_is_ht40_plus(conf)) { | ||
| 6104 | il->ht.extension_chan_offset = | ||
| 6105 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 6106 | il->ht.is_40mhz = true; | ||
| 6107 | } else { | ||
| 6108 | il->ht.extension_chan_offset = | ||
| 6109 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 6110 | il->ht.is_40mhz = false; | ||
| 6111 | } | ||
| 6112 | } else | ||
| 6113 | il->ht.is_40mhz = false; | 6100 | il->ht.is_40mhz = false; |
| 6101 | il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 6102 | break; | ||
| 6103 | case NL80211_CHAN_HT40MINUS: | ||
| 6104 | il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 6105 | il->ht.is_40mhz = true; | ||
| 6106 | break; | ||
| 6107 | case NL80211_CHAN_HT40PLUS: | ||
| 6108 | il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 6109 | il->ht.is_40mhz = true; | ||
| 6110 | break; | ||
| 6111 | } | ||
| 6114 | 6112 | ||
| 6115 | if ((le16_to_cpu(il->staging.channel) != ch)) | 6113 | if ((le16_to_cpu(il->staging.channel) != ch)) |
| 6116 | il->staging.flags = 0; | 6114 | il->staging.flags = 0; |
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 6c7493c2d698..1fc0b227e120 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c | |||
| @@ -2300,7 +2300,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) | |||
| 2300 | 2300 | ||
| 2301 | sta_priv = (struct il_station_priv *)sta->drv_priv; | 2301 | sta_priv = (struct il_station_priv *)sta->drv_priv; |
| 2302 | lq_sta = &sta_priv->lq_sta; | 2302 | lq_sta = &sta_priv->lq_sta; |
| 2303 | sband = hw->wiphy->bands[conf->channel->band]; | 2303 | sband = hw->wiphy->bands[conf->chandef.chan->band]; |
| 2304 | 2304 | ||
| 2305 | lq_sta->lq.sta_id = sta_id; | 2305 | lq_sta->lq.sta_id = sta_id; |
| 2306 | 2306 | ||
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 91eb2d07fdb8..777a578294bd 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c | |||
| @@ -1493,7 +1493,7 @@ il4965_hw_channel_switch(struct il_priv *il, | |||
| 1493 | 1493 | ||
| 1494 | cmd.band = band; | 1494 | cmd.band = band; |
| 1495 | cmd.expect_beacon = 0; | 1495 | cmd.expect_beacon = 0; |
| 1496 | ch = ch_switch->channel->hw_value; | 1496 | ch = ch_switch->chandef.chan->hw_value; |
| 1497 | cmd.channel = cpu_to_le16(ch); | 1497 | cmd.channel = cpu_to_le16(ch); |
| 1498 | cmd.rxon_flags = il->staging.flags; | 1498 | cmd.rxon_flags = il->staging.flags; |
| 1499 | cmd.rxon_filter_flags = il->staging.filter_flags; | 1499 | cmd.rxon_filter_flags = il->staging.filter_flags; |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 3613b3a81ad2..592d0aa634a8 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
| @@ -4971,7 +4971,7 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 4971 | struct il_priv *il = hw->priv; | 4971 | struct il_priv *il = hw->priv; |
| 4972 | const struct il_channel_info *ch_info; | 4972 | const struct il_channel_info *ch_info; |
| 4973 | struct ieee80211_conf *conf = &hw->conf; | 4973 | struct ieee80211_conf *conf = &hw->conf; |
| 4974 | struct ieee80211_channel *channel = conf->channel; | 4974 | struct ieee80211_channel *channel = conf->chandef.chan; |
| 4975 | struct il_ht_config *ht_conf = &il->current_ht_config; | 4975 | struct il_ht_config *ht_conf = &il->current_ht_config; |
| 4976 | unsigned long flags = 0; | 4976 | unsigned long flags = 0; |
| 4977 | int ret = 0; | 4977 | int ret = 0; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 019d433900ef..e575b9b0cda8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
| @@ -73,6 +73,8 @@ | |||
| 73 | /* AUX (TX during scan dwell) queue */ | 73 | /* AUX (TX during scan dwell) queue */ |
| 74 | #define IWL_AUX_QUEUE 10 | 74 | #define IWL_AUX_QUEUE 10 |
| 75 | 75 | ||
| 76 | #define IWL_INVALID_STATION 255 | ||
| 77 | |||
| 76 | /* device operations */ | 78 | /* device operations */ |
| 77 | extern struct iwl_lib_ops iwl1000_lib; | 79 | extern struct iwl_lib_ops iwl1000_lib; |
| 78 | extern struct iwl_lib_ops iwl2000_lib; | 80 | extern struct iwl_lib_ops iwl2000_lib; |
| @@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); | |||
| 176 | /* lib */ | 178 | /* lib */ |
| 177 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 179 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
| 178 | void iwlagn_temperature(struct iwl_priv *priv); | 180 | void iwlagn_temperature(struct iwl_priv *priv); |
| 179 | int iwlagn_txfifo_flush(struct iwl_priv *priv); | 181 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk); |
| 180 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); | 182 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); |
| 181 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 183 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
| 182 | int iwl_send_statistics_request(struct iwl_priv *priv, | 184 | int iwl_send_statistics_request(struct iwl_priv *priv, |
| @@ -210,6 +212,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 210 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); | 212 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); |
| 211 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 213 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, |
| 212 | struct ieee80211_sta *sta, u16 tid); | 214 | struct ieee80211_sta *sta, u16 tid); |
| 215 | int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
| 216 | struct ieee80211_sta *sta, u16 tid); | ||
| 213 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 217 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
| 214 | struct iwl_rx_cmd_buffer *rxb, | 218 | struct iwl_rx_cmd_buffer *rxb, |
| 215 | struct iwl_device_cmd *cmd); | 219 | struct iwl_device_cmd *cmd); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 15cca2ef9294..c48907c8ab43 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
| @@ -379,7 +379,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
| 379 | }; | 379 | }; |
| 380 | 380 | ||
| 381 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 381 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
| 382 | ch = ch_switch->channel->hw_value; | 382 | ch = ch_switch->chandef.chan->hw_value; |
| 383 | IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", | 383 | IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", |
| 384 | ctx->active.channel, ch); | 384 | ctx->active.channel, ch); |
| 385 | cmd.channel = cpu_to_le16(ch); | 385 | cmd.channel = cpu_to_le16(ch); |
| @@ -414,7 +414,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
| 414 | } | 414 | } |
| 415 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 415 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
| 416 | cmd.switch_time); | 416 | cmd.switch_time); |
| 417 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; | 417 | cmd.expect_beacon = |
| 418 | ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; | ||
| 418 | 419 | ||
| 419 | return iwl_dvm_send_cmd(priv, &hcmd); | 420 | return iwl_dvm_send_cmd(priv, &hcmd); |
| 420 | } | 421 | } |
| @@ -540,7 +541,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 540 | hcmd.data[0] = cmd; | 541 | hcmd.data[0] = cmd; |
| 541 | 542 | ||
| 542 | cmd->band = priv->band == IEEE80211_BAND_2GHZ; | 543 | cmd->band = priv->band == IEEE80211_BAND_2GHZ; |
| 543 | ch = ch_switch->channel->hw_value; | 544 | ch = ch_switch->chandef.chan->hw_value; |
| 544 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | 545 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", |
| 545 | ctx->active.channel, ch); | 546 | ctx->active.channel, ch); |
| 546 | cmd->channel = cpu_to_le16(ch); | 547 | cmd->channel = cpu_to_le16(ch); |
| @@ -575,7 +576,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 575 | } | 576 | } |
| 576 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 577 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
| 577 | cmd->switch_time); | 578 | cmd->switch_time); |
| 578 | cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; | 579 | cmd->expect_beacon = |
| 580 | ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; | ||
| 579 | 581 | ||
| 580 | err = iwl_dvm_send_cmd(priv, &hcmd); | 582 | err = iwl_dvm_send_cmd(priv, &hcmd); |
| 581 | kfree(cmd); | 583 | kfree(cmd); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 87c006c9c573..54f553380aa8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
| @@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
| 136 | * 1. acquire mutex before calling | 136 | * 1. acquire mutex before calling |
| 137 | * 2. make sure rf is on and not in exit state | 137 | * 2. make sure rf is on and not in exit state |
| 138 | */ | 138 | */ |
| 139 | int iwlagn_txfifo_flush(struct iwl_priv *priv) | 139 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk) |
| 140 | { | 140 | { |
| 141 | struct iwl_txfifo_flush_cmd flush_cmd; | 141 | struct iwl_txfifo_flush_cmd flush_cmd; |
| 142 | struct iwl_host_cmd cmd = { | 142 | struct iwl_host_cmd cmd = { |
| @@ -162,6 +162,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv) | |||
| 162 | if (priv->nvm_data->sku_cap_11n_enable) | 162 | if (priv->nvm_data->sku_cap_11n_enable) |
| 163 | flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; | 163 | flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; |
| 164 | 164 | ||
| 165 | if (scd_q_msk) | ||
| 166 | flush_cmd.queue_control = cpu_to_le32(scd_q_msk); | ||
| 167 | |||
| 165 | IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", | 168 | IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", |
| 166 | flush_cmd.queue_control); | 169 | flush_cmd.queue_control); |
| 167 | flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); | 170 | flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); |
| @@ -173,7 +176,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) | |||
| 173 | { | 176 | { |
| 174 | mutex_lock(&priv->mutex); | 177 | mutex_lock(&priv->mutex); |
| 175 | ieee80211_stop_queues(priv->hw); | 178 | ieee80211_stop_queues(priv->hw); |
| 176 | if (iwlagn_txfifo_flush(priv)) { | 179 | if (iwlagn_txfifo_flush(priv, 0)) { |
| 177 | IWL_ERR(priv, "flush request fail\n"); | 180 | IWL_ERR(priv, "flush request fail\n"); |
| 178 | goto done; | 181 | goto done; |
| 179 | } | 182 | } |
| @@ -1084,7 +1087,14 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) | |||
| 1084 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 1087 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 1085 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | 1088 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; |
| 1086 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | 1089 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; |
| 1087 | struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; | 1090 | struct iwlagn_d3_config_cmd d3_cfg_cmd = { |
| 1091 | /* | ||
| 1092 | * Program the minimum sleep time to 10 seconds, as many | ||
| 1093 | * platforms have issues processing a wakeup signal while | ||
| 1094 | * still being in the process of suspending. | ||
| 1095 | */ | ||
| 1096 | .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), | ||
| 1097 | }; | ||
| 1088 | struct wowlan_key_data key_data = { | 1098 | struct wowlan_key_data key_data = { |
| 1089 | .ctx = ctx, | 1099 | .ctx = ctx, |
| 1090 | .bssid = ctx->active.bssid_addr, | 1100 | .bssid = ctx->active.bssid_addr, |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index a7294fa4d7e5..cab23af0be9e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
| @@ -777,9 +777,12 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 777 | IWL_DEBUG_HT(priv, "start Tx\n"); | 777 | IWL_DEBUG_HT(priv, "start Tx\n"); |
| 778 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 778 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
| 779 | break; | 779 | break; |
| 780 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
| 781 | case IEEE80211_AMPDU_TX_STOP_FLUSH: | 780 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
| 782 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: | 781 | case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
| 782 | IWL_DEBUG_HT(priv, "Flush Tx\n"); | ||
| 783 | ret = iwlagn_tx_agg_flush(priv, vif, sta, tid); | ||
| 784 | break; | ||
| 785 | case IEEE80211_AMPDU_TX_STOP_CONT: | ||
| 783 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 786 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
| 784 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | 787 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); |
| 785 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | 788 | if ((ret == 0) && (priv->agg_tids_count > 0)) { |
| @@ -967,7 +970,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 967 | { | 970 | { |
| 968 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 971 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 969 | struct ieee80211_conf *conf = &hw->conf; | 972 | struct ieee80211_conf *conf = &hw->conf; |
| 970 | struct ieee80211_channel *channel = ch_switch->channel; | 973 | struct ieee80211_channel *channel = ch_switch->chandef.chan; |
| 971 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | 974 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; |
| 972 | /* | 975 | /* |
| 973 | * MULTI-FIXME | 976 | * MULTI-FIXME |
| @@ -1005,11 +1008,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 1005 | priv->current_ht_config.smps = conf->smps_mode; | 1008 | priv->current_ht_config.smps = conf->smps_mode; |
| 1006 | 1009 | ||
| 1007 | /* Configure HT40 channels */ | 1010 | /* Configure HT40 channels */ |
| 1008 | ctx->ht.enabled = conf_is_ht(conf); | 1011 | switch (cfg80211_get_chandef_type(&ch_switch->chandef)) { |
| 1009 | if (ctx->ht.enabled) | 1012 | case NL80211_CHAN_NO_HT: |
| 1010 | iwlagn_config_ht40(conf, ctx); | 1013 | case NL80211_CHAN_HT20: |
| 1011 | else | ||
| 1012 | ctx->ht.is_40mhz = false; | 1014 | ctx->ht.is_40mhz = false; |
| 1015 | ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 1016 | break; | ||
| 1017 | case NL80211_CHAN_HT40MINUS: | ||
| 1018 | ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 1019 | ctx->ht.is_40mhz = true; | ||
| 1020 | break; | ||
| 1021 | case NL80211_CHAN_HT40PLUS: | ||
| 1022 | ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 1023 | ctx->ht.is_40mhz = true; | ||
| 1024 | break; | ||
| 1025 | } | ||
| 1013 | 1026 | ||
| 1014 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | 1027 | if ((le16_to_cpu(ctx->staging.channel) != ch)) |
| 1015 | ctx->staging.flags = 0; | 1028 | ctx->staging.flags = 0; |
| @@ -1122,7 +1135,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
| 1122 | */ | 1135 | */ |
| 1123 | if (drop) { | 1136 | if (drop) { |
| 1124 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | 1137 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); |
| 1125 | if (iwlagn_txfifo_flush(priv)) { | 1138 | if (iwlagn_txfifo_flush(priv, 0)) { |
| 1126 | IWL_ERR(priv, "flush request fail\n"); | 1139 | IWL_ERR(priv, "flush request fail\n"); |
| 1127 | goto done; | 1140 | goto done; |
| 1128 | } | 1141 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index abe304267261..907bd6e50aad 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
| @@ -2831,7 +2831,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
| 2831 | 2831 | ||
| 2832 | sta_priv = (struct iwl_station_priv *) sta->drv_priv; | 2832 | sta_priv = (struct iwl_station_priv *) sta->drv_priv; |
| 2833 | lq_sta = &sta_priv->lq_sta; | 2833 | lq_sta = &sta_priv->lq_sta; |
| 2834 | sband = hw->wiphy->bands[conf->channel->band]; | 2834 | sband = hw->wiphy->bands[conf->chandef.chan->band]; |
| 2835 | 2835 | ||
| 2836 | 2836 | ||
| 2837 | lq_sta->lq.sta_id = sta_id; | 2837 | lq_sta->lq.sta_id = sta_id; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index a82b6b39d4ff..707446fa00bd 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
| @@ -78,8 +78,9 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, | |||
| 78 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 78 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value); | 81 | ctx->staging.channel = |
| 82 | priv->band = priv->hw->conf.channel->band; | 82 | cpu_to_le16(priv->hw->conf.chandef.chan->hw_value); |
| 83 | priv->band = priv->hw->conf.chandef.chan->band; | ||
| 83 | 84 | ||
| 84 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); | 85 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); |
| 85 | 86 | ||
| @@ -951,7 +952,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, | |||
| 951 | unsigned long basic = ctx->vif->bss_conf.basic_rates; | 952 | unsigned long basic = ctx->vif->bss_conf.basic_rates; |
| 952 | int i; | 953 | int i; |
| 953 | 954 | ||
| 954 | sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band]; | 955 | sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band]; |
| 955 | 956 | ||
| 956 | for_each_set_bit(i, &basic, BITS_PER_LONG) { | 957 | for_each_set_bit(i, &basic, BITS_PER_LONG) { |
| 957 | int hw = sband->bitrates[i].hw_value; | 958 | int hw = sband->bitrates[i].hw_value; |
| @@ -1159,7 +1160,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 1159 | } | 1160 | } |
| 1160 | 1161 | ||
| 1161 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | 1162 | void iwlagn_config_ht40(struct ieee80211_conf *conf, |
| 1162 | struct iwl_rxon_context *ctx) | 1163 | struct iwl_rxon_context *ctx) |
| 1163 | { | 1164 | { |
| 1164 | if (conf_is_ht40_minus(conf)) { | 1165 | if (conf_is_ht40_minus(conf)) { |
| 1165 | ctx->ht.extension_chan_offset = | 1166 | ctx->ht.extension_chan_offset = |
| @@ -1181,7 +1182,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1181 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1182 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
| 1182 | struct iwl_rxon_context *ctx; | 1183 | struct iwl_rxon_context *ctx; |
| 1183 | struct ieee80211_conf *conf = &hw->conf; | 1184 | struct ieee80211_conf *conf = &hw->conf; |
| 1184 | struct ieee80211_channel *channel = conf->channel; | 1185 | struct ieee80211_channel *channel = conf->chandef.chan; |
| 1185 | int ret = 0; | 1186 | int ret = 0; |
| 1186 | 1187 | ||
| 1187 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); | 1188 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 70b7f68c4958..a900aaf47790 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
| @@ -674,6 +674,51 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 674 | return ret; | 674 | return ret; |
| 675 | } | 675 | } |
| 676 | 676 | ||
| 677 | int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
| 678 | struct ieee80211_sta *sta, u16 tid) | ||
| 679 | { | ||
| 680 | struct iwl_tid_data *tid_data; | ||
| 681 | enum iwl_agg_state agg_state; | ||
| 682 | int sta_id, txq_id; | ||
| 683 | sta_id = iwl_sta_id(sta); | ||
| 684 | |||
| 685 | /* | ||
| 686 | * First set the agg state to OFF to avoid calling | ||
| 687 | * ieee80211_stop_tx_ba_cb in iwlagn_check_ratid_empty. | ||
| 688 | */ | ||
| 689 | spin_lock_bh(&priv->sta_lock); | ||
| 690 | |||
| 691 | tid_data = &priv->tid_data[sta_id][tid]; | ||
| 692 | txq_id = tid_data->agg.txq_id; | ||
| 693 | agg_state = tid_data->agg.state; | ||
| 694 | IWL_DEBUG_TX_QUEUES(priv, "Flush AGG: sta %d tid %d q %d state %d\n", | ||
| 695 | sta_id, tid, txq_id, tid_data->agg.state); | ||
| 696 | |||
| 697 | tid_data->agg.state = IWL_AGG_OFF; | ||
| 698 | |||
| 699 | spin_unlock_bh(&priv->sta_lock); | ||
| 700 | |||
| 701 | if (iwlagn_txfifo_flush(priv, BIT(txq_id))) | ||
| 702 | IWL_ERR(priv, "Couldn't flush the AGG queue\n"); | ||
| 703 | |||
| 704 | if (test_bit(txq_id, priv->agg_q_alloc)) { | ||
| 705 | /* | ||
| 706 | * If the transport didn't know that we wanted to start | ||
| 707 | * agreggation, don't tell it that we want to stop them. | ||
| 708 | * This can happen when we don't get the addBA response on | ||
| 709 | * time, or we hadn't time to drain the AC queues. | ||
| 710 | */ | ||
| 711 | if (agg_state == IWL_AGG_ON) | ||
| 712 | iwl_trans_txq_disable(priv->trans, txq_id); | ||
| 713 | else | ||
| 714 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | ||
| 715 | agg_state); | ||
| 716 | iwlagn_dealloc_agg_txq(priv, txq_id); | ||
| 717 | } | ||
| 718 | |||
| 719 | return 0; | ||
| 720 | } | ||
| 721 | |||
| 677 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | 722 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, |
| 678 | struct ieee80211_sta *sta, u16 tid, u8 buf_size) | 723 | struct ieee80211_sta *sta, u16 tid, u8 buf_size) |
| 679 | { | 724 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 498300577ac0..39aad9893e0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -912,8 +912,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
| 912 | } | 912 | } |
| 913 | } | 913 | } |
| 914 | 914 | ||
| 915 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | ||
| 916 | |||
| 917 | /* | 915 | /* |
| 918 | * In mvm uCode there is no difference between data and instructions | 916 | * In mvm uCode there is no difference between data and instructions |
| 919 | * sections. | 917 | * sections. |
| @@ -970,6 +968,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
| 970 | else | 968 | else |
| 971 | op = &iwlwifi_opmode_table[DVM_OP_MODE]; | 969 | op = &iwlwifi_opmode_table[DVM_OP_MODE]; |
| 972 | 970 | ||
| 971 | IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", | ||
| 972 | drv->fw.fw_version, op->name); | ||
| 973 | |||
| 973 | /* add this device to the list of devices using this op_mode */ | 974 | /* add this device to the list of devices using this op_mode */ |
| 974 | list_add_tail(&drv->list, &op->drv); | 975 | list_add_tail(&drv->list, &op->drv); |
| 975 | 976 | ||
| @@ -997,8 +998,13 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
| 997 | * else from proceeding if the module fails to load | 998 | * else from proceeding if the module fails to load |
| 998 | * or hangs loading. | 999 | * or hangs loading. |
| 999 | */ | 1000 | */ |
| 1000 | if (load_module) | 1001 | if (load_module) { |
| 1001 | request_module("%s", op->name); | 1002 | err = request_module("%s", op->name); |
| 1003 | if (err) | ||
| 1004 | IWL_ERR(drv, | ||
| 1005 | "failed to load module %s (error %d), is dynamic loading enabled?\n", | ||
| 1006 | op->name, err); | ||
| 1007 | } | ||
| 1002 | return; | 1008 | return; |
| 1003 | 1009 | ||
| 1004 | try_again: | 1010 | try_again: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7f9c254292a8..7a13790b5bfe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
| @@ -305,7 +305,6 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r) | |||
| 305 | * currently supports | 305 | * currently supports |
| 306 | */ | 306 | */ |
| 307 | #define IWL_MAX_HW_QUEUES 32 | 307 | #define IWL_MAX_HW_QUEUES 32 |
| 308 | #define IWL_INVALID_STATION 255 | ||
| 309 | #define IWL_MAX_TID_COUNT 8 | 308 | #define IWL_MAX_TID_COUNT 8 |
| 310 | #define IWL_FRAME_LIMIT 64 | 309 | #define IWL_FRAME_LIMIT 64 |
| 311 | 310 | ||
| @@ -682,7 +681,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | |||
| 682 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | 681 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, |
| 683 | int fifo) | 682 | int fifo) |
| 684 | { | 683 | { |
| 685 | iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, | 684 | iwl_trans_txq_enable(trans, queue, fifo, -1, |
| 686 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); | 685 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); |
| 687 | } | 686 | } |
| 688 | 687 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 1700232aa166..810bfa5f6de0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
| @@ -61,6 +61,8 @@ | |||
| 61 | * | 61 | * |
| 62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
| 63 | 63 | ||
| 64 | #include <net/mac80211.h> | ||
| 65 | |||
| 64 | #include "fw-api-bt-coex.h" | 66 | #include "fw-api-bt-coex.h" |
| 65 | #include "iwl-modparams.h" | 67 | #include "iwl-modparams.h" |
| 66 | #include "mvm.h" | 68 | #include "mvm.h" |
| @@ -96,6 +98,20 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
| 96 | 98 | ||
| 97 | #undef EVENT_PRIO_ANT | 99 | #undef EVENT_PRIO_ANT |
| 98 | 100 | ||
| 101 | /* BT Antenna Coupling Threshold (dB) */ | ||
| 102 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | ||
| 103 | #define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) | ||
| 104 | |||
| 105 | #define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) | ||
| 106 | #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) | ||
| 107 | #define BT_REDUCED_TX_POWER_BIT BIT(7) | ||
| 108 | |||
| 109 | static inline bool is_loose_coex(void) | ||
| 110 | { | ||
| 111 | return iwlwifi_mod_params.ant_coupling > | ||
| 112 | IWL_BT_ANTENNA_COUPLING_THRESHOLD; | ||
| 113 | } | ||
| 114 | |||
| 99 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) | 115 | int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) |
| 100 | { | 116 | { |
| 101 | return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, | 117 | return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, |
| @@ -186,11 +202,6 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { | |||
| 186 | cpu_to_le32(0x00000000), | 202 | cpu_to_le32(0x00000000), |
| 187 | }; | 203 | }; |
| 188 | 204 | ||
| 189 | /* BT Antenna Coupling Threshold (dB) */ | ||
| 190 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | ||
| 191 | #define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) | ||
| 192 | |||
| 193 | |||
| 194 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | 205 | int iwl_send_bt_init_conf(struct iwl_mvm *mvm) |
| 195 | { | 206 | { |
| 196 | struct iwl_bt_coex_cmd cmd = { | 207 | struct iwl_bt_coex_cmd cmd = { |
| @@ -203,8 +214,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
| 203 | 214 | ||
| 204 | cmd.flags = iwlwifi_mod_params.bt_coex_active ? | 215 | cmd.flags = iwlwifi_mod_params.bt_coex_active ? |
| 205 | BT_COEX_NW : BT_COEX_DISABLE; | 216 | BT_COEX_NW : BT_COEX_DISABLE; |
| 206 | cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0; | 217 | cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; |
| 207 | cmd.flags |= BT_SYNC_2_BT_DISABLE; | ||
| 208 | 218 | ||
| 209 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | | 219 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | |
| 210 | BT_VALID_BT_PRIO_BOOST | | 220 | BT_VALID_BT_PRIO_BOOST | |
| @@ -215,7 +225,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
| 215 | BT_VALID_REDUCED_TX_POWER | | 225 | BT_VALID_REDUCED_TX_POWER | |
| 216 | BT_VALID_LUT); | 226 | BT_VALID_LUT); |
| 217 | 227 | ||
| 218 | if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) | 228 | if (is_loose_coex()) |
| 219 | memcpy(&cmd.decision_lut, iwl_loose_lookup, | 229 | memcpy(&cmd.decision_lut, iwl_loose_lookup, |
| 220 | sizeof(iwl_tight_lookup)); | 230 | sizeof(iwl_tight_lookup)); |
| 221 | else | 231 | else |
| @@ -228,6 +238,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
| 228 | cmd.kill_cts_msk = | 238 | cmd.kill_cts_msk = |
| 229 | cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); | 239 | cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); |
| 230 | 240 | ||
| 241 | memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); | ||
| 242 | |||
| 231 | /* go to CALIB state in internal BT-Coex state machine */ | 243 | /* go to CALIB state in internal BT-Coex state machine */ |
| 232 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, | 244 | ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, |
| 233 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 245 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
| @@ -243,19 +255,101 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
| 243 | sizeof(cmd), &cmd); | 255 | sizeof(cmd), &cmd); |
| 244 | } | 256 | } |
| 245 | 257 | ||
| 246 | struct iwl_bt_notif_iterator_data { | 258 | static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, |
| 247 | struct iwl_mvm *mvm; | 259 | bool reduced_tx_power) |
| 260 | { | ||
| 261 | enum iwl_bt_kill_msk bt_kill_msk; | ||
| 262 | struct iwl_bt_coex_cmd cmd = {}; | ||
| 263 | struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; | ||
| 264 | |||
| 265 | lockdep_assert_held(&mvm->mutex); | ||
| 266 | |||
| 267 | if (reduced_tx_power) { | ||
| 268 | /* Reduced Tx power has precedence on the type of the profile */ | ||
| 269 | bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW; | ||
| 270 | } else { | ||
| 271 | /* Low latency BT profile is active: give higher prio to BT */ | ||
| 272 | if (BT_MBOX_MSG(notif, 3, SCO_STATE) || | ||
| 273 | BT_MBOX_MSG(notif, 3, A2DP_STATE) || | ||
| 274 | BT_MBOX_MSG(notif, 3, SNIFF_STATE)) | ||
| 275 | bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; | ||
| 276 | else | ||
| 277 | bt_kill_msk = BT_KILL_MSK_DEFAULT; | ||
| 278 | } | ||
| 279 | |||
| 280 | IWL_DEBUG_COEX(mvm, | ||
| 281 | "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", | ||
| 282 | bt_kill_msk, | ||
| 283 | BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", | ||
| 284 | BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", | ||
| 285 | BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); | ||
| 286 | |||
| 287 | /* Don't send HCMD if there is no update */ | ||
| 288 | if (bt_kill_msk == mvm->bt_kill_msk) | ||
| 289 | return 0; | ||
| 290 | |||
| 291 | mvm->bt_kill_msk = bt_kill_msk; | ||
| 292 | cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); | ||
| 293 | cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); | ||
| 294 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); | ||
| 295 | |||
| 296 | IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); | ||
| 297 | return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, | ||
| 298 | sizeof(cmd), &cmd); | ||
| 299 | } | ||
| 300 | |||
| 301 | static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, | ||
| 302 | bool enable) | ||
| 303 | { | ||
| 304 | struct iwl_bt_coex_cmd cmd = { | ||
| 305 | .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), | ||
| 306 | .bt_reduced_tx_power = sta_id, | ||
| 307 | }; | ||
| 308 | struct ieee80211_sta *sta; | ||
| 309 | struct iwl_mvm_sta *mvmsta; | ||
| 310 | |||
| 311 | /* This can happen if the station has been removed right now */ | ||
| 312 | if (sta_id == IWL_MVM_STATION_COUNT) | ||
| 313 | return 0; | ||
| 314 | |||
| 315 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], | ||
| 316 | lockdep_is_held(&mvm->mutex)); | ||
| 317 | mvmsta = (void *)sta->drv_priv; | ||
| 318 | |||
| 319 | /* nothing to do */ | ||
| 320 | if (mvmsta->bt_reduced_txpower == enable) | ||
| 321 | return 0; | ||
| 322 | |||
| 323 | if (enable) | ||
| 324 | cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT; | ||
| 325 | |||
| 326 | IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n", | ||
| 327 | enable ? "en" : "dis", sta_id); | ||
| 328 | |||
| 329 | mvmsta->bt_reduced_txpower = enable; | ||
| 330 | |||
| 331 | /* Send ASYNC since this can be sent from an atomic context */ | ||
| 332 | return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC, | ||
| 333 | sizeof(cmd), &cmd); | ||
| 334 | } | ||
| 335 | |||
| 336 | struct iwl_bt_iterator_data { | ||
| 248 | struct iwl_bt_coex_profile_notif *notif; | 337 | struct iwl_bt_coex_profile_notif *notif; |
| 338 | struct iwl_mvm *mvm; | ||
| 339 | u32 num_bss_ifaces; | ||
| 340 | bool reduced_tx_power; | ||
| 249 | }; | 341 | }; |
| 250 | 342 | ||
| 251 | static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | 343 | static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, |
| 252 | struct ieee80211_vif *vif) | 344 | struct ieee80211_vif *vif) |
| 253 | { | 345 | { |
| 254 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 346 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 255 | struct iwl_bt_notif_iterator_data *data = _data; | 347 | struct iwl_bt_iterator_data *data = _data; |
| 348 | struct iwl_mvm *mvm = data->mvm; | ||
| 256 | struct ieee80211_chanctx_conf *chanctx_conf; | 349 | struct ieee80211_chanctx_conf *chanctx_conf; |
| 257 | enum ieee80211_smps_mode smps_mode; | 350 | enum ieee80211_smps_mode smps_mode; |
| 258 | enum ieee80211_band band; | 351 | enum ieee80211_band band; |
| 352 | int ave_rssi; | ||
| 259 | 353 | ||
| 260 | if (vif->type != NL80211_IFTYPE_STATION) | 354 | if (vif->type != NL80211_IFTYPE_STATION) |
| 261 | return; | 355 | return; |
| @@ -268,11 +362,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
| 268 | band = -1; | 362 | band = -1; |
| 269 | rcu_read_unlock(); | 363 | rcu_read_unlock(); |
| 270 | 364 | ||
| 271 | if (band != IEEE80211_BAND_2GHZ) | ||
| 272 | return; | ||
| 273 | |||
| 274 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 365 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
| 275 | 366 | ||
| 367 | if (band != IEEE80211_BAND_2GHZ) { | ||
| 368 | ieee80211_request_smps(vif, smps_mode); | ||
| 369 | return; | ||
| 370 | } | ||
| 371 | |||
| 276 | if (data->notif->bt_status) | 372 | if (data->notif->bt_status) |
| 277 | smps_mode = IEEE80211_SMPS_DYNAMIC; | 373 | smps_mode = IEEE80211_SMPS_DYNAMIC; |
| 278 | 374 | ||
| @@ -285,20 +381,88 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, | |||
| 285 | data->notif->bt_traffic_load, smps_mode); | 381 | data->notif->bt_traffic_load, smps_mode); |
| 286 | 382 | ||
| 287 | ieee80211_request_smps(vif, smps_mode); | 383 | ieee80211_request_smps(vif, smps_mode); |
| 384 | |||
| 385 | /* don't reduce the Tx power if in loose scheme */ | ||
| 386 | if (is_loose_coex()) | ||
| 387 | return; | ||
| 388 | |||
| 389 | data->num_bss_ifaces++; | ||
| 390 | |||
| 391 | /* reduced Txpower only if there are open BT connections, so ...*/ | ||
| 392 | if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) { | ||
| 393 | /* ... cancel reduced Tx power ... */ | ||
| 394 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) | ||
| 395 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
| 396 | data->reduced_tx_power = false; | ||
| 397 | |||
| 398 | /* ... and there is no need to get reports on RSSI any more. */ | ||
| 399 | ieee80211_disable_rssi_reports(vif); | ||
| 400 | return; | ||
| 401 | } | ||
| 402 | |||
| 403 | ave_rssi = ieee80211_ave_rssi(vif); | ||
| 404 | |||
| 405 | /* if the RSSI isn't valid, fake it is very low */ | ||
| 406 | if (!ave_rssi) | ||
| 407 | ave_rssi = -100; | ||
| 408 | if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) { | ||
| 409 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true)) | ||
| 410 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
| 411 | |||
| 412 | /* | ||
| 413 | * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the | ||
| 414 | * BSS / P2P clients have rssi above threshold. | ||
| 415 | * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before | ||
| 416 | * the iteration, if one interface's rssi isn't good enough, | ||
| 417 | * bt_kill_msk will be set to default values. | ||
| 418 | */ | ||
| 419 | } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) { | ||
| 420 | if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) | ||
| 421 | IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); | ||
| 422 | |||
| 423 | /* | ||
| 424 | * One interface hasn't rssi above threshold, bt_kill_msk must | ||
| 425 | * be set to default values. | ||
| 426 | */ | ||
| 427 | data->reduced_tx_power = false; | ||
| 428 | } | ||
| 429 | |||
| 430 | /* Begin to monitor the RSSI: it may influence the reduced Tx power */ | ||
| 431 | ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD, | ||
| 432 | BT_ENABLE_REDUCED_TXPOWER_THRESHOLD); | ||
| 433 | } | ||
| 434 | |||
| 435 | static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) | ||
| 436 | { | ||
| 437 | struct iwl_bt_iterator_data data = { | ||
| 438 | .mvm = mvm, | ||
| 439 | .notif = &mvm->last_bt_notif, | ||
| 440 | .reduced_tx_power = true, | ||
| 441 | }; | ||
| 442 | |||
| 443 | ieee80211_iterate_active_interfaces_atomic( | ||
| 444 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
| 445 | iwl_mvm_bt_notif_iterator, &data); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * If there are no BSS / P2P client interfaces, reduced Tx Power is | ||
| 449 | * irrelevant since it is based on the RSSI coming from the beacon. | ||
| 450 | * Use BT_KILL_MSK_DEFAULT in that case. | ||
| 451 | */ | ||
| 452 | data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; | ||
| 453 | |||
| 454 | if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) | ||
| 455 | IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); | ||
| 288 | } | 456 | } |
| 289 | 457 | ||
| 458 | /* upon association, the fw will send in BT Coex notification */ | ||
| 290 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | 459 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, |
| 291 | struct iwl_rx_cmd_buffer *rxb, | 460 | struct iwl_rx_cmd_buffer *rxb, |
| 292 | struct iwl_device_cmd *dev_cmd) | 461 | struct iwl_device_cmd *dev_cmd) |
| 293 | { | 462 | { |
| 294 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 463 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 295 | struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; | 464 | struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; |
| 296 | struct iwl_bt_notif_iterator_data data = { | 465 | |
| 297 | .mvm = mvm, | ||
| 298 | .notif = notif, | ||
| 299 | }; | ||
| 300 | struct iwl_bt_coex_cmd cmd = {}; | ||
| 301 | enum iwl_bt_kill_msk bt_kill_msk; | ||
| 302 | 466 | ||
| 303 | IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); | 467 | IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); |
| 304 | IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); | 468 | IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); |
| @@ -311,38 +475,115 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | |||
| 311 | /* remember this notification for future use: rssi fluctuations */ | 475 | /* remember this notification for future use: rssi fluctuations */ |
| 312 | memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); | 476 | memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); |
| 313 | 477 | ||
| 314 | ieee80211_iterate_active_interfaces_atomic( | 478 | iwl_mvm_bt_coex_notif_handle(mvm); |
| 315 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, | 479 | |
| 316 | iwl_mvm_bt_notif_iterator, &data); | 480 | /* |
| 481 | * This is an async handler for a notification, returning anything other | ||
| 482 | * than 0 doesn't make sense even if HCMD failed. | ||
| 483 | */ | ||
| 484 | return 0; | ||
| 485 | } | ||
| 486 | |||
| 487 | static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, | ||
| 488 | struct ieee80211_vif *vif) | ||
| 489 | { | ||
| 490 | struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; | ||
| 491 | struct iwl_bt_iterator_data *data = _data; | ||
| 492 | struct iwl_mvm *mvm = data->mvm; | ||
| 493 | |||
| 494 | struct ieee80211_sta *sta; | ||
| 495 | struct iwl_mvm_sta *mvmsta; | ||
| 496 | |||
| 497 | if (vif->type != NL80211_IFTYPE_STATION || | ||
| 498 | mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | ||
| 499 | return; | ||
| 500 | |||
| 501 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], | ||
| 502 | lockdep_is_held(&mvm->mutex)); | ||
| 503 | mvmsta = (void *)sta->drv_priv; | ||
| 504 | |||
| 505 | /* | ||
| 506 | * This interface doesn't support reduced Tx power (because of low | ||
| 507 | * RSSI probably), then set bt_kill_msk to default values. | ||
| 508 | */ | ||
| 509 | if (!mvmsta->bt_reduced_txpower) | ||
| 510 | data->reduced_tx_power = false; | ||
| 511 | /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */ | ||
| 512 | } | ||
| 513 | |||
| 514 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 515 | enum ieee80211_rssi_event rssi_event) | ||
| 516 | { | ||
| 517 | struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; | ||
| 518 | struct iwl_bt_iterator_data data = { | ||
| 519 | .mvm = mvm, | ||
| 520 | .reduced_tx_power = true, | ||
| 521 | }; | ||
| 522 | int ret; | ||
| 523 | |||
| 524 | mutex_lock(&mvm->mutex); | ||
| 525 | |||
| 526 | /* Rssi update while not associated ?! */ | ||
| 527 | if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) | ||
| 528 | goto out_unlock; | ||
| 317 | 529 | ||
| 318 | /* Low latency BT profile is active: give higher prio to BT */ | 530 | /* No open connection - reports should be disabled */ |
| 319 | if (BT_MBOX_MSG(notif, 3, SCO_STATE) || | 531 | if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2)) |
| 320 | BT_MBOX_MSG(notif, 3, A2DP_STATE) || | 532 | goto out_unlock; |
| 321 | BT_MBOX_MSG(notif, 3, SNIFF_STATE)) | 533 | |
| 322 | bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; | 534 | IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, |
| 535 | rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); | ||
| 536 | |||
| 537 | /* | ||
| 538 | * Check if rssi is good enough for reduced Tx power, but not in loose | ||
| 539 | * scheme. | ||
| 540 | */ | ||
| 541 | if (rssi_event == RSSI_EVENT_LOW || is_loose_coex()) | ||
| 542 | ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, | ||
| 543 | false); | ||
| 323 | else | 544 | else |
| 324 | bt_kill_msk = BT_KILL_MSK_DEFAULT; | 545 | ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true); |
| 325 | 546 | ||
| 326 | /* Don't send HCMD if there is no update */ | 547 | if (ret) |
| 327 | if (bt_kill_msk == mvm->bt_kill_msk) | 548 | IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n"); |
| 328 | return 0; | ||
| 329 | 549 | ||
| 330 | IWL_DEBUG_COEX(mvm, | 550 | ieee80211_iterate_active_interfaces_atomic( |
| 331 | "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", | 551 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, |
| 332 | bt_kill_msk, | 552 | iwl_mvm_bt_rssi_iterator, &data); |
| 333 | BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", | ||
| 334 | BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", | ||
| 335 | BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); | ||
| 336 | 553 | ||
| 337 | mvm->bt_kill_msk = bt_kill_msk; | 554 | /* |
| 338 | cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); | 555 | * If there are no BSS / P2P client interfaces, reduced Tx Power is |
| 339 | cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); | 556 | * irrelevant since it is based on the RSSI coming from the beacon. |
| 557 | * Use BT_KILL_MSK_DEFAULT in that case. | ||
| 558 | */ | ||
| 559 | data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; | ||
| 340 | 560 | ||
| 341 | cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); | 561 | if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) |
| 562 | IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); | ||
| 342 | 563 | ||
| 343 | if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) | 564 | out_unlock: |
| 344 | IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); | 565 | mutex_unlock(&mvm->mutex); |
| 566 | } | ||
| 345 | 567 | ||
| 346 | /* This handler is ASYNC */ | 568 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
| 347 | return 0; | 569 | { |
| 570 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 571 | enum ieee80211_band band; | ||
| 572 | |||
| 573 | rcu_read_lock(); | ||
| 574 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
| 575 | if (chanctx_conf && chanctx_conf->def.chan) | ||
| 576 | band = chanctx_conf->def.chan->band; | ||
| 577 | else | ||
| 578 | band = -1; | ||
| 579 | rcu_read_unlock(); | ||
| 580 | |||
| 581 | /* if we are in 2GHz we will get a notification from the fw */ | ||
| 582 | if (band == IEEE80211_BAND_2GHZ) | ||
| 583 | return; | ||
| 584 | |||
| 585 | /* else, we can remove all the constraints */ | ||
| 586 | memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); | ||
| 587 | |||
| 588 | iwl_mvm_bt_coex_notif_handle(mvm); | ||
| 348 | } | 589 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index bf087abe39f3..16bbdcc8627a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -769,7 +769,14 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 769 | struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; | 769 | struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; |
| 770 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; | 770 | struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; |
| 771 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; | 771 | struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; |
| 772 | struct iwl_d3_manager_config d3_cfg_cmd = {}; | 772 | struct iwl_d3_manager_config d3_cfg_cmd = { |
| 773 | /* | ||
| 774 | * Program the minimum sleep time to 10 seconds, as many | ||
| 775 | * platforms have issues processing a wakeup signal while | ||
| 776 | * still being in the process of suspending. | ||
| 777 | */ | ||
| 778 | .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), | ||
| 779 | }; | ||
| 773 | struct wowlan_key_data key_data = { | 780 | struct wowlan_key_data key_data = { |
| 774 | .use_rsc_tsc = false, | 781 | .use_rsc_tsc = false, |
| 775 | .tkip = &tkip_cmd, | 782 | .tkip = &tkip_cmd, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index b080b4ba5458..2053dccefcd6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
| @@ -300,6 +300,67 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, | |||
| 300 | return count; | 300 | return count; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | static ssize_t iwl_dbgfs_mac_params_read(struct file *file, | ||
| 304 | char __user *user_buf, | ||
| 305 | size_t count, loff_t *ppos) | ||
| 306 | { | ||
| 307 | struct ieee80211_vif *vif = file->private_data; | ||
| 308 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 309 | struct iwl_mvm *mvm = mvmvif->dbgfs_data; | ||
| 310 | u8 ap_sta_id; | ||
| 311 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 312 | char buf[512]; | ||
| 313 | int bufsz = sizeof(buf); | ||
| 314 | int pos = 0; | ||
| 315 | int i; | ||
| 316 | |||
| 317 | mutex_lock(&mvm->mutex); | ||
| 318 | |||
| 319 | ap_sta_id = mvmvif->ap_sta_id; | ||
| 320 | |||
| 321 | pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n", | ||
| 322 | mvmvif->id, mvmvif->color); | ||
| 323 | pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n", | ||
| 324 | vif->bss_conf.bssid); | ||
| 325 | pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n"); | ||
| 326 | for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) { | ||
| 327 | pos += scnprintf(buf+pos, bufsz-pos, | ||
| 328 | "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n", | ||
| 329 | i, mvmvif->queue_params[i].txop, | ||
| 330 | mvmvif->queue_params[i].cw_min, | ||
| 331 | mvmvif->queue_params[i].cw_max, | ||
| 332 | mvmvif->queue_params[i].aifs, | ||
| 333 | mvmvif->queue_params[i].uapsd); | ||
| 334 | } | ||
| 335 | |||
| 336 | if (vif->type == NL80211_IFTYPE_STATION && | ||
| 337 | ap_sta_id != IWL_MVM_STATION_COUNT) { | ||
| 338 | struct ieee80211_sta *sta; | ||
| 339 | struct iwl_mvm_sta *mvm_sta; | ||
| 340 | |||
| 341 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id], | ||
| 342 | lockdep_is_held(&mvm->mutex)); | ||
| 343 | mvm_sta = (void *)sta->drv_priv; | ||
| 344 | pos += scnprintf(buf+pos, bufsz-pos, | ||
| 345 | "ap_sta_id %d - reduced Tx power %d\n", | ||
| 346 | ap_sta_id, mvm_sta->bt_reduced_txpower); | ||
| 347 | } | ||
| 348 | |||
| 349 | rcu_read_lock(); | ||
| 350 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
| 351 | if (chanctx_conf) { | ||
| 352 | pos += scnprintf(buf+pos, bufsz-pos, | ||
| 353 | "idle rx chains %d, active rx chains: %d\n", | ||
| 354 | chanctx_conf->rx_chains_static, | ||
| 355 | chanctx_conf->rx_chains_dynamic); | ||
| 356 | } | ||
| 357 | rcu_read_unlock(); | ||
| 358 | |||
| 359 | mutex_unlock(&mvm->mutex); | ||
| 360 | |||
| 361 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
| 362 | } | ||
| 363 | |||
| 303 | #define BT_MBOX_MSG(_notif, _num, _field) \ | 364 | #define BT_MBOX_MSG(_notif, _num, _field) \ |
| 304 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ | 365 | ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ |
| 305 | >> BT_MBOX##_num##_##_field##_POS) | 366 | >> BT_MBOX##_num##_##_field##_POS) |
| @@ -464,6 +525,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); | |||
| 464 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); | 525 | MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); |
| 465 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); | 526 | MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); |
| 466 | 527 | ||
| 528 | /* Interface specific debugfs entries */ | ||
| 529 | MVM_DEBUGFS_READ_FILE_OPS(mac_params); | ||
| 530 | |||
| 467 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | 531 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) |
| 468 | { | 532 | { |
| 469 | char buf[100]; | 533 | char buf[100]; |
| @@ -494,3 +558,58 @@ err: | |||
| 494 | IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); | 558 | IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); |
| 495 | return -ENOMEM; | 559 | return -ENOMEM; |
| 496 | } | 560 | } |
| 561 | |||
| 562 | void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
| 563 | { | ||
| 564 | struct dentry *dbgfs_dir = vif->debugfs_dir; | ||
| 565 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 566 | char buf[100]; | ||
| 567 | |||
| 568 | if (!dbgfs_dir) | ||
| 569 | return; | ||
| 570 | |||
| 571 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); | ||
| 572 | mvmvif->dbgfs_data = mvm; | ||
| 573 | |||
| 574 | if (!mvmvif->dbgfs_dir) { | ||
| 575 | IWL_ERR(mvm, "Failed to create debugfs directory under %s\n", | ||
| 576 | dbgfs_dir->d_name.name); | ||
| 577 | return; | ||
| 578 | } | ||
| 579 | |||
| 580 | MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, | ||
| 581 | S_IRUSR); | ||
| 582 | |||
| 583 | /* | ||
| 584 | * Create symlink for convenience pointing to interface specific | ||
| 585 | * debugfs entries for the driver. For example, under | ||
| 586 | * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/ | ||
| 587 | * find | ||
| 588 | * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/ | ||
| 589 | */ | ||
| 590 | snprintf(buf, 100, "../../../%s/%s/%s/%s", | ||
| 591 | dbgfs_dir->d_parent->d_parent->d_name.name, | ||
| 592 | dbgfs_dir->d_parent->d_name.name, | ||
| 593 | dbgfs_dir->d_name.name, | ||
| 594 | mvmvif->dbgfs_dir->d_name.name); | ||
| 595 | |||
| 596 | mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name, | ||
| 597 | mvm->debugfs_dir, buf); | ||
| 598 | if (!mvmvif->dbgfs_slink) | ||
| 599 | IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n", | ||
| 600 | dbgfs_dir->d_name.name); | ||
| 601 | return; | ||
| 602 | err: | ||
| 603 | IWL_ERR(mvm, "Can't create debugfs entity\n"); | ||
| 604 | } | ||
| 605 | |||
| 606 | void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
| 607 | { | ||
| 608 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 609 | |||
| 610 | debugfs_remove(mvmvif->dbgfs_slink); | ||
| 611 | mvmvif->dbgfs_slink = NULL; | ||
| 612 | |||
| 613 | debugfs_remove_recursive(mvmvif->dbgfs_dir); | ||
| 614 | mvmvif->dbgfs_dir = NULL; | ||
| 615 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 127051891e9b..81fe45f46be7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
| @@ -68,73 +68,53 @@ | |||
| 68 | 68 | ||
| 69 | /** | 69 | /** |
| 70 | * enum iwl_scan_flags - masks for power table command flags | 70 | * enum iwl_scan_flags - masks for power table command flags |
| 71 | * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off | ||
| 72 | * receiver and transmitter. '0' - does not allow. | ||
| 71 | * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, | 73 | * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, |
| 72 | * '1' Driver enables PM (use rest of parameters) | 74 | * '1' Driver enables PM (use rest of parameters) |
| 73 | * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, | 75 | * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, |
| 74 | * '1' PM could sleep over DTIM till listen Interval. | 76 | * '1' PM could sleep over DTIM till listen Interval. |
| 75 | * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. | ||
| 76 | * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all | ||
| 77 | * access categories are both delivery and trigger enabled. | ||
| 78 | * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and | ||
| 79 | * PBW Snoozing enabled | ||
| 80 | * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask | 77 | * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask |
| 78 | * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. | ||
| 81 | */ | 79 | */ |
| 82 | enum iwl_power_flags { | 80 | enum iwl_power_flags { |
| 83 | POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0), | 81 | POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), |
| 84 | POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1), | 82 | POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1), |
| 85 | POWER_FLAGS_LPRX_ENA_MSK = BIT(2), | 83 | POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2), |
| 86 | POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3), | 84 | POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), |
| 87 | POWER_FLAGS_BT_SCO_ENA = BIT(4), | 85 | POWER_FLAGS_LPRX_ENA_MSK = BIT(11), |
| 88 | POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5) | ||
| 89 | }; | 86 | }; |
| 90 | 87 | ||
| 88 | #define IWL_POWER_VEC_SIZE 5 | ||
| 89 | |||
| 91 | /** | 90 | /** |
| 92 | * struct iwl_powertable_cmd - Power Table Command | 91 | * struct iwl_powertable_cmd - Power Table Command |
| 93 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) | 92 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) |
| 94 | * | 93 | * |
| 95 | * @id_and_color: MAC contex identifier | ||
| 96 | * @action: Action on context - no action, add new, | ||
| 97 | * modify existent, remove | ||
| 98 | * @flags: Power table command flags from POWER_FLAGS_* | 94 | * @flags: Power table command flags from POWER_FLAGS_* |
| 99 | * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. | 95 | * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. |
| 100 | * Minimum allowed:- 3 * DTIM | 96 | * Minimum allowed:- 3 * DTIM. Keep alive period must be |
| 97 | * set regardless of power scheme or current power state. | ||
| 98 | * FW use this value also when PM is disabled. | ||
| 101 | * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to | 99 | * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to |
| 102 | * PSM transition - legacy PM | 100 | * PSM transition - legacy PM |
| 103 | * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to | 101 | * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to |
| 104 | * PSM transition - legacy PM | 102 | * PSM transition - legacy PM |
| 105 | * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to | 103 | * @sleep_interval: not in use |
| 106 | * PSM transition - uAPSD | 104 | * @keep_alive_beacons: not in use |
| 107 | * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to | ||
| 108 | * PSM transition - uAPSD | ||
| 109 | * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. | 105 | * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. |
| 110 | * Default: 80dbm | 106 | * Default: 80dbm |
| 111 | * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set | ||
| 112 | * @snooze_interval: TBD | ||
| 113 | * @snooze_window: TBD | ||
| 114 | * @snooze_step: TBD | ||
| 115 | * @qndp_tid: TBD | ||
| 116 | * @uapsd_ac_flags: TBD | ||
| 117 | * @uapsd_max_sp: TBD | ||
| 118 | */ | 107 | */ |
| 119 | struct iwl_powertable_cmd { | 108 | struct iwl_powertable_cmd { |
| 120 | /* COMMON_INDEX_HDR_API_S_VER_1 */ | 109 | /* PM_POWER_TABLE_CMD_API_S_VER_5 */ |
| 121 | __le32 id_and_color; | ||
| 122 | __le32 action; | ||
| 123 | __le16 flags; | 110 | __le16 flags; |
| 124 | u8 reserved; | 111 | u8 keep_alive_seconds; |
| 125 | __le16 keep_alive_seconds; | 112 | u8 debug_flags; |
| 126 | __le32 rx_data_timeout; | 113 | __le32 rx_data_timeout; |
| 127 | __le32 tx_data_timeout; | 114 | __le32 tx_data_timeout; |
| 128 | __le32 rx_data_timeout_uapsd; | 115 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; |
| 129 | __le32 tx_data_timeout_uapsd; | 116 | __le32 keep_alive_beacons; |
| 130 | u8 lprx_rssi_threshold; | 117 | __le32 lprx_rssi_threshold; |
| 131 | u8 num_skip_dtim; | ||
| 132 | __le16 snooze_interval; | ||
| 133 | __le16 snooze_window; | ||
| 134 | u8 snooze_step; | ||
| 135 | u8 qndp_tid; | ||
| 136 | u8 uapsd_ac_flags; | ||
| 137 | u8 uapsd_max_sp; | ||
| 138 | } __packed; | 118 | } __packed; |
| 139 | 119 | ||
| 140 | #endif | 120 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 1073f2682221..191dcae8ba47 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
| @@ -480,15 +480,34 @@ enum { | |||
| 480 | TE_DEP_TSF = 2, | 480 | TE_DEP_TSF = 2, |
| 481 | TE_EVENT_SOCIOPATHIC = 4, | 481 | TE_EVENT_SOCIOPATHIC = 4, |
| 482 | }; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ | 482 | }; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ |
| 483 | 483 | /* | |
| 484 | /* When to send Time Event notifications and to whom (internal = FW) */ | 484 | * Supported Time event notifications configuration. |
| 485 | * A notification (both event and fragment) includes a status indicating weather | ||
| 486 | * the FW was able to schedule the event or not. For fragment start/end | ||
| 487 | * notification the status is always success. There is no start/end fragment | ||
| 488 | * notification for monolithic events. | ||
| 489 | * | ||
| 490 | * @TE_NOTIF_NONE: no notifications | ||
| 491 | * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start | ||
| 492 | * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end | ||
| 493 | * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use | ||
| 494 | * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use. | ||
| 495 | * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start | ||
| 496 | * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end | ||
| 497 | * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use. | ||
| 498 | * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use. | ||
| 499 | */ | ||
| 485 | enum { | 500 | enum { |
| 486 | TE_NOTIF_NONE = 0, | 501 | TE_NOTIF_NONE = 0, |
| 487 | TE_NOTIF_HOST_START = 0x1, | 502 | TE_NOTIF_HOST_EVENT_START = 0x1, |
| 488 | TE_NOTIF_HOST_END = 0x2, | 503 | TE_NOTIF_HOST_EVENT_END = 0x2, |
| 489 | TE_NOTIF_INTERNAL_START = 0x4, | 504 | TE_NOTIF_INTERNAL_EVENT_START = 0x4, |
| 490 | TE_NOTIF_INTERNAL_END = 0x8 | 505 | TE_NOTIF_INTERNAL_EVENT_END = 0x8, |
| 491 | }; /* MAC_EVENT_ACTION_API_E_VER_1 */ | 506 | TE_NOTIF_HOST_FRAG_START = 0x10, |
| 507 | TE_NOTIF_HOST_FRAG_END = 0x20, | ||
| 508 | TE_NOTIF_INTERNAL_FRAG_START = 0x40, | ||
| 509 | TE_NOTIF_INTERNAL_FRAG_END = 0x80 | ||
| 510 | }; /* MAC_EVENT_ACTION_API_E_VER_2 */ | ||
| 492 | 511 | ||
| 493 | /* | 512 | /* |
| 494 | * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. | 513 | * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 86e312a4f629..e6eca4d66f6c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
| @@ -669,6 +669,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, | |||
| 669 | u32 action) | 669 | u32 action) |
| 670 | { | 670 | { |
| 671 | struct iwl_mac_ctx_cmd cmd = {}; | 671 | struct iwl_mac_ctx_cmd cmd = {}; |
| 672 | struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr; | ||
| 672 | 673 | ||
| 673 | WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p); | 674 | WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p); |
| 674 | 675 | ||
| @@ -678,7 +679,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, | |||
| 678 | /* Fill the data specific for station mode */ | 679 | /* Fill the data specific for station mode */ |
| 679 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); | 680 | iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); |
| 680 | 681 | ||
| 681 | cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); | 682 | cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & |
| 683 | IEEE80211_P2P_OPPPS_CTWINDOW_MASK); | ||
| 682 | 684 | ||
| 683 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); | 685 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); |
| 684 | } | 686 | } |
| @@ -919,6 +921,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
| 919 | u32 action) | 921 | u32 action) |
| 920 | { | 922 | { |
| 921 | struct iwl_mac_ctx_cmd cmd = {}; | 923 | struct iwl_mac_ctx_cmd cmd = {}; |
| 924 | struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr; | ||
| 922 | 925 | ||
| 923 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); | 926 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); |
| 924 | 927 | ||
| @@ -929,8 +932,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
| 929 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, | 932 | iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, |
| 930 | action == FW_CTXT_ACTION_ADD); | 933 | action == FW_CTXT_ACTION_ADD); |
| 931 | 934 | ||
| 932 | cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); | 935 | cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow & |
| 933 | cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); | 936 | IEEE80211_P2P_OPPPS_CTWINDOW_MASK); |
| 937 | cmd.go.opp_ps_enabled = | ||
| 938 | cpu_to_le32(!!(noa->oppps_ctwindow & | ||
| 939 | IEEE80211_P2P_OPPPS_ENABLE_BIT)); | ||
| 934 | 940 | ||
| 935 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); | 941 | return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); |
| 936 | } | 942 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 3d193f8c33b6..fe031608fd91 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -502,11 +502,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 502 | /* | 502 | /* |
| 503 | * TODO: remove this temporary code. | 503 | * TODO: remove this temporary code. |
| 504 | * Currently MVM FW supports power management only on single MAC. | 504 | * Currently MVM FW supports power management only on single MAC. |
| 505 | * Iterate and disable PM on all active interfaces. | 505 | * If new interface added, disable PM on existing interface. |
| 506 | * P2P device is a special case, since it is handled by FW similary to | ||
| 507 | * scan. If P2P deviced is added, PM remains enabled on existing | ||
| 508 | * interface. | ||
| 506 | * Note: the method below does not count the new interface being added | 509 | * Note: the method below does not count the new interface being added |
| 507 | * at this moment. | 510 | * at this moment. |
| 508 | */ | 511 | */ |
| 509 | mvm->vif_count++; | 512 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) |
| 513 | mvm->vif_count++; | ||
| 510 | if (mvm->vif_count > 1) { | 514 | if (mvm->vif_count > 1) { |
| 511 | IWL_DEBUG_MAC80211(mvm, | 515 | IWL_DEBUG_MAC80211(mvm, |
| 512 | "Disable power on existing interfaces\n"); | 516 | "Disable power on existing interfaces\n"); |
| @@ -562,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 562 | mvm->p2p_device_vif = vif; | 566 | mvm->p2p_device_vif = vif; |
| 563 | } | 567 | } |
| 564 | 568 | ||
| 569 | iwl_mvm_vif_dbgfs_register(mvm, vif); | ||
| 565 | goto out_unlock; | 570 | goto out_unlock; |
| 566 | 571 | ||
| 567 | out_unbind: | 572 | out_unbind: |
| @@ -575,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 575 | /* | 580 | /* |
| 576 | * TODO: remove this temporary code. | 581 | * TODO: remove this temporary code. |
| 577 | * Currently MVM FW supports power management only on single MAC. | 582 | * Currently MVM FW supports power management only on single MAC. |
| 578 | * Check if only one additional interface remains after rereasing | 583 | * Check if only one additional interface remains after releasing |
| 579 | * current one. Update power mode on the remaining interface. | 584 | * current one. Update power mode on the remaining interface. |
| 580 | */ | 585 | */ |
| 581 | mvm->vif_count--; | 586 | if (vif->type != NL80211_IFTYPE_P2P_DEVICE) |
| 587 | mvm->vif_count--; | ||
| 582 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", | 588 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", |
| 583 | mvm->vif_count); | 589 | mvm->vif_count); |
| 584 | if (mvm->vif_count == 1) { | 590 | if (mvm->vif_count == 1) { |
| @@ -640,6 +646,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 640 | 646 | ||
| 641 | mutex_lock(&mvm->mutex); | 647 | mutex_lock(&mvm->mutex); |
| 642 | 648 | ||
| 649 | iwl_mvm_vif_dbgfs_clean(mvm, vif); | ||
| 650 | |||
| 643 | /* | 651 | /* |
| 644 | * For AP/GO interface, the tear down of the resources allocated to the | 652 | * For AP/GO interface, the tear down of the resources allocated to the |
| 645 | * interface is be handled as part of the stop_ap flow. | 653 | * interface is be handled as part of the stop_ap flow. |
| @@ -663,7 +671,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 663 | * Check if only one additional interface remains after removing | 671 | * Check if only one additional interface remains after removing |
| 664 | * current one. Update power mode on the remaining interface. | 672 | * current one. Update power mode on the remaining interface. |
| 665 | */ | 673 | */ |
| 666 | if (mvm->vif_count) | 674 | if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) |
| 667 | mvm->vif_count--; | 675 | mvm->vif_count--; |
| 668 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", | 676 | IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", |
| 669 | mvm->vif_count); | 677 | mvm->vif_count); |
| @@ -713,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
| 713 | IWL_ERR(mvm, "failed to update quotas\n"); | 721 | IWL_ERR(mvm, "failed to update quotas\n"); |
| 714 | return; | 722 | return; |
| 715 | } | 723 | } |
| 724 | iwl_mvm_bt_coex_vif_assoc(mvm, vif); | ||
| 716 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 725 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
| 717 | /* remove AP station now that the MAC is unassoc */ | 726 | /* remove AP station now that the MAC is unassoc */ |
| 718 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); | 727 | ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); |
| @@ -931,7 +940,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, | |||
| 931 | */ | 940 | */ |
| 932 | break; | 941 | break; |
| 933 | case STA_NOTIFY_AWAKE: | 942 | case STA_NOTIFY_AWAKE: |
| 934 | if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) | 943 | if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) |
| 935 | break; | 944 | break; |
| 936 | iwl_mvm_sta_modify_ps_wake(mvm, sta); | 945 | iwl_mvm_sta_modify_ps_wake(mvm, sta); |
| 937 | break; | 946 | break; |
| @@ -1326,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw, | |||
| 1326 | return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); | 1335 | return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); |
| 1327 | } | 1336 | } |
| 1328 | 1337 | ||
| 1338 | static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw, | ||
| 1339 | struct ieee80211_vif *vif, | ||
| 1340 | enum ieee80211_rssi_event rssi_event) | ||
| 1341 | { | ||
| 1342 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
| 1343 | |||
| 1344 | iwl_mvm_bt_rssi_event(mvm, vif, rssi_event); | ||
| 1345 | } | ||
| 1346 | |||
| 1329 | struct ieee80211_ops iwl_mvm_hw_ops = { | 1347 | struct ieee80211_ops iwl_mvm_hw_ops = { |
| 1330 | .tx = iwl_mvm_mac_tx, | 1348 | .tx = iwl_mvm_mac_tx, |
| 1331 | .ampdu_action = iwl_mvm_mac_ampdu_action, | 1349 | .ampdu_action = iwl_mvm_mac_ampdu_action, |
| @@ -1349,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = { | |||
| 1349 | .update_tkip_key = iwl_mvm_mac_update_tkip_key, | 1367 | .update_tkip_key = iwl_mvm_mac_update_tkip_key, |
| 1350 | .remain_on_channel = iwl_mvm_roc, | 1368 | .remain_on_channel = iwl_mvm_roc, |
| 1351 | .cancel_remain_on_channel = iwl_mvm_cancel_roc, | 1369 | .cancel_remain_on_channel = iwl_mvm_cancel_roc, |
| 1370 | .rssi_callback = iwl_mvm_mac_rssi_callback, | ||
| 1352 | 1371 | ||
| 1353 | .add_chanctx = iwl_mvm_add_chanctx, | 1372 | .add_chanctx = iwl_mvm_add_chanctx, |
| 1354 | .remove_chanctx = iwl_mvm_remove_chanctx, | 1373 | .remove_chanctx = iwl_mvm_remove_chanctx, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 53d58968e30a..8269bc562951 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
| @@ -212,6 +212,7 @@ struct iwl_mvm_vif { | |||
| 212 | 212 | ||
| 213 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 213 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 214 | struct dentry *dbgfs_dir; | 214 | struct dentry *dbgfs_dir; |
| 215 | struct dentry *dbgfs_slink; | ||
| 215 | void *dbgfs_data; | 216 | void *dbgfs_data; |
| 216 | #endif | 217 | #endif |
| 217 | }; | 218 | }; |
| @@ -321,6 +322,13 @@ struct iwl_mvm { | |||
| 321 | * can hold 16 keys at most. Reflect this fact. | 322 | * can hold 16 keys at most. Reflect this fact. |
| 322 | */ | 323 | */ |
| 323 | unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; | 324 | unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; |
| 325 | |||
| 326 | /* | ||
| 327 | * This counter of created interfaces is referenced only in conjunction | ||
| 328 | * with FW limitation related to power management. Currently PM is | ||
| 329 | * supported only on a single interface. | ||
| 330 | * IMPORTANT: this variable counts all interfaces except P2P device. | ||
| 331 | */ | ||
| 324 | u8 vif_count; | 332 | u8 vif_count; |
| 325 | 333 | ||
| 326 | struct led_classdev led; | 334 | struct led_classdev led; |
| @@ -471,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); | |||
| 471 | /* MVM debugfs */ | 479 | /* MVM debugfs */ |
| 472 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 480 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 473 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); | 481 | int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); |
| 474 | int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 482 | void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 475 | struct dentry *dbgfs_dir); | 483 | void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 476 | void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 477 | struct iwl_powertable_cmd *cmd); | ||
| 478 | #else | 484 | #else |
| 479 | static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, | 485 | static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, |
| 480 | struct dentry *dbgfs_dir) | 486 | struct dentry *dbgfs_dir) |
| 481 | { | 487 | { |
| 482 | return 0; | 488 | return 0; |
| 483 | } | 489 | } |
| 490 | static inline void | ||
| 491 | iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
| 492 | { | ||
| 493 | } | ||
| 494 | static inline void | ||
| 495 | iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
| 496 | { | ||
| 497 | } | ||
| 484 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 498 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
| 485 | 499 | ||
| 486 | /* rate scaling */ | 500 | /* rate scaling */ |
| @@ -490,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, | |||
| 490 | /* power managment */ | 504 | /* power managment */ |
| 491 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 505 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 492 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 506 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
| 507 | void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 508 | struct iwl_powertable_cmd *cmd); | ||
| 493 | 509 | ||
| 494 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); | 510 | int iwl_mvm_leds_init(struct iwl_mvm *mvm); |
| 495 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); | 511 | void iwl_mvm_leds_exit(struct iwl_mvm *mvm); |
| @@ -513,5 +529,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm); | |||
| 513 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | 529 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, |
| 514 | struct iwl_rx_cmd_buffer *rxb, | 530 | struct iwl_rx_cmd_buffer *rxb, |
| 515 | struct iwl_device_cmd *cmd); | 531 | struct iwl_device_cmd *cmd); |
| 532 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 533 | enum ieee80211_rssi_event rssi_event); | ||
| 534 | void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | ||
| 516 | 535 | ||
| 517 | #endif /* __IWL_MVM_H__ */ | 536 | #endif /* __IWL_MVM_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index efb9a6f3faac..9395ab2a1af2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
| @@ -75,23 +75,49 @@ | |||
| 75 | 75 | ||
| 76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 | 76 | #define POWER_KEEP_ALIVE_PERIOD_SEC 25 |
| 77 | 77 | ||
| 78 | static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 78 | static void iwl_mvm_power_log(struct iwl_mvm *mvm, |
| 79 | struct iwl_powertable_cmd *cmd) | 79 | struct iwl_powertable_cmd *cmd) |
| 80 | { | ||
| 81 | IWL_DEBUG_POWER(mvm, | ||
| 82 | "Sending power table command for power level %d, flags = 0x%X\n", | ||
| 83 | iwlmvm_mod_params.power_scheme, | ||
| 84 | le16_to_cpu(cmd->flags)); | ||
| 85 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); | ||
| 86 | |||
| 87 | if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
| 88 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | ||
| 89 | le32_to_cpu(cmd->rx_data_timeout)); | ||
| 90 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
| 91 | le32_to_cpu(cmd->tx_data_timeout)); | ||
| 92 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
| 93 | cmd->lprx_rssi_threshold); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 98 | struct iwl_powertable_cmd *cmd) | ||
| 80 | { | 99 | { |
| 81 | struct ieee80211_hw *hw = mvm->hw; | 100 | struct ieee80211_hw *hw = mvm->hw; |
| 82 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 83 | struct ieee80211_chanctx_conf *chanctx_conf; | 101 | struct ieee80211_chanctx_conf *chanctx_conf; |
| 84 | struct ieee80211_channel *chan; | 102 | struct ieee80211_channel *chan; |
| 85 | int dtimper, dtimper_msec; | 103 | int dtimper, dtimper_msec; |
| 86 | int keep_alive; | 104 | int keep_alive; |
| 87 | bool radar_detect = false; | 105 | bool radar_detect = false; |
| 88 | 106 | ||
| 89 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 107 | /* |
| 90 | mvmvif->color)); | 108 | * Regardless of power management state the driver must set |
| 91 | cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); | 109 | * keep alive period. FW will use it for sending keep alive NDPs |
| 110 | * immediately after association. | ||
| 111 | */ | ||
| 112 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; | ||
| 113 | |||
| 114 | if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) || | ||
| 115 | !iwlwifi_mod_params.power_save) | ||
| 116 | return; | ||
| 117 | |||
| 118 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | ||
| 92 | 119 | ||
| 93 | if ((!vif->bss_conf.ps) || | 120 | if (!vif->bss_conf.ps) |
| 94 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)) | ||
| 95 | return; | 121 | return; |
| 96 | 122 | ||
| 97 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | 123 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); |
| @@ -110,26 +136,23 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 110 | 136 | ||
| 111 | /* Check skip over DTIM conditions */ | 137 | /* Check skip over DTIM conditions */ |
| 112 | if (!radar_detect && (dtimper <= 10) && | 138 | if (!radar_detect && (dtimper <= 10) && |
| 113 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { | 139 | (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) |
| 114 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); | 140 | cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); |
| 115 | cmd->num_skip_dtim = 2; | ||
| 116 | } | ||
| 117 | 141 | ||
| 118 | /* Check that keep alive period is at least 3 * DTIM */ | 142 | /* Check that keep alive period is at least 3 * DTIM */ |
| 119 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; | 143 | dtimper_msec = dtimper * vif->bss_conf.beacon_int; |
| 120 | keep_alive = max_t(int, 3 * dtimper_msec, | 144 | keep_alive = max_t(int, 3 * dtimper_msec, |
| 121 | MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); | 145 | MSEC_PER_SEC * cmd->keep_alive_seconds); |
| 122 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | 146 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); |
| 123 | 147 | cmd->keep_alive_seconds = keep_alive; | |
| 124 | cmd->keep_alive_seconds = cpu_to_le16(keep_alive); | ||
| 125 | 148 | ||
| 126 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { | 149 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { |
| 127 | /* TODO: Also for D3 (device sleep / WoWLAN) */ | 150 | /* TODO: Also for D3 (device sleep / WoWLAN) */ |
| 128 | cmd->rx_data_timeout = cpu_to_le32(10); | 151 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
| 129 | cmd->tx_data_timeout = cpu_to_le32(10); | 152 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); |
| 130 | } else { | 153 | } else { |
| 131 | cmd->rx_data_timeout = cpu_to_le32(50); | 154 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
| 132 | cmd->tx_data_timeout = cpu_to_le32(50); | 155 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
| 133 | } | 156 | } |
| 134 | } | 157 | } |
| 135 | 158 | ||
| @@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 137 | { | 160 | { |
| 138 | struct iwl_powertable_cmd cmd = {}; | 161 | struct iwl_powertable_cmd cmd = {}; |
| 139 | 162 | ||
| 140 | if (!iwlwifi_mod_params.power_save) { | ||
| 141 | IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 163 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
| 146 | return 0; | 164 | return 0; |
| 147 | 165 | ||
| 148 | iwl_power_build_cmd(mvm, vif, &cmd); | 166 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
| 149 | 167 | iwl_mvm_power_log(mvm, &cmd); | |
| 150 | IWL_DEBUG_POWER(mvm, | ||
| 151 | "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", | ||
| 152 | cmd.id_and_color, iwlmvm_mod_params.power_scheme, | ||
| 153 | le16_to_cpu(cmd.flags)); | ||
| 154 | |||
| 155 | if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { | ||
| 156 | IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", | ||
| 157 | le16_to_cpu(cmd.keep_alive_seconds)); | ||
| 158 | IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", | ||
| 159 | le32_to_cpu(cmd.rx_data_timeout)); | ||
| 160 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
| 161 | le32_to_cpu(cmd.tx_data_timeout)); | ||
| 162 | IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n", | ||
| 163 | le32_to_cpu(cmd.rx_data_timeout_uapsd)); | ||
| 164 | IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", | ||
| 165 | le32_to_cpu(cmd.tx_data_timeout_uapsd)); | ||
| 166 | IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", | ||
| 167 | cmd.lprx_rssi_threshold); | ||
| 168 | IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim); | ||
| 169 | } | ||
| 170 | 168 | ||
| 171 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, | 169 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, |
| 172 | sizeof(cmd), &cmd); | 170 | sizeof(cmd), &cmd); |
| @@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 175 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 173 | int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
| 176 | { | 174 | { |
| 177 | struct iwl_powertable_cmd cmd = {}; | 175 | struct iwl_powertable_cmd cmd = {}; |
| 178 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
| 179 | |||
| 180 | if (!iwlwifi_mod_params.power_save) { | ||
| 181 | IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); | ||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | 176 | ||
| 185 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 177 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
| 186 | return 0; | 178 | return 0; |
| 187 | 179 | ||
| 188 | cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 180 | if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) && |
| 189 | mvmvif->color)); | 181 | iwlwifi_mod_params.power_save) |
| 190 | cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); | 182 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
| 191 | 183 | ||
| 192 | IWL_DEBUG_POWER(mvm, | 184 | iwl_mvm_power_log(mvm, &cmd); |
| 193 | "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", | ||
| 194 | cmd.id_and_color, iwlmvm_mod_params.power_scheme, | ||
| 195 | le16_to_cpu(cmd.flags)); | ||
| 196 | 185 | ||
| 197 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, | 186 | return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, |
| 198 | sizeof(cmd), &cmd); | 187 | sizeof(cmd), &cmd); |
| 199 | } | 188 | } |
| 200 | |||
| 201 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
| 202 | void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
| 203 | struct iwl_powertable_cmd *cmd) | ||
| 204 | { | ||
| 205 | iwl_power_build_cmd(mvm, vif, cmd); | ||
| 206 | } | ||
| 207 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index a01a6612677e..55334d542e26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
| @@ -793,7 +793,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
| 793 | 793 | ||
| 794 | if (num_of_ant(tbl->ant_type) > 1) | 794 | if (num_of_ant(tbl->ant_type) > 1) |
| 795 | tbl->ant_type = | 795 | tbl->ant_type = |
| 796 | first_antenna(mvm->nvm_data->valid_tx_ant); | 796 | first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
| 797 | 797 | ||
| 798 | tbl->is_ht40 = 0; | 798 | tbl->is_ht40 = 0; |
| 799 | tbl->is_SGI = 0; | 799 | tbl->is_SGI = 0; |
| @@ -1235,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, | |||
| 1235 | return -1; | 1235 | return -1; |
| 1236 | 1236 | ||
| 1237 | /* Need both Tx chains/antennas to support MIMO */ | 1237 | /* Need both Tx chains/antennas to support MIMO */ |
| 1238 | if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2) | 1238 | if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2) |
| 1239 | return -1; | 1239 | return -1; |
| 1240 | 1240 | ||
| 1241 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); | 1241 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); |
| @@ -1287,7 +1287,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm, | |||
| 1287 | return -1; | 1287 | return -1; |
| 1288 | 1288 | ||
| 1289 | /* Need both Tx chains/antennas to support MIMO */ | 1289 | /* Need both Tx chains/antennas to support MIMO */ |
| 1290 | if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3) | 1290 | if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3) |
| 1291 | return -1; | 1291 | return -1; |
| 1292 | 1292 | ||
| 1293 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); | 1293 | IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); |
| @@ -1381,7 +1381,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm, | |||
| 1381 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1381 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
| 1382 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1382 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
| 1383 | u8 start_action; | 1383 | u8 start_action; |
| 1384 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1384 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 1385 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1385 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
| 1386 | int ret; | 1386 | int ret; |
| 1387 | u8 update_search_tbl_counter = 0; | 1387 | u8 update_search_tbl_counter = 0; |
| @@ -1514,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, | |||
| 1514 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1514 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
| 1515 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1515 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
| 1516 | u8 start_action; | 1516 | u8 start_action; |
| 1517 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1517 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 1518 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1518 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
| 1519 | u8 update_search_tbl_counter = 0; | 1519 | u8 update_search_tbl_counter = 0; |
| 1520 | int ret; | 1520 | int ret; |
| @@ -1649,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, | |||
| 1649 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1649 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
| 1650 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1650 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
| 1651 | u8 start_action; | 1651 | u8 start_action; |
| 1652 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1652 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 1653 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1653 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
| 1654 | u8 update_search_tbl_counter = 0; | 1654 | u8 update_search_tbl_counter = 0; |
| 1655 | int ret; | 1655 | int ret; |
| @@ -1786,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm, | |||
| 1786 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1786 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
| 1787 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1787 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
| 1788 | u8 start_action; | 1788 | u8 start_action; |
| 1789 | u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 1789 | u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 1790 | u8 tx_chains_num = num_of_ant(valid_tx_ant); | 1790 | u8 tx_chains_num = num_of_ant(valid_tx_ant); |
| 1791 | int ret; | 1791 | int ret; |
| 1792 | u8 update_search_tbl_counter = 0; | 1792 | u8 update_search_tbl_counter = 0; |
| @@ -2449,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
| 2449 | 2449 | ||
| 2450 | i = lq_sta->last_txrate_idx; | 2450 | i = lq_sta->last_txrate_idx; |
| 2451 | 2451 | ||
| 2452 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2452 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 2453 | 2453 | ||
| 2454 | if (!lq_sta->search_better_tbl) | 2454 | if (!lq_sta->search_better_tbl) |
| 2455 | active_tbl = lq_sta->active_tbl; | 2455 | active_tbl = lq_sta->active_tbl; |
| @@ -2639,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
| 2639 | 2639 | ||
| 2640 | /* These values will be overridden later */ | 2640 | /* These values will be overridden later */ |
| 2641 | lq_sta->lq.single_stream_ant_msk = | 2641 | lq_sta->lq.single_stream_ant_msk = |
| 2642 | first_antenna(mvm->nvm_data->valid_tx_ant); | 2642 | first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
| 2643 | lq_sta->lq.dual_stream_ant_msk = | 2643 | lq_sta->lq.dual_stream_ant_msk = |
| 2644 | mvm->nvm_data->valid_tx_ant & | 2644 | iwl_fw_valid_tx_ant(mvm->fw) & |
| 2645 | ~first_antenna(mvm->nvm_data->valid_tx_ant); | 2645 | ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); |
| 2646 | if (!lq_sta->lq.dual_stream_ant_msk) { | 2646 | if (!lq_sta->lq.dual_stream_ant_msk) { |
| 2647 | lq_sta->lq.dual_stream_ant_msk = ANT_AB; | 2647 | lq_sta->lq.dual_stream_ant_msk = ANT_AB; |
| 2648 | } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) { | 2648 | } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) { |
| 2649 | lq_sta->lq.dual_stream_ant_msk = | 2649 | lq_sta->lq.dual_stream_ant_msk = |
| 2650 | mvm->nvm_data->valid_tx_ant; | 2650 | iwl_fw_valid_tx_ant(mvm->fw); |
| 2651 | } | 2651 | } |
| 2652 | 2652 | ||
| 2653 | /* as default allow aggregation for all tids */ | 2653 | /* as default allow aggregation for all tids */ |
| @@ -2708,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, | |||
| 2708 | index++; | 2708 | index++; |
| 2709 | repeat_rate--; | 2709 | repeat_rate--; |
| 2710 | if (mvm) | 2710 | if (mvm) |
| 2711 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2711 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 2712 | 2712 | ||
| 2713 | /* Fill rest of rate table */ | 2713 | /* Fill rest of rate table */ |
| 2714 | while (index < LINK_QUAL_MAX_RETRY_NUM) { | 2714 | while (index < LINK_QUAL_MAX_RETRY_NUM) { |
| @@ -2813,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
| 2813 | u8 ant_sel_tx; | 2813 | u8 ant_sel_tx; |
| 2814 | 2814 | ||
| 2815 | mvm = lq_sta->drv; | 2815 | mvm = lq_sta->drv; |
| 2816 | valid_tx_ant = mvm->nvm_data->valid_tx_ant; | 2816 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
| 2817 | if (lq_sta->dbg_fixed_rate) { | 2817 | if (lq_sta->dbg_fixed_rate) { |
| 2818 | ant_sel_tx = | 2818 | ant_sel_tx = |
| 2819 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) | 2819 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) |
| @@ -2884,9 +2884,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
| 2884 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 2884 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
| 2885 | lq_sta->dbg_fixed_rate); | 2885 | lq_sta->dbg_fixed_rate); |
| 2886 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 2886 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
| 2887 | (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", | 2887 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "", |
| 2888 | (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", | 2888 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", |
| 2889 | (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); | 2889 | (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); |
| 2890 | desc += sprintf(buff+desc, "lq type %s\n", | 2890 | desc += sprintf(buff+desc, "lq type %s\n", |
| 2891 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); | 2891 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); |
| 2892 | if (is_Ht(tbl->lq_type)) { | 2892 | if (is_Ht(tbl->lq_type)) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 4d872d69577f..0fd96e4da461 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -945,7 +945,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, | |||
| 945 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) | 945 | mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) |
| 946 | return mvmvif->ap_sta_id; | 946 | return mvmvif->ap_sta_id; |
| 947 | 947 | ||
| 948 | return IWL_INVALID_STATION; | 948 | return IWL_MVM_STATION_COUNT; |
| 949 | } | 949 | } |
| 950 | 950 | ||
| 951 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, | 951 | static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, |
| @@ -1093,7 +1093,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, | |||
| 1093 | 1093 | ||
| 1094 | /* Get the station id from the mvm local station table */ | 1094 | /* Get the station id from the mvm local station table */ |
| 1095 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1095 | sta_id = iwl_mvm_get_key_sta_id(vif, sta); |
| 1096 | if (sta_id == IWL_INVALID_STATION) { | 1096 | if (sta_id == IWL_MVM_STATION_COUNT) { |
| 1097 | IWL_ERR(mvm, "Failed to find station id\n"); | 1097 | IWL_ERR(mvm, "Failed to find station id\n"); |
| 1098 | return -EINVAL; | 1098 | return -EINVAL; |
| 1099 | } | 1099 | } |
| @@ -1188,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, | |||
| 1188 | return -ENOENT; | 1188 | return -ENOENT; |
| 1189 | } | 1189 | } |
| 1190 | 1190 | ||
| 1191 | if (sta_id == IWL_INVALID_STATION) { | 1191 | if (sta_id == IWL_MVM_STATION_COUNT) { |
| 1192 | IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); | 1192 | IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); |
| 1193 | return 0; | 1193 | return 0; |
| 1194 | } | 1194 | } |
| @@ -1254,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, | |||
| 1254 | struct iwl_mvm_sta *mvm_sta; | 1254 | struct iwl_mvm_sta *mvm_sta; |
| 1255 | u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); | 1255 | u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); |
| 1256 | 1256 | ||
| 1257 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | 1257 | if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) |
| 1258 | return; | 1258 | return; |
| 1259 | 1259 | ||
| 1260 | rcu_read_lock(); | 1260 | rcu_read_lock(); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index b0352df981e4..12abd2d71835 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
| @@ -271,6 +271,7 @@ struct iwl_mvm_tid_data { | |||
| 271 | * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for | 271 | * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for |
| 272 | * tid. | 272 | * tid. |
| 273 | * @max_agg_bufsize: the maximal size of the AGG buffer for this station | 273 | * @max_agg_bufsize: the maximal size of the AGG buffer for this station |
| 274 | * @bt_reduced_txpower: is reduced tx power enabled for this station | ||
| 274 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx | 275 | * @lock: lock to protect the whole struct. Since %tid_data is access from Tx |
| 275 | * and from Tx response flow, it needs a spinlock. | 276 | * and from Tx response flow, it needs a spinlock. |
| 276 | * @pending_frames: number of frames for this STA on the shared Tx queues. | 277 | * @pending_frames: number of frames for this STA on the shared Tx queues. |
| @@ -287,6 +288,7 @@ struct iwl_mvm_sta { | |||
| 287 | u32 mac_id_n_color; | 288 | u32 mac_id_n_color; |
| 288 | u16 tid_disable_agg; | 289 | u16 tid_disable_agg; |
| 289 | u8 max_agg_bufsize; | 290 | u8 max_agg_bufsize; |
| 291 | bool bt_reduced_txpower; | ||
| 290 | spinlock_t lock; | 292 | spinlock_t lock; |
| 291 | atomic_t pending_frames; | 293 | atomic_t pending_frames; |
| 292 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; | 294 | struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 4dc934bed055..ad9bbca99213 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
| @@ -166,7 +166,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
| 166 | WARN_ONCE(!le32_to_cpu(notif->status), | 166 | WARN_ONCE(!le32_to_cpu(notif->status), |
| 167 | "Failed to schedule time event\n"); | 167 | "Failed to schedule time event\n"); |
| 168 | 168 | ||
| 169 | if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) { | 169 | if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { |
| 170 | IWL_DEBUG_TE(mvm, | 170 | IWL_DEBUG_TE(mvm, |
| 171 | "TE ended - current time %lu, estimated end %lu\n", | 171 | "TE ended - current time %lu, estimated end %lu\n", |
| 172 | jiffies, te_data->end_jiffies); | 172 | jiffies, te_data->end_jiffies); |
| @@ -189,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | iwl_mvm_te_clear_data(mvm, te_data); | 191 | iwl_mvm_te_clear_data(mvm, te_data); |
| 192 | } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { | 192 | } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { |
| 193 | te_data->running = true; | 193 | te_data->running = true; |
| 194 | te_data->end_jiffies = jiffies + | 194 | te_data->end_jiffies = jiffies + |
| 195 | TU_TO_JIFFIES(te_data->duration); | 195 | TU_TO_JIFFIES(te_data->duration); |
| @@ -368,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
| 368 | time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); | 368 | time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); |
| 369 | time_cmd.duration = cpu_to_le32(duration); | 369 | time_cmd.duration = cpu_to_le32(duration); |
| 370 | time_cmd.repeat = cpu_to_le32(1); | 370 | time_cmd.repeat = cpu_to_le32(1); |
| 371 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); | 371 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | |
| 372 | TE_NOTIF_HOST_EVENT_END); | ||
| 372 | 373 | ||
| 373 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 374 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
| 374 | } | 375 | } |
| @@ -485,7 +486,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 485 | time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); | 486 | time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); |
| 486 | time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); | 487 | time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); |
| 487 | time_cmd.repeat = cpu_to_le32(1); | 488 | time_cmd.repeat = cpu_to_le32(1); |
| 488 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); | 489 | time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | |
| 490 | TE_NOTIF_HOST_EVENT_END); | ||
| 489 | 491 | ||
| 490 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 492 | return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); |
| 491 | } | 493 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 0acc0bff43c7..479074303bd7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -205,7 +205,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, | |||
| 205 | rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); | 205 | rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); |
| 206 | 206 | ||
| 207 | mvm->mgmt_last_antenna_idx = | 207 | mvm->mgmt_last_antenna_idx = |
| 208 | iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, | 208 | iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), |
| 209 | mvm->mgmt_last_antenna_idx); | 209 | mvm->mgmt_last_antenna_idx); |
| 210 | rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; | 210 | rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; |
| 211 | 211 | ||
| @@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 365 | if (WARN_ON_ONCE(!mvmsta)) | 365 | if (WARN_ON_ONCE(!mvmsta)) |
| 366 | return -1; | 366 | return -1; |
| 367 | 367 | ||
| 368 | if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION)) | 368 | if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) |
| 369 | return -1; | 369 | return -1; |
| 370 | 370 | ||
| 371 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); | 371 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); |
| @@ -641,10 +641,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | IWL_DEBUG_TX_REPLY(mvm, | 643 | IWL_DEBUG_TX_REPLY(mvm, |
| 644 | "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x " | 644 | "TXQ %d status %s (0x%08x)\n", |
| 645 | "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", | 645 | txq_id, iwl_mvm_get_tx_fail_reason(status), status); |
| 646 | txq_id, iwl_mvm_get_tx_fail_reason(status), | 646 | |
| 647 | status, le32_to_cpu(tx_resp->initial_rate), | 647 | IWL_DEBUG_TX_REPLY(mvm, |
| 648 | "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", | ||
| 649 | le32_to_cpu(tx_resp->initial_rate), | ||
| 648 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), | 650 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), |
| 649 | ssn, next_reclaimed, seq_ctl); | 651 | ssn, next_reclaimed, seq_ctl); |
| 650 | 652 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index e308ad93aa9e..0cc8d8c0d393 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -462,7 +462,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, | |||
| 462 | .data = { lq, }, | 462 | .data = { lq, }, |
| 463 | }; | 463 | }; |
| 464 | 464 | ||
| 465 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) | 465 | if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT)) |
| 466 | return -EINVAL; | 466 | return -EINVAL; |
| 467 | 467 | ||
| 468 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) | 468 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 46ca91f77c9c..0016bb24b3d7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -241,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 241 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | 241 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, |
| 242 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | 242 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, |
| 243 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, | 243 | {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, |
| 244 | {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, | ||
| 244 | 245 | ||
| 245 | /* 105 Series */ | 246 | /* 105 Series */ |
| 246 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | 247 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 68466ca80770..c5e30294c5ac 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
| @@ -1061,7 +1061,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
| 1061 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 1061 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); |
| 1062 | 1062 | ||
| 1063 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 1063 | /* If this queue is mapped to a certain station: it is an AGG queue */ |
| 1064 | if (sta_id != IWL_INVALID_STATION) { | 1064 | if (sta_id >= 0) { |
| 1065 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 1065 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); |
| 1066 | 1066 | ||
| 1067 | /* Map receiver-address / traffic-ID to this queue */ | 1067 | /* Map receiver-address / traffic-ID to this queue */ |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 7001856241e6..088de9d25c39 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
| @@ -412,9 +412,9 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 412 | struct ieee80211_conf *conf = &hw->conf; | 412 | struct ieee80211_conf *conf = &hw->conf; |
| 413 | lbtf_deb_enter(LBTF_DEB_MACOPS); | 413 | lbtf_deb_enter(LBTF_DEB_MACOPS); |
| 414 | 414 | ||
| 415 | if (conf->channel->center_freq != priv->cur_freq) { | 415 | if (conf->chandef.chan->center_freq != priv->cur_freq) { |
| 416 | priv->cur_freq = conf->channel->center_freq; | 416 | priv->cur_freq = conf->chandef.chan->center_freq; |
| 417 | lbtf_set_channel(priv, conf->channel->hw_value); | 417 | lbtf_set_channel(priv, conf->chandef.chan->hw_value); |
| 418 | } | 418 | } |
| 419 | lbtf_deb_leave(LBTF_DEB_MACOPS); | 419 | lbtf_deb_leave(LBTF_DEB_MACOPS); |
| 420 | return 0; | 420 | return 0; |
| @@ -537,7 +537,7 @@ static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 537 | if (idx != 0) | 537 | if (idx != 0) |
| 538 | return -ENOENT; | 538 | return -ENOENT; |
| 539 | 539 | ||
| 540 | survey->channel = conf->channel; | 540 | survey->channel = conf->chandef.chan; |
| 541 | survey->filled = SURVEY_INFO_NOISE_DBM; | 541 | survey->filled = SURVEY_INFO_NOISE_DBM; |
| 542 | survey->noise = priv->noise; | 542 | survey->noise = priv->noise; |
| 543 | 543 | ||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 0064d38276bf..b878a32e7a98 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/if_arp.h> | 25 | #include <linux/if_arp.h> |
| 26 | #include <linux/rtnetlink.h> | 26 | #include <linux/rtnetlink.h> |
| 27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 28 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/debugfs.h> | 29 | #include <linux/debugfs.h> |
| 29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 30 | #include <linux/ktime.h> | 31 | #include <linux/ktime.h> |
| @@ -52,6 +53,10 @@ static bool paged_rx = false; | |||
| 52 | module_param(paged_rx, bool, 0644); | 53 | module_param(paged_rx, bool, 0644); |
| 53 | MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones"); | 54 | MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones"); |
| 54 | 55 | ||
| 56 | static bool rctbl = false; | ||
| 57 | module_param(rctbl, bool, 0444); | ||
| 58 | MODULE_PARM_DESC(rctbl, "Handle rate control table"); | ||
| 59 | |||
| 55 | /** | 60 | /** |
| 56 | * enum hwsim_regtest - the type of regulatory tests we offer | 61 | * enum hwsim_regtest - the type of regulatory tests we offer |
| 57 | * | 62 | * |
| @@ -717,9 +722,17 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
| 717 | rx_status.flag |= RX_FLAG_MACTIME_START; | 722 | rx_status.flag |= RX_FLAG_MACTIME_START; |
| 718 | rx_status.freq = chan->center_freq; | 723 | rx_status.freq = chan->center_freq; |
| 719 | rx_status.band = chan->band; | 724 | rx_status.band = chan->band; |
| 720 | rx_status.rate_idx = info->control.rates[0].idx; | 725 | if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) { |
| 721 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | 726 | rx_status.rate_idx = |
| 722 | rx_status.flag |= RX_FLAG_HT; | 727 | ieee80211_rate_get_vht_mcs(&info->control.rates[0]); |
| 728 | rx_status.vht_nss = | ||
| 729 | ieee80211_rate_get_vht_nss(&info->control.rates[0]); | ||
| 730 | rx_status.flag |= RX_FLAG_VHT; | ||
| 731 | } else { | ||
| 732 | rx_status.rate_idx = info->control.rates[0].idx; | ||
| 733 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | ||
| 734 | rx_status.flag |= RX_FLAG_HT; | ||
| 735 | } | ||
| 723 | if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 736 | if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
| 724 | rx_status.flag |= RX_FLAG_40MHZ; | 737 | rx_status.flag |= RX_FLAG_40MHZ; |
| 725 | if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI) | 738 | if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI) |
| @@ -886,8 +899,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, | |||
| 886 | if (control->sta) | 899 | if (control->sta) |
| 887 | hwsim_check_sta_magic(control->sta); | 900 | hwsim_check_sta_magic(control->sta); |
| 888 | 901 | ||
| 889 | txi->rate_driver_data[0] = channel; | 902 | if (rctbl) |
| 903 | ieee80211_get_tx_rates(txi->control.vif, control->sta, skb, | ||
| 904 | txi->control.rates, | ||
| 905 | ARRAY_SIZE(txi->control.rates)); | ||
| 890 | 906 | ||
| 907 | txi->rate_driver_data[0] = channel; | ||
| 891 | mac80211_hwsim_monitor_rx(hw, skb, channel); | 908 | mac80211_hwsim_monitor_rx(hw, skb, channel); |
| 892 | 909 | ||
| 893 | /* wmediumd mode check */ | 910 | /* wmediumd mode check */ |
| @@ -989,6 +1006,13 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
| 989 | { | 1006 | { |
| 990 | u32 _pid = ACCESS_ONCE(wmediumd_portid); | 1007 | u32 _pid = ACCESS_ONCE(wmediumd_portid); |
| 991 | 1008 | ||
| 1009 | if (rctbl) { | ||
| 1010 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); | ||
| 1011 | ieee80211_get_tx_rates(txi->control.vif, NULL, skb, | ||
| 1012 | txi->control.rates, | ||
| 1013 | ARRAY_SIZE(txi->control.rates)); | ||
| 1014 | } | ||
| 1015 | |||
| 992 | mac80211_hwsim_monitor_rx(hw, skb, chan); | 1016 | mac80211_hwsim_monitor_rx(hw, skb, chan); |
| 993 | 1017 | ||
| 994 | if (_pid) | 1018 | if (_pid) |
| @@ -1019,6 +1043,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
| 1019 | if (skb == NULL) | 1043 | if (skb == NULL) |
| 1020 | return; | 1044 | return; |
| 1021 | info = IEEE80211_SKB_CB(skb); | 1045 | info = IEEE80211_SKB_CB(skb); |
| 1046 | if (rctbl) | ||
| 1047 | ieee80211_get_tx_rates(vif, NULL, skb, | ||
| 1048 | info->control.rates, | ||
| 1049 | ARRAY_SIZE(info->control.rates)); | ||
| 1050 | |||
| 1022 | txrate = ieee80211_get_tx_rate(hw, info); | 1051 | txrate = ieee80211_get_tx_rate(hw, info); |
| 1023 | 1052 | ||
| 1024 | mgmt = (struct ieee80211_mgmt *) skb->data; | 1053 | mgmt = (struct ieee80211_mgmt *) skb->data; |
| @@ -1062,11 +1091,13 @@ out: | |||
| 1062 | return HRTIMER_NORESTART; | 1091 | return HRTIMER_NORESTART; |
| 1063 | } | 1092 | } |
| 1064 | 1093 | ||
| 1065 | static const char *hwsim_chantypes[] = { | 1094 | static const char * const hwsim_chanwidths[] = { |
| 1066 | [NL80211_CHAN_NO_HT] = "noht", | 1095 | [NL80211_CHAN_WIDTH_20_NOHT] = "noht", |
| 1067 | [NL80211_CHAN_HT20] = "ht20", | 1096 | [NL80211_CHAN_WIDTH_20] = "ht20", |
| 1068 | [NL80211_CHAN_HT40MINUS] = "ht40-", | 1097 | [NL80211_CHAN_WIDTH_40] = "ht40", |
| 1069 | [NL80211_CHAN_HT40PLUS] = "ht40+", | 1098 | [NL80211_CHAN_WIDTH_80] = "vht80", |
| 1099 | [NL80211_CHAN_WIDTH_80P80] = "vht80p80", | ||
| 1100 | [NL80211_CHAN_WIDTH_160] = "vht160", | ||
| 1070 | }; | 1101 | }; |
| 1071 | 1102 | ||
| 1072 | static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | 1103 | static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) |
| @@ -1080,18 +1111,28 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1080 | [IEEE80211_SMPS_DYNAMIC] = "dynamic", | 1111 | [IEEE80211_SMPS_DYNAMIC] = "dynamic", |
| 1081 | }; | 1112 | }; |
| 1082 | 1113 | ||
| 1083 | wiphy_debug(hw->wiphy, | 1114 | if (conf->chandef.chan) |
| 1084 | "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", | 1115 | wiphy_debug(hw->wiphy, |
| 1085 | __func__, | 1116 | "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n", |
| 1086 | conf->channel ? conf->channel->center_freq : 0, | 1117 | __func__, |
| 1087 | hwsim_chantypes[conf->channel_type], | 1118 | conf->chandef.chan->center_freq, |
| 1088 | !!(conf->flags & IEEE80211_CONF_IDLE), | 1119 | conf->chandef.center_freq1, |
| 1089 | !!(conf->flags & IEEE80211_CONF_PS), | 1120 | conf->chandef.center_freq2, |
| 1090 | smps_modes[conf->smps_mode]); | 1121 | hwsim_chanwidths[conf->chandef.width], |
| 1122 | !!(conf->flags & IEEE80211_CONF_IDLE), | ||
| 1123 | !!(conf->flags & IEEE80211_CONF_PS), | ||
| 1124 | smps_modes[conf->smps_mode]); | ||
| 1125 | else | ||
| 1126 | wiphy_debug(hw->wiphy, | ||
| 1127 | "%s (freq=0 idle=%d ps=%d smps=%s)\n", | ||
| 1128 | __func__, | ||
| 1129 | !!(conf->flags & IEEE80211_CONF_IDLE), | ||
| 1130 | !!(conf->flags & IEEE80211_CONF_PS), | ||
| 1131 | smps_modes[conf->smps_mode]); | ||
| 1091 | 1132 | ||
| 1092 | data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1133 | data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
| 1093 | 1134 | ||
| 1094 | data->channel = conf->channel; | 1135 | data->channel = conf->chandef.chan; |
| 1095 | 1136 | ||
| 1096 | WARN_ON(data->channel && channels > 1); | 1137 | WARN_ON(data->channel && channels > 1); |
| 1097 | 1138 | ||
| @@ -1277,7 +1318,7 @@ static int mac80211_hwsim_get_survey( | |||
| 1277 | return -ENOENT; | 1318 | return -ENOENT; |
| 1278 | 1319 | ||
| 1279 | /* Current channel */ | 1320 | /* Current channel */ |
| 1280 | survey->channel = conf->channel; | 1321 | survey->channel = conf->chandef.chan; |
| 1281 | 1322 | ||
| 1282 | /* | 1323 | /* |
| 1283 | * Magically conjured noise level --- this is only ok for simulated hardware. | 1324 | * Magically conjured noise level --- this is only ok for simulated hardware. |
| @@ -1675,6 +1716,7 @@ static void mac80211_hwsim_free(void) | |||
| 1675 | debugfs_remove(data->debugfs_ps); | 1716 | debugfs_remove(data->debugfs_ps); |
| 1676 | debugfs_remove(data->debugfs); | 1717 | debugfs_remove(data->debugfs); |
| 1677 | ieee80211_unregister_hw(data->hw); | 1718 | ieee80211_unregister_hw(data->hw); |
| 1719 | device_release_driver(data->dev); | ||
| 1678 | device_unregister(data->dev); | 1720 | device_unregister(data->dev); |
| 1679 | ieee80211_free_hw(data->hw); | 1721 | ieee80211_free_hw(data->hw); |
| 1680 | } | 1722 | } |
| @@ -1683,7 +1725,9 @@ static void mac80211_hwsim_free(void) | |||
| 1683 | 1725 | ||
| 1684 | 1726 | ||
| 1685 | static struct device_driver mac80211_hwsim_driver = { | 1727 | static struct device_driver mac80211_hwsim_driver = { |
| 1686 | .name = "mac80211_hwsim" | 1728 | .name = "mac80211_hwsim", |
| 1729 | .bus = &platform_bus_type, | ||
| 1730 | .owner = THIS_MODULE, | ||
| 1687 | }; | 1731 | }; |
| 1688 | 1732 | ||
| 1689 | static const struct net_device_ops hwsim_netdev_ops = { | 1733 | static const struct net_device_ops hwsim_netdev_ops = { |
| @@ -2175,9 +2219,15 @@ static int __init init_mac80211_hwsim(void) | |||
| 2175 | spin_lock_init(&hwsim_radio_lock); | 2219 | spin_lock_init(&hwsim_radio_lock); |
| 2176 | INIT_LIST_HEAD(&hwsim_radios); | 2220 | INIT_LIST_HEAD(&hwsim_radios); |
| 2177 | 2221 | ||
| 2222 | err = driver_register(&mac80211_hwsim_driver); | ||
| 2223 | if (err) | ||
| 2224 | return err; | ||
| 2225 | |||
| 2178 | hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); | 2226 | hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); |
| 2179 | if (IS_ERR(hwsim_class)) | 2227 | if (IS_ERR(hwsim_class)) { |
| 2180 | return PTR_ERR(hwsim_class); | 2228 | err = PTR_ERR(hwsim_class); |
| 2229 | goto failed_unregister_driver; | ||
| 2230 | } | ||
| 2181 | 2231 | ||
| 2182 | memset(addr, 0, ETH_ALEN); | 2232 | memset(addr, 0, ETH_ALEN); |
| 2183 | addr[0] = 0x02; | 2233 | addr[0] = 0x02; |
| @@ -2199,12 +2249,20 @@ static int __init init_mac80211_hwsim(void) | |||
| 2199 | "hwsim%d", i); | 2249 | "hwsim%d", i); |
| 2200 | if (IS_ERR(data->dev)) { | 2250 | if (IS_ERR(data->dev)) { |
| 2201 | printk(KERN_DEBUG | 2251 | printk(KERN_DEBUG |
| 2202 | "mac80211_hwsim: device_create " | 2252 | "mac80211_hwsim: device_create failed (%ld)\n", |
| 2203 | "failed (%ld)\n", PTR_ERR(data->dev)); | 2253 | PTR_ERR(data->dev)); |
| 2204 | err = -ENOMEM; | 2254 | err = -ENOMEM; |
| 2205 | goto failed_drvdata; | 2255 | goto failed_drvdata; |
| 2206 | } | 2256 | } |
| 2207 | data->dev->driver = &mac80211_hwsim_driver; | 2257 | data->dev->driver = &mac80211_hwsim_driver; |
| 2258 | err = device_bind_driver(data->dev); | ||
| 2259 | if (err != 0) { | ||
| 2260 | printk(KERN_DEBUG | ||
| 2261 | "mac80211_hwsim: device_bind_driver failed (%d)\n", | ||
| 2262 | err); | ||
| 2263 | goto failed_hw; | ||
| 2264 | } | ||
| 2265 | |||
| 2208 | skb_queue_head_init(&data->pending); | 2266 | skb_queue_head_init(&data->pending); |
| 2209 | 2267 | ||
| 2210 | SET_IEEE80211_DEV(hw, data->dev); | 2268 | SET_IEEE80211_DEV(hw, data->dev); |
| @@ -2247,6 +2305,8 @@ static int __init init_mac80211_hwsim(void) | |||
| 2247 | IEEE80211_HW_AMPDU_AGGREGATION | | 2305 | IEEE80211_HW_AMPDU_AGGREGATION | |
| 2248 | IEEE80211_HW_WANT_MONITOR_VIF | | 2306 | IEEE80211_HW_WANT_MONITOR_VIF | |
| 2249 | IEEE80211_HW_QUEUE_CONTROL; | 2307 | IEEE80211_HW_QUEUE_CONTROL; |
| 2308 | if (rctbl) | ||
| 2309 | hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; | ||
| 2250 | 2310 | ||
| 2251 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | | 2311 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | |
| 2252 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 2312 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
| @@ -2298,9 +2358,6 @@ static int __init init_mac80211_hwsim(void) | |||
| 2298 | 2358 | ||
| 2299 | hw->wiphy->bands[band] = sband; | 2359 | hw->wiphy->bands[band] = sband; |
| 2300 | 2360 | ||
| 2301 | if (channels == 1) | ||
| 2302 | continue; | ||
| 2303 | |||
| 2304 | sband->vht_cap.vht_supported = true; | 2361 | sband->vht_cap.vht_supported = true; |
| 2305 | sband->vht_cap.cap = | 2362 | sband->vht_cap.cap = |
| 2306 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | | 2363 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | |
| @@ -2506,6 +2563,8 @@ failed_drvdata: | |||
| 2506 | ieee80211_free_hw(hw); | 2563 | ieee80211_free_hw(hw); |
| 2507 | failed: | 2564 | failed: |
| 2508 | mac80211_hwsim_free(); | 2565 | mac80211_hwsim_free(); |
| 2566 | failed_unregister_driver: | ||
| 2567 | driver_unregister(&mac80211_hwsim_driver); | ||
| 2509 | return err; | 2568 | return err; |
| 2510 | } | 2569 | } |
| 2511 | module_init(init_mac80211_hwsim); | 2570 | module_init(init_mac80211_hwsim); |
| @@ -2518,5 +2577,6 @@ static void __exit exit_mac80211_hwsim(void) | |||
| 2518 | 2577 | ||
| 2519 | mac80211_hwsim_free(); | 2578 | mac80211_hwsim_free(); |
| 2520 | unregister_netdev(hwsim_mon); | 2579 | unregister_netdev(hwsim_mon); |
| 2580 | driver_unregister(&mac80211_hwsim_driver); | ||
| 2521 | } | 2581 | } |
| 2522 | module_exit(exit_mac80211_hwsim); | 2582 | module_exit(exit_mac80211_hwsim); |
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c index 966a78f8e21a..5e0eec4d71c7 100644 --- a/drivers/net/wireless/mwifiex/11ac.c +++ b/drivers/net/wireless/mwifiex/11ac.c | |||
| @@ -200,7 +200,7 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, | |||
| 200 | 200 | ||
| 201 | /* VHT Operation IE */ | 201 | /* VHT Operation IE */ |
| 202 | if (bss_desc->bcn_vht_oper) { | 202 | if (bss_desc->bcn_vht_oper) { |
| 203 | if (priv->bss_mode == HostCmd_BSS_MODE_IBSS) { | 203 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
| 204 | vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer; | 204 | vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer; |
| 205 | memset(vht_op, 0, sizeof(*vht_op)); | 205 | memset(vht_op, 0, sizeof(*vht_op)); |
| 206 | vht_op->header.type = | 206 | vht_op->header.type = |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index af8fe6352eed..a78e0651409c 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
| @@ -296,19 +296,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 296 | break; | 296 | break; |
| 297 | } | 297 | } |
| 298 | if (ret != -EBUSY) { | 298 | if (ret != -EBUSY) { |
| 299 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); | 299 | mwifiex_rotate_priolists(priv, pra_list, ptrindex); |
| 300 | if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { | ||
| 301 | priv->wmm.packets_out[ptrindex]++; | ||
| 302 | priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list; | ||
| 303 | } | ||
| 304 | /* Now bss_prio_cur pointer points to next node */ | ||
| 305 | adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = | ||
| 306 | list_first_entry( | ||
| 307 | &adapter->bss_prio_tbl[priv->bss_priority] | ||
| 308 | .bss_prio_cur->list, | ||
| 309 | struct mwifiex_bss_prio_node, list); | ||
| 310 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | ||
| 311 | ra_list_flags); | ||
| 312 | } | 300 | } |
| 313 | 301 | ||
| 314 | return 0; | 302 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 5e796f847088..ada809f576fe 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
| @@ -447,7 +447,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
| 447 | end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); | 447 | end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); |
| 448 | del_timer(&tbl->timer_context.timer); | 448 | del_timer(&tbl->timer_context.timer); |
| 449 | mod_timer(&tbl->timer_context.timer, | 449 | mod_timer(&tbl->timer_context.timer, |
| 450 | jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); | 450 | jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size)); |
| 451 | 451 | ||
| 452 | /* | 452 | /* |
| 453 | * If seq_num is less then starting win then ignore and drop the | 453 | * If seq_num is less then starting win then ignore and drop the |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 47012947a447..a0cb0770d319 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
| @@ -1666,17 +1666,13 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
| 1666 | struct cfg80211_connect_params *sme) | 1666 | struct cfg80211_connect_params *sme) |
| 1667 | { | 1667 | { |
| 1668 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1668 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
| 1669 | int ret = 0; | 1669 | int ret; |
| 1670 | |||
| 1671 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | ||
| 1672 | wiphy_err(wiphy, "received infra assoc request " | ||
| 1673 | "when station is in ibss mode\n"); | ||
| 1674 | goto done; | ||
| 1675 | } | ||
| 1676 | 1670 | ||
| 1677 | if (priv->bss_mode == NL80211_IFTYPE_AP) { | 1671 | if (priv->bss_mode != NL80211_IFTYPE_STATION) { |
| 1678 | wiphy_err(wiphy, "skip association request for AP interface\n"); | 1672 | wiphy_err(wiphy, |
| 1679 | goto done; | 1673 | "%s: reject infra assoc request in non-STA mode\n", |
| 1674 | dev->name); | ||
| 1675 | return -EINVAL; | ||
| 1680 | } | 1676 | } |
| 1681 | 1677 | ||
| 1682 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", | 1678 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", |
| @@ -1684,7 +1680,6 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
| 1684 | 1680 | ||
| 1685 | ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, | 1681 | ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, |
| 1686 | priv->bss_mode, sme->channel, sme, 0); | 1682 | priv->bss_mode, sme->channel, sme, 0); |
| 1687 | done: | ||
| 1688 | if (!ret) { | 1683 | if (!ret) { |
| 1689 | cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, | 1684 | cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, |
| 1690 | NULL, 0, WLAN_STATUS_SUCCESS, | 1685 | NULL, 0, WLAN_STATUS_SUCCESS, |
| @@ -2136,10 +2131,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
| 2136 | 2131 | ||
| 2137 | /* At start-up, wpa_supplicant tries to change the interface | 2132 | /* At start-up, wpa_supplicant tries to change the interface |
| 2138 | * to NL80211_IFTYPE_STATION if it is not managed mode. | 2133 | * to NL80211_IFTYPE_STATION if it is not managed mode. |
| 2139 | * So, we initialize it to STA mode. | ||
| 2140 | */ | 2134 | */ |
| 2141 | wdev->iftype = NL80211_IFTYPE_STATION; | 2135 | wdev->iftype = NL80211_IFTYPE_P2P_CLIENT; |
| 2142 | priv->bss_mode = NL80211_IFTYPE_STATION; | 2136 | priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT; |
| 2143 | 2137 | ||
| 2144 | /* Setting bss_type to P2P tells firmware that this interface | 2138 | /* Setting bss_type to P2P tells firmware that this interface |
| 2145 | * is receiving P2P peers found during find phase and doing | 2139 | * is receiving P2P peers found during find phase and doing |
| @@ -2153,6 +2147,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
| 2153 | priv->bss_started = 0; | 2147 | priv->bss_started = 0; |
| 2154 | priv->bss_num = 0; | 2148 | priv->bss_num = 0; |
| 2155 | 2149 | ||
| 2150 | if (mwifiex_cfg80211_init_p2p_client(priv)) | ||
| 2151 | return ERR_PTR(-EFAULT); | ||
| 2152 | |||
| 2156 | break; | 2153 | break; |
| 2157 | default: | 2154 | default: |
| 2158 | wiphy_err(wiphy, "type not supported\n"); | 2155 | wiphy_err(wiphy, "type not supported\n"); |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index da469c336aa1..74db0d24a579 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
| @@ -250,7 +250,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
| 250 | 250 | ||
| 251 | /* Setup the timer after transmit command */ | 251 | /* Setup the timer after transmit command */ |
| 252 | mod_timer(&adapter->cmd_timer, | 252 | mod_timer(&adapter->cmd_timer, |
| 253 | jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); | 253 | jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); |
| 254 | 254 | ||
| 255 | return 0; | 255 | return 0; |
| 256 | } | 256 | } |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 42d7f0adf9bd..9f44fda19db9 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
| @@ -44,8 +44,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
| 44 | 44 | ||
| 45 | bss_prio->priv = priv; | 45 | bss_prio->priv = priv; |
| 46 | INIT_LIST_HEAD(&bss_prio->list); | 46 | INIT_LIST_HEAD(&bss_prio->list); |
| 47 | if (!tbl[priv->bss_priority].bss_prio_cur) | ||
| 48 | tbl[priv->bss_priority].bss_prio_cur = bss_prio; | ||
| 49 | 47 | ||
| 50 | spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); | 48 | spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); |
| 51 | list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); | 49 | list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); |
| @@ -525,7 +523,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) | |||
| 525 | 523 | ||
| 526 | for (i = 0; i < adapter->priv_num; ++i) { | 524 | for (i = 0; i < adapter->priv_num; ++i) { |
| 527 | INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); | 525 | INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); |
| 528 | adapter->bss_prio_tbl[i].bss_prio_cur = NULL; | ||
| 529 | spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); | 526 | spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); |
| 530 | } | 527 | } |
| 531 | 528 | ||
| @@ -625,42 +622,36 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) | |||
| 625 | { | 622 | { |
| 626 | int i; | 623 | int i; |
| 627 | struct mwifiex_adapter *adapter = priv->adapter; | 624 | struct mwifiex_adapter *adapter = priv->adapter; |
| 628 | struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; | 625 | struct mwifiex_bss_prio_node *bssprio_node, *tmp_node; |
| 629 | struct list_head *head; | 626 | struct list_head *head; |
| 630 | spinlock_t *lock; /* bss priority lock */ | 627 | spinlock_t *lock; /* bss priority lock */ |
| 631 | unsigned long flags; | 628 | unsigned long flags; |
| 632 | 629 | ||
| 633 | for (i = 0; i < adapter->priv_num; ++i) { | 630 | for (i = 0; i < adapter->priv_num; ++i) { |
| 634 | head = &adapter->bss_prio_tbl[i].bss_prio_head; | 631 | head = &adapter->bss_prio_tbl[i].bss_prio_head; |
| 635 | cur = &adapter->bss_prio_tbl[i].bss_prio_cur; | ||
| 636 | lock = &adapter->bss_prio_tbl[i].bss_prio_lock; | 632 | lock = &adapter->bss_prio_tbl[i].bss_prio_lock; |
| 637 | dev_dbg(adapter->dev, "info: delete BSS priority table," | 633 | dev_dbg(adapter->dev, "info: delete BSS priority table," |
| 638 | " bss_type = %d, bss_num = %d, i = %d," | 634 | " bss_type = %d, bss_num = %d, i = %d," |
| 639 | " head = %p, cur = %p\n", | 635 | " head = %p\n", |
| 640 | priv->bss_type, priv->bss_num, i, head, *cur); | 636 | priv->bss_type, priv->bss_num, i, head); |
| 641 | if (*cur) { | 637 | |
| 638 | { | ||
| 642 | spin_lock_irqsave(lock, flags); | 639 | spin_lock_irqsave(lock, flags); |
| 643 | if (list_empty(head)) { | 640 | if (list_empty(head)) { |
| 644 | spin_unlock_irqrestore(lock, flags); | 641 | spin_unlock_irqrestore(lock, flags); |
| 645 | continue; | 642 | continue; |
| 646 | } | 643 | } |
| 647 | bssprio_node = list_first_entry(head, | ||
| 648 | struct mwifiex_bss_prio_node, list); | ||
| 649 | spin_unlock_irqrestore(lock, flags); | ||
| 650 | |||
| 651 | list_for_each_entry_safe(bssprio_node, tmp_node, head, | 644 | list_for_each_entry_safe(bssprio_node, tmp_node, head, |
| 652 | list) { | 645 | list) { |
| 653 | if (bssprio_node->priv == priv) { | 646 | if (bssprio_node->priv == priv) { |
| 654 | dev_dbg(adapter->dev, "info: Delete " | 647 | dev_dbg(adapter->dev, "info: Delete " |
| 655 | "node %p, next = %p\n", | 648 | "node %p, next = %p\n", |
| 656 | bssprio_node, tmp_node); | 649 | bssprio_node, tmp_node); |
| 657 | spin_lock_irqsave(lock, flags); | ||
| 658 | list_del(&bssprio_node->list); | 650 | list_del(&bssprio_node->list); |
| 659 | spin_unlock_irqrestore(lock, flags); | ||
| 660 | kfree(bssprio_node); | 651 | kfree(bssprio_node); |
| 661 | } | 652 | } |
| 662 | } | 653 | } |
| 663 | *cur = (struct mwifiex_bss_prio_node *)head; | 654 | spin_unlock_irqrestore(lock, flags); |
| 664 | } | 655 | } |
| 665 | } | 656 | } |
| 666 | } | 657 | } |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index b7484efc9443..4ef67fca06d3 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
| @@ -213,7 +213,6 @@ struct mwifiex_ra_list_tbl { | |||
| 213 | 213 | ||
| 214 | struct mwifiex_tid_tbl { | 214 | struct mwifiex_tid_tbl { |
| 215 | struct list_head ra_list; | 215 | struct list_head ra_list; |
| 216 | struct mwifiex_ra_list_tbl *ra_list_curr; | ||
| 217 | }; | 216 | }; |
| 218 | 217 | ||
| 219 | #define WMM_HIGHEST_PRIORITY 7 | 218 | #define WMM_HIGHEST_PRIORITY 7 |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 856959b64bc7..80f282c0bd4d 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
| @@ -572,7 +572,7 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) | |||
| 572 | if (card->rx_buf_list[i]) { | 572 | if (card->rx_buf_list[i]) { |
| 573 | skb = card->rx_buf_list[i]; | 573 | skb = card->rx_buf_list[i]; |
| 574 | pci_unmap_single(card->dev, desc2->paddr, | 574 | pci_unmap_single(card->dev, desc2->paddr, |
| 575 | skb->len, PCI_DMA_TODEVICE); | 575 | skb->len, PCI_DMA_FROMDEVICE); |
| 576 | dev_kfree_skb_any(skb); | 576 | dev_kfree_skb_any(skb); |
| 577 | } | 577 | } |
| 578 | memset(desc2, 0, sizeof(*desc2)); | 578 | memset(desc2, 0, sizeof(*desc2)); |
| @@ -581,7 +581,7 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) | |||
| 581 | if (card->rx_buf_list[i]) { | 581 | if (card->rx_buf_list[i]) { |
| 582 | skb = card->rx_buf_list[i]; | 582 | skb = card->rx_buf_list[i]; |
| 583 | pci_unmap_single(card->dev, desc->paddr, | 583 | pci_unmap_single(card->dev, desc->paddr, |
| 584 | skb->len, PCI_DMA_TODEVICE); | 584 | skb->len, PCI_DMA_FROMDEVICE); |
| 585 | dev_kfree_skb_any(skb); | 585 | dev_kfree_skb_any(skb); |
| 586 | } | 586 | } |
| 587 | memset(desc, 0, sizeof(*desc)); | 587 | memset(desc, 0, sizeof(*desc)); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index e7f6deaf715e..9cf5d8f07df8 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
| @@ -1500,43 +1500,22 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, | |||
| 1500 | if (ret) | 1500 | if (ret) |
| 1501 | goto done; | 1501 | goto done; |
| 1502 | 1502 | ||
| 1503 | /* Update current bss descriptor parameters */ | ||
| 1504 | spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); | 1503 | spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); |
| 1505 | priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL; | ||
| 1506 | priv->curr_bss_params.bss_descriptor.wpa_offset = 0; | ||
| 1507 | priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL; | ||
| 1508 | priv->curr_bss_params.bss_descriptor.rsn_offset = 0; | ||
| 1509 | priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL; | ||
| 1510 | priv->curr_bss_params.bss_descriptor.wapi_offset = 0; | ||
| 1511 | priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL; | ||
| 1512 | priv->curr_bss_params.bss_descriptor.ht_cap_offset = 0; | ||
| 1513 | priv->curr_bss_params.bss_descriptor.bcn_ht_oper = NULL; | ||
| 1514 | priv->curr_bss_params.bss_descriptor.ht_info_offset = 0; | ||
| 1515 | priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = NULL; | ||
| 1516 | priv->curr_bss_params.bss_descriptor.bss_co_2040_offset = 0; | ||
| 1517 | priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL; | ||
| 1518 | priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0; | ||
| 1519 | priv->curr_bss_params.bss_descriptor.beacon_buf = NULL; | ||
| 1520 | priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0; | ||
| 1521 | priv->curr_bss_params.bss_descriptor.bcn_vht_cap = NULL; | ||
| 1522 | priv->curr_bss_params.bss_descriptor.vht_cap_offset = 0; | ||
| 1523 | priv->curr_bss_params.bss_descriptor.bcn_vht_oper = NULL; | ||
| 1524 | priv->curr_bss_params.bss_descriptor.vht_info_offset = 0; | ||
| 1525 | priv->curr_bss_params.bss_descriptor.oper_mode = NULL; | ||
| 1526 | priv->curr_bss_params.bss_descriptor.oper_mode_offset = 0; | ||
| 1527 | |||
| 1528 | /* Disable 11ac by default. Enable it only where there | ||
| 1529 | * exist VHT_CAP IE in AP beacon | ||
| 1530 | */ | ||
| 1531 | priv->curr_bss_params.bss_descriptor.disable_11ac = true; | ||
| 1532 | |||
| 1533 | /* Make a copy of current BSSID descriptor */ | 1504 | /* Make a copy of current BSSID descriptor */ |
| 1534 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, | 1505 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, |
| 1535 | sizeof(priv->curr_bss_params.bss_descriptor)); | 1506 | sizeof(priv->curr_bss_params.bss_descriptor)); |
| 1507 | |||
| 1508 | /* The contents of beacon_ie will be copied to its own buffer | ||
| 1509 | * in mwifiex_save_curr_bcn() | ||
| 1510 | */ | ||
| 1536 | mwifiex_save_curr_bcn(priv); | 1511 | mwifiex_save_curr_bcn(priv); |
| 1537 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); | 1512 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); |
| 1538 | 1513 | ||
| 1539 | done: | 1514 | done: |
| 1515 | /* beacon_ie buffer was allocated in function | ||
| 1516 | * mwifiex_fill_new_bss_desc(). Free it now. | ||
| 1517 | */ | ||
| 1518 | kfree(bss_desc->beacon_buf); | ||
| 1540 | kfree(bss_desc); | 1519 | kfree(bss_desc); |
| 1541 | return 0; | 1520 | return 0; |
| 1542 | } | 1521 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index e6c9b2ae22ed..311d0b26b81c 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
| @@ -140,12 +140,13 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, | |||
| 140 | /* | 140 | /* |
| 141 | * This function fills bss descriptor structure using provided | 141 | * This function fills bss descriptor structure using provided |
| 142 | * information. | 142 | * information. |
| 143 | * beacon_ie buffer is allocated in this function. It is caller's | ||
| 144 | * responsibility to free the memory. | ||
| 143 | */ | 145 | */ |
| 144 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | 146 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, |
| 145 | struct cfg80211_bss *bss, | 147 | struct cfg80211_bss *bss, |
| 146 | struct mwifiex_bssdescriptor *bss_desc) | 148 | struct mwifiex_bssdescriptor *bss_desc) |
| 147 | { | 149 | { |
| 148 | int ret; | ||
| 149 | u8 *beacon_ie; | 150 | u8 *beacon_ie; |
| 150 | size_t beacon_ie_len; | 151 | size_t beacon_ie_len; |
| 151 | struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; | 152 | struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; |
| @@ -165,6 +166,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
| 165 | 166 | ||
| 166 | memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); | 167 | memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); |
| 167 | bss_desc->rssi = bss->signal; | 168 | bss_desc->rssi = bss->signal; |
| 169 | /* The caller of this function will free beacon_ie */ | ||
| 168 | bss_desc->beacon_buf = beacon_ie; | 170 | bss_desc->beacon_buf = beacon_ie; |
| 169 | bss_desc->beacon_buf_size = beacon_ie_len; | 171 | bss_desc->beacon_buf_size = beacon_ie_len; |
| 170 | bss_desc->beacon_period = bss->beacon_interval; | 172 | bss_desc->beacon_period = bss->beacon_interval; |
| @@ -182,10 +184,12 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
| 182 | else | 184 | else |
| 183 | bss_desc->bss_mode = NL80211_IFTYPE_STATION; | 185 | bss_desc->bss_mode = NL80211_IFTYPE_STATION; |
| 184 | 186 | ||
| 185 | ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); | 187 | /* Disable 11ac by default. Enable it only where there |
| 188 | * exist VHT_CAP IE in AP beacon | ||
| 189 | */ | ||
| 190 | bss_desc->disable_11ac = true; | ||
| 186 | 191 | ||
| 187 | kfree(beacon_ie); | 192 | return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); |
| 188 | return ret; | ||
| 189 | } | 193 | } |
| 190 | 194 | ||
| 191 | static int mwifiex_process_country_ie(struct mwifiex_private *priv, | 195 | static int mwifiex_process_country_ie(struct mwifiex_private *priv, |
| @@ -349,6 +353,11 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
| 349 | } | 353 | } |
| 350 | 354 | ||
| 351 | done: | 355 | done: |
| 356 | /* beacon_ie buffer was allocated in function | ||
| 357 | * mwifiex_fill_new_bss_desc(). Free it now. | ||
| 358 | */ | ||
| 359 | if (bss_desc) | ||
| 360 | kfree(bss_desc->beacon_buf); | ||
| 352 | kfree(bss_desc); | 361 | kfree(bss_desc); |
| 353 | return ret; | 362 | return ret; |
| 354 | } | 363 | } |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 2cc81ba590e3..4be3d33ceae8 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
| @@ -191,9 +191,6 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) | |||
| 191 | } | 191 | } |
| 192 | list_add_tail(&ra_list->list, | 192 | list_add_tail(&ra_list->list, |
| 193 | &priv->wmm.tid_tbl_ptr[i].ra_list); | 193 | &priv->wmm.tid_tbl_ptr[i].ra_list); |
| 194 | |||
| 195 | if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) | ||
| 196 | priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; | ||
| 197 | } | 194 | } |
| 198 | } | 195 | } |
| 199 | 196 | ||
| @@ -424,7 +421,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
| 424 | priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; | 421 | priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; |
| 425 | priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; | 422 | priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; |
| 426 | priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; | 423 | priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; |
| 427 | priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; | ||
| 428 | } | 424 | } |
| 429 | 425 | ||
| 430 | priv->aggr_prio_tbl[6].amsdu | 426 | priv->aggr_prio_tbl[6].amsdu |
| @@ -530,8 +526,6 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) | |||
| 530 | } | 526 | } |
| 531 | 527 | ||
| 532 | INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); | 528 | INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); |
| 533 | |||
| 534 | priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; | ||
| 535 | } | 529 | } |
| 536 | } | 530 | } |
| 537 | 531 | ||
| @@ -883,38 +877,26 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
| 883 | struct mwifiex_private **priv, int *tid) | 877 | struct mwifiex_private **priv, int *tid) |
| 884 | { | 878 | { |
| 885 | struct mwifiex_private *priv_tmp; | 879 | struct mwifiex_private *priv_tmp; |
| 886 | struct mwifiex_ra_list_tbl *ptr, *head; | 880 | struct mwifiex_ra_list_tbl *ptr; |
| 887 | struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; | ||
| 888 | struct mwifiex_tid_tbl *tid_ptr; | 881 | struct mwifiex_tid_tbl *tid_ptr; |
| 889 | atomic_t *hqp; | 882 | atomic_t *hqp; |
| 890 | unsigned long flags_bss, flags_ra; | 883 | unsigned long flags_bss, flags_ra; |
| 891 | int i, j; | 884 | int i, j; |
| 892 | 885 | ||
| 886 | /* check the BSS with highest priority first */ | ||
| 893 | for (j = adapter->priv_num - 1; j >= 0; --j) { | 887 | for (j = adapter->priv_num - 1; j >= 0; --j) { |
| 894 | spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, | 888 | spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, |
| 895 | flags_bss); | 889 | flags_bss); |
| 896 | 890 | ||
| 897 | if (list_empty(&adapter->bss_prio_tbl[j].bss_prio_head)) | 891 | /* iterate over BSS with the equal priority */ |
| 898 | goto skip_prio_tbl; | 892 | list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur, |
| 899 | 893 | &adapter->bss_prio_tbl[j].bss_prio_head, | |
| 900 | if (adapter->bss_prio_tbl[j].bss_prio_cur == | 894 | list) { |
| 901 | (struct mwifiex_bss_prio_node *) | ||
| 902 | &adapter->bss_prio_tbl[j].bss_prio_head) { | ||
| 903 | adapter->bss_prio_tbl[j].bss_prio_cur = | ||
| 904 | list_first_entry(&adapter->bss_prio_tbl[j] | ||
| 905 | .bss_prio_head, | ||
| 906 | struct mwifiex_bss_prio_node, | ||
| 907 | list); | ||
| 908 | } | ||
| 909 | |||
| 910 | bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur; | ||
| 911 | bssprio_head = bssprio_node; | ||
| 912 | 895 | ||
| 913 | do { | 896 | priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv; |
| 914 | priv_tmp = bssprio_node->priv; | ||
| 915 | 897 | ||
| 916 | if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0) | 898 | if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0) |
| 917 | goto skip_bss; | 899 | continue; |
| 918 | 900 | ||
| 919 | /* iterate over the WMM queues of the BSS */ | 901 | /* iterate over the WMM queues of the BSS */ |
| 920 | hqp = &priv_tmp->wmm.highest_queued_prio; | 902 | hqp = &priv_tmp->wmm.highest_queued_prio; |
| @@ -926,73 +908,21 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
| 926 | tid_ptr = &(priv_tmp)->wmm. | 908 | tid_ptr = &(priv_tmp)->wmm. |
| 927 | tid_tbl_ptr[tos_to_tid[i]]; | 909 | tid_tbl_ptr[tos_to_tid[i]]; |
| 928 | 910 | ||
| 929 | /* For non-STA ra_list_curr may be NULL */ | 911 | /* iterate over receiver addresses */ |
| 930 | if (!tid_ptr->ra_list_curr) | 912 | list_for_each_entry(ptr, &tid_ptr->ra_list, |
| 931 | goto skip_wmm_queue; | 913 | list) { |
| 932 | |||
| 933 | if (list_empty(&tid_ptr->ra_list)) | ||
| 934 | goto skip_wmm_queue; | ||
| 935 | |||
| 936 | /* | ||
| 937 | * Always choose the next ra we transmitted | ||
| 938 | * last time, this way we pick the ra's in | ||
| 939 | * round robin fashion. | ||
| 940 | */ | ||
| 941 | ptr = list_first_entry( | ||
| 942 | &tid_ptr->ra_list_curr->list, | ||
| 943 | struct mwifiex_ra_list_tbl, | ||
| 944 | list); | ||
| 945 | |||
| 946 | head = ptr; | ||
| 947 | if (ptr == (struct mwifiex_ra_list_tbl *) | ||
| 948 | &tid_ptr->ra_list) { | ||
| 949 | /* Get next ra */ | ||
| 950 | ptr = list_first_entry(&ptr->list, | ||
| 951 | struct mwifiex_ra_list_tbl, list); | ||
| 952 | head = ptr; | ||
| 953 | } | ||
| 954 | 914 | ||
| 955 | do { | ||
| 956 | if (!skb_queue_empty(&ptr->skb_head)) | 915 | if (!skb_queue_empty(&ptr->skb_head)) |
| 957 | /* holds both locks */ | 916 | /* holds both locks */ |
| 958 | goto found; | 917 | goto found; |
| 918 | } | ||
| 959 | 919 | ||
| 960 | /* Get next ra */ | ||
| 961 | ptr = list_first_entry(&ptr->list, | ||
| 962 | struct mwifiex_ra_list_tbl, | ||
| 963 | list); | ||
| 964 | if (ptr == | ||
| 965 | (struct mwifiex_ra_list_tbl *) | ||
| 966 | &tid_ptr->ra_list) | ||
| 967 | ptr = list_first_entry( | ||
| 968 | &ptr->list, | ||
| 969 | struct mwifiex_ra_list_tbl, | ||
| 970 | list); | ||
| 971 | } while (ptr != head); | ||
| 972 | |||
| 973 | skip_wmm_queue: | ||
| 974 | spin_unlock_irqrestore(&priv_tmp->wmm. | 920 | spin_unlock_irqrestore(&priv_tmp->wmm. |
| 975 | ra_list_spinlock, | 921 | ra_list_spinlock, |
| 976 | flags_ra); | 922 | flags_ra); |
| 977 | } | 923 | } |
| 924 | } | ||
| 978 | 925 | ||
| 979 | skip_bss: | ||
| 980 | /* Get next bss priority node */ | ||
| 981 | bssprio_node = list_first_entry(&bssprio_node->list, | ||
| 982 | struct mwifiex_bss_prio_node, | ||
| 983 | list); | ||
| 984 | |||
| 985 | if (bssprio_node == | ||
| 986 | (struct mwifiex_bss_prio_node *) | ||
| 987 | &adapter->bss_prio_tbl[j].bss_prio_head) | ||
| 988 | /* Get next bss priority node */ | ||
| 989 | bssprio_node = list_first_entry( | ||
| 990 | &bssprio_node->list, | ||
| 991 | struct mwifiex_bss_prio_node, | ||
| 992 | list); | ||
| 993 | } while (bssprio_node != bssprio_head); | ||
| 994 | |||
| 995 | skip_prio_tbl: | ||
| 996 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, | 926 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, |
| 997 | flags_bss); | 927 | flags_bss); |
| 998 | } | 928 | } |
| @@ -1013,6 +943,42 @@ found: | |||
| 1013 | return ptr; | 943 | return ptr; |
| 1014 | } | 944 | } |
| 1015 | 945 | ||
| 946 | /* This functions rotates ra and bss lists so packets are picked round robin. | ||
| 947 | * | ||
| 948 | * After a packet is successfully transmitted, rotate the ra list, so the ra | ||
| 949 | * next to the one transmitted, will come first in the list. This way we pick | ||
| 950 | * the ra' in a round robin fashion. Same applies to bss nodes of equal | ||
| 951 | * priority. | ||
| 952 | * | ||
| 953 | * Function also increments wmm.packets_out counter. | ||
| 954 | */ | ||
| 955 | void mwifiex_rotate_priolists(struct mwifiex_private *priv, | ||
| 956 | struct mwifiex_ra_list_tbl *ra, | ||
| 957 | int tid) | ||
| 958 | { | ||
| 959 | struct mwifiex_adapter *adapter = priv->adapter; | ||
| 960 | struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; | ||
| 961 | struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid]; | ||
| 962 | unsigned long flags; | ||
| 963 | |||
| 964 | spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); | ||
| 965 | /* | ||
| 966 | * dirty trick: we remove 'head' temporarily and reinsert it after | ||
| 967 | * curr bss node. imagine list to stay fixed while head is moved | ||
| 968 | */ | ||
| 969 | list_move(&tbl[priv->bss_priority].bss_prio_head, | ||
| 970 | &tbl[priv->bss_priority].bss_prio_cur->list); | ||
| 971 | spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); | ||
| 972 | |||
| 973 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); | ||
| 974 | if (mwifiex_is_ralist_valid(priv, ra, tid)) { | ||
| 975 | priv->wmm.packets_out[tid]++; | ||
| 976 | /* same as above */ | ||
| 977 | list_move(&tid_ptr->ra_list, &ra->list); | ||
| 978 | } | ||
| 979 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | ||
| 980 | } | ||
| 981 | |||
| 1016 | /* | 982 | /* |
| 1017 | * This function checks if 11n aggregation is possible. | 983 | * This function checks if 11n aggregation is possible. |
| 1018 | */ | 984 | */ |
| @@ -1099,20 +1065,8 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
| 1099 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1065 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
| 1100 | ra_list_flags); | 1066 | ra_list_flags); |
| 1101 | } else { | 1067 | } else { |
| 1102 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); | 1068 | mwifiex_rotate_priolists(priv, ptr, ptr_index); |
| 1103 | if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { | ||
| 1104 | priv->wmm.packets_out[ptr_index]++; | ||
| 1105 | priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; | ||
| 1106 | } | ||
| 1107 | adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = | ||
| 1108 | list_first_entry( | ||
| 1109 | &adapter->bss_prio_tbl[priv->bss_priority] | ||
| 1110 | .bss_prio_cur->list, | ||
| 1111 | struct mwifiex_bss_prio_node, | ||
| 1112 | list); | ||
| 1113 | atomic_dec(&priv->wmm.tx_pkts_queued); | 1069 | atomic_dec(&priv->wmm.tx_pkts_queued); |
| 1114 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | ||
| 1115 | ra_list_flags); | ||
| 1116 | } | 1070 | } |
| 1117 | } | 1071 | } |
| 1118 | 1072 | ||
| @@ -1216,20 +1170,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, | |||
| 1216 | break; | 1170 | break; |
| 1217 | } | 1171 | } |
| 1218 | if (ret != -EBUSY) { | 1172 | if (ret != -EBUSY) { |
| 1219 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); | 1173 | mwifiex_rotate_priolists(priv, ptr, ptr_index); |
| 1220 | if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { | ||
| 1221 | priv->wmm.packets_out[ptr_index]++; | ||
| 1222 | priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; | ||
| 1223 | } | ||
| 1224 | adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = | ||
| 1225 | list_first_entry( | ||
| 1226 | &adapter->bss_prio_tbl[priv->bss_priority] | ||
| 1227 | .bss_prio_cur->list, | ||
| 1228 | struct mwifiex_bss_prio_node, | ||
| 1229 | list); | ||
| 1230 | atomic_dec(&priv->wmm.tx_pkts_queued); | 1174 | atomic_dec(&priv->wmm.tx_pkts_queued); |
| 1231 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | ||
| 1232 | ra_list_flags); | ||
| 1233 | } | 1175 | } |
| 1234 | } | 1176 | } |
| 1235 | 1177 | ||
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index b92f39d8963b..644d6e0c51cc 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h | |||
| @@ -85,6 +85,9 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) | |||
| 85 | void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, | 85 | void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, |
| 86 | struct sk_buff *skb); | 86 | struct sk_buff *skb); |
| 87 | void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); | 87 | void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); |
| 88 | void mwifiex_rotate_priolists(struct mwifiex_private *priv, | ||
| 89 | struct mwifiex_ra_list_tbl *ra, | ||
| 90 | int tid); | ||
| 88 | 91 | ||
| 89 | int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); | 92 | int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); |
| 90 | void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); | 93 | void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 956c1084ebf1..6820fce4016b 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
| @@ -193,10 +193,10 @@ struct mwl8k_priv { | |||
| 193 | struct rxd_ops *rxd_ops; | 193 | struct rxd_ops *rxd_ops; |
| 194 | struct ieee80211_supported_band band_24; | 194 | struct ieee80211_supported_band band_24; |
| 195 | struct ieee80211_channel channels_24[14]; | 195 | struct ieee80211_channel channels_24[14]; |
| 196 | struct ieee80211_rate rates_24[14]; | 196 | struct ieee80211_rate rates_24[13]; |
| 197 | struct ieee80211_supported_band band_50; | 197 | struct ieee80211_supported_band band_50; |
| 198 | struct ieee80211_channel channels_50[4]; | 198 | struct ieee80211_channel channels_50[4]; |
| 199 | struct ieee80211_rate rates_50[9]; | 199 | struct ieee80211_rate rates_50[8]; |
| 200 | u32 ap_macids_supported; | 200 | u32 ap_macids_supported; |
| 201 | u32 sta_macids_supported; | 201 | u32 sta_macids_supported; |
| 202 | 202 | ||
| @@ -366,7 +366,6 @@ static const struct ieee80211_rate mwl8k_rates_24[] = { | |||
| 366 | { .bitrate = 360, .hw_value = 72, }, | 366 | { .bitrate = 360, .hw_value = 72, }, |
| 367 | { .bitrate = 480, .hw_value = 96, }, | 367 | { .bitrate = 480, .hw_value = 96, }, |
| 368 | { .bitrate = 540, .hw_value = 108, }, | 368 | { .bitrate = 540, .hw_value = 108, }, |
| 369 | { .bitrate = 720, .hw_value = 144, }, | ||
| 370 | }; | 369 | }; |
| 371 | 370 | ||
| 372 | static const struct ieee80211_channel mwl8k_channels_50[] = { | 371 | static const struct ieee80211_channel mwl8k_channels_50[] = { |
| @@ -385,7 +384,6 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { | |||
| 385 | { .bitrate = 360, .hw_value = 72, }, | 384 | { .bitrate = 360, .hw_value = 72, }, |
| 386 | { .bitrate = 480, .hw_value = 96, }, | 385 | { .bitrate = 480, .hw_value = 96, }, |
| 387 | { .bitrate = 540, .hw_value = 108, }, | 386 | { .bitrate = 540, .hw_value = 108, }, |
| 388 | { .bitrate = 720, .hw_value = 144, }, | ||
| 389 | }; | 387 | }; |
| 390 | 388 | ||
| 391 | /* Set or get info from Firmware */ | 389 | /* Set or get info from Firmware */ |
| @@ -2852,7 +2850,9 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, | |||
| 2852 | struct ieee80211_conf *conf, | 2850 | struct ieee80211_conf *conf, |
| 2853 | unsigned short pwr) | 2851 | unsigned short pwr) |
| 2854 | { | 2852 | { |
| 2855 | struct ieee80211_channel *channel = conf->channel; | 2853 | struct ieee80211_channel *channel = conf->chandef.chan; |
| 2854 | enum nl80211_channel_type channel_type = | ||
| 2855 | cfg80211_get_chandef_type(&conf->chandef); | ||
| 2856 | struct mwl8k_cmd_tx_power *cmd; | 2856 | struct mwl8k_cmd_tx_power *cmd; |
| 2857 | int rc; | 2857 | int rc; |
| 2858 | int i; | 2858 | int i; |
| @@ -2872,14 +2872,14 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, | |||
| 2872 | 2872 | ||
| 2873 | cmd->channel = cpu_to_le16(channel->hw_value); | 2873 | cmd->channel = cpu_to_le16(channel->hw_value); |
| 2874 | 2874 | ||
| 2875 | if (conf->channel_type == NL80211_CHAN_NO_HT || | 2875 | if (channel_type == NL80211_CHAN_NO_HT || |
| 2876 | conf->channel_type == NL80211_CHAN_HT20) { | 2876 | channel_type == NL80211_CHAN_HT20) { |
| 2877 | cmd->bw = cpu_to_le16(0x2); | 2877 | cmd->bw = cpu_to_le16(0x2); |
| 2878 | } else { | 2878 | } else { |
| 2879 | cmd->bw = cpu_to_le16(0x4); | 2879 | cmd->bw = cpu_to_le16(0x4); |
| 2880 | if (conf->channel_type == NL80211_CHAN_HT40MINUS) | 2880 | if (channel_type == NL80211_CHAN_HT40MINUS) |
| 2881 | cmd->sub_ch = cpu_to_le16(0x3); | 2881 | cmd->sub_ch = cpu_to_le16(0x3); |
| 2882 | else if (conf->channel_type == NL80211_CHAN_HT40PLUS) | 2882 | else if (channel_type == NL80211_CHAN_HT40PLUS) |
| 2883 | cmd->sub_ch = cpu_to_le16(0x1); | 2883 | cmd->sub_ch = cpu_to_le16(0x1); |
| 2884 | } | 2884 | } |
| 2885 | 2885 | ||
| @@ -3023,7 +3023,9 @@ struct mwl8k_cmd_set_rf_channel { | |||
| 3023 | static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, | 3023 | static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, |
| 3024 | struct ieee80211_conf *conf) | 3024 | struct ieee80211_conf *conf) |
| 3025 | { | 3025 | { |
| 3026 | struct ieee80211_channel *channel = conf->channel; | 3026 | struct ieee80211_channel *channel = conf->chandef.chan; |
| 3027 | enum nl80211_channel_type channel_type = | ||
| 3028 | cfg80211_get_chandef_type(&conf->chandef); | ||
| 3027 | struct mwl8k_cmd_set_rf_channel *cmd; | 3029 | struct mwl8k_cmd_set_rf_channel *cmd; |
| 3028 | int rc; | 3030 | int rc; |
| 3029 | 3031 | ||
| @@ -3041,12 +3043,12 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, | |||
| 3041 | else if (channel->band == IEEE80211_BAND_5GHZ) | 3043 | else if (channel->band == IEEE80211_BAND_5GHZ) |
| 3042 | cmd->channel_flags |= cpu_to_le32(0x00000004); | 3044 | cmd->channel_flags |= cpu_to_le32(0x00000004); |
| 3043 | 3045 | ||
| 3044 | if (conf->channel_type == NL80211_CHAN_NO_HT || | 3046 | if (channel_type == NL80211_CHAN_NO_HT || |
| 3045 | conf->channel_type == NL80211_CHAN_HT20) | 3047 | channel_type == NL80211_CHAN_HT20) |
| 3046 | cmd->channel_flags |= cpu_to_le32(0x00000080); | 3048 | cmd->channel_flags |= cpu_to_le32(0x00000080); |
| 3047 | else if (conf->channel_type == NL80211_CHAN_HT40MINUS) | 3049 | else if (channel_type == NL80211_CHAN_HT40MINUS) |
| 3048 | cmd->channel_flags |= cpu_to_le32(0x000001900); | 3050 | cmd->channel_flags |= cpu_to_le32(0x000001900); |
| 3049 | else if (conf->channel_type == NL80211_CHAN_HT40PLUS) | 3051 | else if (channel_type == NL80211_CHAN_HT40PLUS) |
| 3050 | cmd->channel_flags |= cpu_to_le32(0x000000900); | 3052 | cmd->channel_flags |= cpu_to_le32(0x000000900); |
| 3051 | 3053 | ||
| 3052 | rc = mwl8k_post_cmd(hw, &cmd->header); | 3054 | rc = mwl8k_post_cmd(hw, &cmd->header); |
| @@ -3079,11 +3081,11 @@ static void legacy_rate_mask_to_array(u8 *rates, u32 mask) | |||
| 3079 | int j; | 3081 | int j; |
| 3080 | 3082 | ||
| 3081 | /* | 3083 | /* |
| 3082 | * Clear nonstandard rates 4 and 13. | 3084 | * Clear nonstandard rate 4. |
| 3083 | */ | 3085 | */ |
| 3084 | mask &= 0x1fef; | 3086 | mask &= 0x1fef; |
| 3085 | 3087 | ||
| 3086 | for (i = 0, j = 0; i < 14; i++) { | 3088 | for (i = 0, j = 0; i < 13; i++) { |
| 3087 | if (mask & (1 << i)) | 3089 | if (mask & (1 << i)) |
| 3088 | rates[j++] = mwl8k_rates_24[i].hw_value; | 3090 | rates[j++] = mwl8k_rates_24[i].hw_value; |
| 3089 | } | 3091 | } |
| @@ -3965,7 +3967,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, | |||
| 3965 | memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); | 3967 | memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); |
| 3966 | cmd->stn_id = cpu_to_le16(sta->aid); | 3968 | cmd->stn_id = cpu_to_le16(sta->aid); |
| 3967 | cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); | 3969 | cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); |
| 3968 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) | 3970 | if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 3969 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; | 3971 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; |
| 3970 | else | 3972 | else |
| 3971 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; | 3973 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; |
| @@ -4400,7 +4402,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, | |||
| 4400 | p->ht_caps = cpu_to_le16(sta->ht_cap.cap); | 4402 | p->ht_caps = cpu_to_le16(sta->ht_cap.cap); |
| 4401 | p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | | 4403 | p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | |
| 4402 | ((sta->ht_cap.ampdu_density & 7) << 2); | 4404 | ((sta->ht_cap.ampdu_density & 7) << 2); |
| 4403 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) | 4405 | if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 4404 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; | 4406 | rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; |
| 4405 | else | 4407 | else |
| 4406 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; | 4408 | rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; |
| @@ -4881,7 +4883,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 4881 | goto out; | 4883 | goto out; |
| 4882 | } | 4884 | } |
| 4883 | 4885 | ||
| 4884 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) { | 4886 | if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { |
| 4885 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; | 4887 | ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; |
| 4886 | } else { | 4888 | } else { |
| 4887 | ap_legacy_rates = | 4889 | ap_legacy_rates = |
| @@ -4913,7 +4915,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 4913 | if (idx) | 4915 | if (idx) |
| 4914 | idx--; | 4916 | idx--; |
| 4915 | 4917 | ||
| 4916 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) | 4918 | if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 4917 | rate = mwl8k_rates_24[idx].hw_value; | 4919 | rate = mwl8k_rates_24[idx].hw_value; |
| 4918 | else | 4920 | else |
| 4919 | rate = mwl8k_rates_50[idx].hw_value; | 4921 | rate = mwl8k_rates_50[idx].hw_value; |
| @@ -4986,7 +4988,7 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 4986 | if (idx) | 4988 | if (idx) |
| 4987 | idx--; | 4989 | idx--; |
| 4988 | 4990 | ||
| 4989 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) | 4991 | if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) |
| 4990 | rate = mwl8k_rates_24[idx].hw_value; | 4992 | rate = mwl8k_rates_24[idx].hw_value; |
| 4991 | else | 4993 | else |
| 4992 | rate = mwl8k_rates_50[idx].hw_value; | 4994 | rate = mwl8k_rates_50[idx].hw_value; |
| @@ -5259,7 +5261,7 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 5259 | if (idx != 0) | 5261 | if (idx != 0) |
| 5260 | return -ENOENT; | 5262 | return -ENOENT; |
| 5261 | 5263 | ||
| 5262 | survey->channel = conf->channel; | 5264 | survey->channel = conf->chandef.chan; |
| 5263 | survey->filled = SURVEY_INFO_NOISE_DBM; | 5265 | survey->filled = SURVEY_INFO_NOISE_DBM; |
| 5264 | survey->noise = priv->noise; | 5266 | survey->noise = priv->noise; |
| 5265 | 5267 | ||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 9ba85106eec0..b3879fbf5368 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
| @@ -402,7 +402,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
| 402 | struct p54_rssi_db_entry *rssi_data; | 402 | struct p54_rssi_db_entry *rssi_data; |
| 403 | unsigned int i; | 403 | unsigned int i; |
| 404 | void *entry; | 404 | void *entry; |
| 405 | __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); | 405 | __le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq); |
| 406 | 406 | ||
| 407 | skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + | 407 | skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + |
| 408 | 2 + sizeof(*iq_autocal) + sizeof(*body) + | 408 | 2 + sizeof(*iq_autocal) + sizeof(*body) + |
| @@ -532,7 +532,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
| 532 | err: | 532 | err: |
| 533 | wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", | 533 | wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", |
| 534 | ieee80211_frequency_to_channel( | 534 | ieee80211_frequency_to_channel( |
| 535 | priv->hw->conf.channel->center_freq)); | 535 | priv->hw->conf.chandef.chan->center_freq)); |
| 536 | 536 | ||
| 537 | dev_kfree_skb_any(skb); | 537 | dev_kfree_skb_any(skb); |
| 538 | return -EINVAL; | 538 | return -EINVAL; |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index ee654a691f38..067e6f2fd050 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
| @@ -340,7 +340,7 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed) | |||
| 340 | * TODO: Use the LM_SCAN_TRAP to determine the current | 340 | * TODO: Use the LM_SCAN_TRAP to determine the current |
| 341 | * operating channel. | 341 | * operating channel. |
| 342 | */ | 342 | */ |
| 343 | priv->curchan = priv->hw->conf.channel; | 343 | priv->curchan = priv->hw->conf.chandef.chan; |
| 344 | p54_reset_stats(priv); | 344 | p54_reset_stats(priv); |
| 345 | WARN_ON(p54_fetch_statistics(priv)); | 345 | WARN_ON(p54_fetch_statistics(priv)); |
| 346 | } | 346 | } |
| @@ -480,7 +480,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev, | |||
| 480 | p54_set_edcf(priv); | 480 | p54_set_edcf(priv); |
| 481 | } | 481 | } |
| 482 | if (changed & BSS_CHANGED_BASIC_RATES) { | 482 | if (changed & BSS_CHANGED_BASIC_RATES) { |
| 483 | if (dev->conf.channel->band == IEEE80211_BAND_5GHZ) | 483 | if (dev->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) |
| 484 | priv->basic_rate_mask = (info->basic_rates << 4); | 484 | priv->basic_rate_mask = (info->basic_rates << 4); |
| 485 | else | 485 | else |
| 486 | priv->basic_rate_mask = info->basic_rates; | 486 | priv->basic_rate_mask = info->basic_rates; |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 12f0a34477f2..f95de0d16216 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
| @@ -354,13 +354,13 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) | |||
| 354 | rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); | 354 | rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); |
| 355 | if (hdr->rate & 0x10) | 355 | if (hdr->rate & 0x10) |
| 356 | rx_status->flag |= RX_FLAG_SHORTPRE; | 356 | rx_status->flag |= RX_FLAG_SHORTPRE; |
| 357 | if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) | 357 | if (priv->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) |
| 358 | rx_status->rate_idx = (rate < 4) ? 0 : rate - 4; | 358 | rx_status->rate_idx = (rate < 4) ? 0 : rate - 4; |
| 359 | else | 359 | else |
| 360 | rx_status->rate_idx = rate; | 360 | rx_status->rate_idx = rate; |
| 361 | 361 | ||
| 362 | rx_status->freq = freq; | 362 | rx_status->freq = freq; |
| 363 | rx_status->band = priv->hw->conf.channel->band; | 363 | rx_status->band = priv->hw->conf.chandef.chan->band; |
| 364 | rx_status->antenna = hdr->antenna; | 364 | rx_status->antenna = hdr->antenna; |
| 365 | 365 | ||
| 366 | tsf32 = le32_to_cpu(hdr->tsf32); | 366 | tsf32 = le32_to_cpu(hdr->tsf32); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index dcfb54e0c516..f7143733d7e9 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | /* | 41 | /* |
| 42 | * Register access. | 42 | * Register access. |
| 43 | * All access to the CSR registers will go through the methods | 43 | * All access to the CSR registers will go through the methods |
| 44 | * rt2x00pci_register_read and rt2x00pci_register_write. | 44 | * rt2x00mmio_register_read and rt2x00mmio_register_write. |
| 45 | * BBP and RF register require indirect register access, | 45 | * BBP and RF register require indirect register access, |
| 46 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | 46 | * and use the CSR registers BBPCSR and RFCSR to achieve this. |
| 47 | * These indirect registers work with busy bits, | 47 | * These indirect registers work with busy bits, |
| @@ -52,9 +52,9 @@ | |||
| 52 | * and we will print an error. | 52 | * and we will print an error. |
| 53 | */ | 53 | */ |
| 54 | #define WAIT_FOR_BBP(__dev, __reg) \ | 54 | #define WAIT_FOR_BBP(__dev, __reg) \ |
| 55 | rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) | 55 | rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) |
| 56 | #define WAIT_FOR_RF(__dev, __reg) \ | 56 | #define WAIT_FOR_RF(__dev, __reg) \ |
| 57 | rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) | 57 | rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) |
| 58 | 58 | ||
| 59 | static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 59 | static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
| 60 | const unsigned int word, const u8 value) | 60 | const unsigned int word, const u8 value) |
| @@ -74,7 +74,7 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
| 74 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | 74 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
| 75 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | 75 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); |
| 76 | 76 | ||
| 77 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 77 | rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | mutex_unlock(&rt2x00dev->csr_mutex); | 80 | mutex_unlock(&rt2x00dev->csr_mutex); |
| @@ -101,7 +101,7 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
| 101 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | 101 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
| 102 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | 102 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); |
| 103 | 103 | ||
| 104 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 104 | rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); |
| 105 | 105 | ||
| 106 | WAIT_FOR_BBP(rt2x00dev, ®); | 106 | WAIT_FOR_BBP(rt2x00dev, ®); |
| 107 | } | 107 | } |
| @@ -129,7 +129,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
| 129 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | 129 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); |
| 130 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | 130 | rt2x00_set_field32(®, RFCSR_BUSY, 1); |
| 131 | 131 | ||
| 132 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | 132 | rt2x00mmio_register_write(rt2x00dev, RFCSR, reg); |
| 133 | rt2x00_rf_write(rt2x00dev, word, value); | 133 | rt2x00_rf_write(rt2x00dev, word, value); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| @@ -141,7 +141,7 @@ static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | |||
| 141 | struct rt2x00_dev *rt2x00dev = eeprom->data; | 141 | struct rt2x00_dev *rt2x00dev = eeprom->data; |
| 142 | u32 reg; | 142 | u32 reg; |
| 143 | 143 | ||
| 144 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | 144 | rt2x00mmio_register_read(rt2x00dev, CSR21, ®); |
| 145 | 145 | ||
| 146 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); | 146 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); |
| 147 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); | 147 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); |
| @@ -163,15 +163,15 @@ static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
| 163 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, | 163 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, |
| 164 | !!eeprom->reg_chip_select); | 164 | !!eeprom->reg_chip_select); |
| 165 | 165 | ||
| 166 | rt2x00pci_register_write(rt2x00dev, CSR21, reg); | 166 | rt2x00mmio_register_write(rt2x00dev, CSR21, reg); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 169 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
| 170 | static const struct rt2x00debug rt2400pci_rt2x00debug = { | 170 | static const struct rt2x00debug rt2400pci_rt2x00debug = { |
| 171 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
| 172 | .csr = { | 172 | .csr = { |
| 173 | .read = rt2x00pci_register_read, | 173 | .read = rt2x00mmio_register_read, |
| 174 | .write = rt2x00pci_register_write, | 174 | .write = rt2x00mmio_register_write, |
| 175 | .flags = RT2X00DEBUGFS_OFFSET, | 175 | .flags = RT2X00DEBUGFS_OFFSET, |
| 176 | .word_base = CSR_REG_BASE, | 176 | .word_base = CSR_REG_BASE, |
| 177 | .word_size = sizeof(u32), | 177 | .word_size = sizeof(u32), |
| @@ -205,7 +205,7 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
| 205 | { | 205 | { |
| 206 | u32 reg; | 206 | u32 reg; |
| 207 | 207 | ||
| 208 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | 208 | rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); |
| 209 | return rt2x00_get_field32(reg, GPIOCSR_VAL0); | 209 | return rt2x00_get_field32(reg, GPIOCSR_VAL0); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| @@ -218,14 +218,14 @@ static void rt2400pci_brightness_set(struct led_classdev *led_cdev, | |||
| 218 | unsigned int enabled = brightness != LED_OFF; | 218 | unsigned int enabled = brightness != LED_OFF; |
| 219 | u32 reg; | 219 | u32 reg; |
| 220 | 220 | ||
| 221 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | 221 | rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); |
| 222 | 222 | ||
| 223 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) | 223 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) |
| 224 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); | 224 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
| 225 | else if (led->type == LED_TYPE_ACTIVITY) | 225 | else if (led->type == LED_TYPE_ACTIVITY) |
| 226 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); | 226 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); |
| 227 | 227 | ||
| 228 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | 228 | rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | static int rt2400pci_blink_set(struct led_classdev *led_cdev, | 231 | static int rt2400pci_blink_set(struct led_classdev *led_cdev, |
| @@ -236,10 +236,10 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev, | |||
| 236 | container_of(led_cdev, struct rt2x00_led, led_dev); | 236 | container_of(led_cdev, struct rt2x00_led, led_dev); |
| 237 | u32 reg; | 237 | u32 reg; |
| 238 | 238 | ||
| 239 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | 239 | rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); |
| 240 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); | 240 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); |
| 241 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); | 241 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); |
| 242 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | 242 | rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); |
| 243 | 243 | ||
| 244 | return 0; | 244 | return 0; |
| 245 | } | 245 | } |
| @@ -269,7 +269,7 @@ static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 269 | * Note that the version error will always be dropped | 269 | * Note that the version error will always be dropped |
| 270 | * since there is no filter for it at this time. | 270 | * since there is no filter for it at this time. |
| 271 | */ | 271 | */ |
| 272 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 272 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 273 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, | 273 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, |
| 274 | !(filter_flags & FIF_FCSFAIL)); | 274 | !(filter_flags & FIF_FCSFAIL)); |
| 275 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, | 275 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, |
| @@ -282,7 +282,7 @@ static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 282 | !(filter_flags & FIF_PROMISC_IN_BSS) && | 282 | !(filter_flags & FIF_PROMISC_IN_BSS) && |
| 283 | !rt2x00dev->intf_ap_count); | 283 | !rt2x00dev->intf_ap_count); |
| 284 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | 284 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); |
| 285 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 285 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | 288 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, |
| @@ -298,25 +298,26 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
| 298 | * Enable beacon config | 298 | * Enable beacon config |
| 299 | */ | 299 | */ |
| 300 | bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); | 300 | bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); |
| 301 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 301 | rt2x00mmio_register_read(rt2x00dev, BCNCSR1, ®); |
| 302 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | 302 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
| 303 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 303 | rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg); |
| 304 | 304 | ||
| 305 | /* | 305 | /* |
| 306 | * Enable synchronisation. | 306 | * Enable synchronisation. |
| 307 | */ | 307 | */ |
| 308 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 308 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 309 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 309 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
| 310 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 310 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | if (flags & CONFIG_UPDATE_MAC) | 313 | if (flags & CONFIG_UPDATE_MAC) |
| 314 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | 314 | rt2x00mmio_register_multiwrite(rt2x00dev, CSR3, |
| 315 | conf->mac, sizeof(conf->mac)); | 315 | conf->mac, sizeof(conf->mac)); |
| 316 | 316 | ||
| 317 | if (flags & CONFIG_UPDATE_BSSID) | 317 | if (flags & CONFIG_UPDATE_BSSID) |
| 318 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | 318 | rt2x00mmio_register_multiwrite(rt2x00dev, CSR5, |
| 319 | conf->bssid, sizeof(conf->bssid)); | 319 | conf->bssid, |
| 320 | sizeof(conf->bssid)); | ||
| 320 | } | 321 | } |
| 321 | 322 | ||
| 322 | static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, | 323 | static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, |
| @@ -332,68 +333,68 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
| 332 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 333 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
| 333 | preamble_mask = erp->short_preamble << 3; | 334 | preamble_mask = erp->short_preamble << 3; |
| 334 | 335 | ||
| 335 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 336 | rt2x00mmio_register_read(rt2x00dev, TXCSR1, ®); |
| 336 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); | 337 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); |
| 337 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); | 338 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); |
| 338 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | 339 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); |
| 339 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | 340 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); |
| 340 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 341 | rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg); |
| 341 | 342 | ||
| 342 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 343 | rt2x00mmio_register_read(rt2x00dev, ARCSR2, ®); |
| 343 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 344 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
| 344 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 345 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
| 345 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 346 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 346 | GET_DURATION(ACK_SIZE, 10)); | 347 | GET_DURATION(ACK_SIZE, 10)); |
| 347 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 348 | rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg); |
| 348 | 349 | ||
| 349 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | 350 | rt2x00mmio_register_read(rt2x00dev, ARCSR3, ®); |
| 350 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 351 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
| 351 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 352 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
| 352 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 353 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 353 | GET_DURATION(ACK_SIZE, 20)); | 354 | GET_DURATION(ACK_SIZE, 20)); |
| 354 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | 355 | rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg); |
| 355 | 356 | ||
| 356 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | 357 | rt2x00mmio_register_read(rt2x00dev, ARCSR4, ®); |
| 357 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 358 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
| 358 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 359 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); |
| 359 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 360 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 360 | GET_DURATION(ACK_SIZE, 55)); | 361 | GET_DURATION(ACK_SIZE, 55)); |
| 361 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | 362 | rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg); |
| 362 | 363 | ||
| 363 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | 364 | rt2x00mmio_register_read(rt2x00dev, ARCSR5, ®); |
| 364 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 365 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); |
| 365 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 366 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
| 366 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 367 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 367 | GET_DURATION(ACK_SIZE, 110)); | 368 | GET_DURATION(ACK_SIZE, 110)); |
| 368 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 369 | rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg); |
| 369 | } | 370 | } |
| 370 | 371 | ||
| 371 | if (changed & BSS_CHANGED_BASIC_RATES) | 372 | if (changed & BSS_CHANGED_BASIC_RATES) |
| 372 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); | 373 | rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates); |
| 373 | 374 | ||
| 374 | if (changed & BSS_CHANGED_ERP_SLOT) { | 375 | if (changed & BSS_CHANGED_ERP_SLOT) { |
| 375 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 376 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 376 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); | 377 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); |
| 377 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 378 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 378 | 379 | ||
| 379 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); | 380 | rt2x00mmio_register_read(rt2x00dev, CSR18, ®); |
| 380 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); | 381 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); |
| 381 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); | 382 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); |
| 382 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | 383 | rt2x00mmio_register_write(rt2x00dev, CSR18, reg); |
| 383 | 384 | ||
| 384 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | 385 | rt2x00mmio_register_read(rt2x00dev, CSR19, ®); |
| 385 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | 386 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); |
| 386 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | 387 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); |
| 387 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | 388 | rt2x00mmio_register_write(rt2x00dev, CSR19, reg); |
| 388 | } | 389 | } |
| 389 | 390 | ||
| 390 | if (changed & BSS_CHANGED_BEACON_INT) { | 391 | if (changed & BSS_CHANGED_BEACON_INT) { |
| 391 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | 392 | rt2x00mmio_register_read(rt2x00dev, CSR12, ®); |
| 392 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, | 393 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, |
| 393 | erp->beacon_int * 16); | 394 | erp->beacon_int * 16); |
| 394 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, | 395 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, |
| 395 | erp->beacon_int * 16); | 396 | erp->beacon_int * 16); |
| 396 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 397 | rt2x00mmio_register_write(rt2x00dev, CSR12, reg); |
| 397 | } | 398 | } |
| 398 | } | 399 | } |
| 399 | 400 | ||
| @@ -497,7 +498,7 @@ static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 497 | /* | 498 | /* |
| 498 | * Clear false CRC during channel switch. | 499 | * Clear false CRC during channel switch. |
| 499 | */ | 500 | */ |
| 500 | rt2x00pci_register_read(rt2x00dev, CNT0, &rf->rf1); | 501 | rt2x00mmio_register_read(rt2x00dev, CNT0, &rf->rf1); |
| 501 | } | 502 | } |
| 502 | 503 | ||
| 503 | static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower) | 504 | static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower) |
| @@ -510,12 +511,12 @@ static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, | |||
| 510 | { | 511 | { |
| 511 | u32 reg; | 512 | u32 reg; |
| 512 | 513 | ||
| 513 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 514 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 514 | rt2x00_set_field32(®, CSR11_LONG_RETRY, | 515 | rt2x00_set_field32(®, CSR11_LONG_RETRY, |
| 515 | libconf->conf->long_frame_max_tx_count); | 516 | libconf->conf->long_frame_max_tx_count); |
| 516 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, | 517 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, |
| 517 | libconf->conf->short_frame_max_tx_count); | 518 | libconf->conf->short_frame_max_tx_count); |
| 518 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 519 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 519 | } | 520 | } |
| 520 | 521 | ||
| 521 | static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, | 522 | static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, |
| @@ -527,7 +528,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 527 | u32 reg; | 528 | u32 reg; |
| 528 | 529 | ||
| 529 | if (state == STATE_SLEEP) { | 530 | if (state == STATE_SLEEP) { |
| 530 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | 531 | rt2x00mmio_register_read(rt2x00dev, CSR20, ®); |
| 531 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | 532 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, |
| 532 | (rt2x00dev->beacon_int - 20) * 16); | 533 | (rt2x00dev->beacon_int - 20) * 16); |
| 533 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | 534 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, |
| @@ -535,14 +536,14 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 535 | 536 | ||
| 536 | /* We must first disable autowake before it can be enabled */ | 537 | /* We must first disable autowake before it can be enabled */ |
| 537 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | 538 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); |
| 538 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 539 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 539 | 540 | ||
| 540 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | 541 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); |
| 541 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 542 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 542 | } else { | 543 | } else { |
| 543 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | 544 | rt2x00mmio_register_read(rt2x00dev, CSR20, ®); |
| 544 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | 545 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); |
| 545 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 546 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 546 | } | 547 | } |
| 547 | 548 | ||
| 548 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | 549 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); |
| @@ -568,10 +569,10 @@ static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | |||
| 568 | { | 569 | { |
| 569 | u32 reg; | 570 | u32 reg; |
| 570 | 571 | ||
| 571 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 572 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 572 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); | 573 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); |
| 573 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); | 574 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); |
| 574 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 575 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 575 | } | 576 | } |
| 576 | 577 | ||
| 577 | /* | 578 | /* |
| @@ -586,7 +587,7 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
| 586 | /* | 587 | /* |
| 587 | * Update FCS error count from register. | 588 | * Update FCS error count from register. |
| 588 | */ | 589 | */ |
| 589 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | 590 | rt2x00mmio_register_read(rt2x00dev, CNT0, ®); |
| 590 | qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); | 591 | qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); |
| 591 | 592 | ||
| 592 | /* | 593 | /* |
| @@ -641,16 +642,16 @@ static void rt2400pci_start_queue(struct data_queue *queue) | |||
| 641 | 642 | ||
| 642 | switch (queue->qid) { | 643 | switch (queue->qid) { |
| 643 | case QID_RX: | 644 | case QID_RX: |
| 644 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 645 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 645 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); | 646 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); |
| 646 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 647 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 647 | break; | 648 | break; |
| 648 | case QID_BEACON: | 649 | case QID_BEACON: |
| 649 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 650 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 650 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 651 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
| 651 | rt2x00_set_field32(®, CSR14_TBCN, 1); | 652 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
| 652 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 653 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
| 653 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 654 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 654 | break; | 655 | break; |
| 655 | default: | 656 | default: |
| 656 | break; | 657 | break; |
| @@ -664,19 +665,19 @@ static void rt2400pci_kick_queue(struct data_queue *queue) | |||
| 664 | 665 | ||
| 665 | switch (queue->qid) { | 666 | switch (queue->qid) { |
| 666 | case QID_AC_VO: | 667 | case QID_AC_VO: |
| 667 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 668 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 668 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | 669 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); |
| 669 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 670 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 670 | break; | 671 | break; |
| 671 | case QID_AC_VI: | 672 | case QID_AC_VI: |
| 672 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 673 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 673 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | 674 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); |
| 674 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 675 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 675 | break; | 676 | break; |
| 676 | case QID_ATIM: | 677 | case QID_ATIM: |
| 677 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 678 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 678 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | 679 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); |
| 679 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 680 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 680 | break; | 681 | break; |
| 681 | default: | 682 | default: |
| 682 | break; | 683 | break; |
| @@ -692,21 +693,21 @@ static void rt2400pci_stop_queue(struct data_queue *queue) | |||
| 692 | case QID_AC_VO: | 693 | case QID_AC_VO: |
| 693 | case QID_AC_VI: | 694 | case QID_AC_VI: |
| 694 | case QID_ATIM: | 695 | case QID_ATIM: |
| 695 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 696 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 696 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | 697 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); |
| 697 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 698 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 698 | break; | 699 | break; |
| 699 | case QID_RX: | 700 | case QID_RX: |
| 700 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 701 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 701 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); | 702 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); |
| 702 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 703 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 703 | break; | 704 | break; |
| 704 | case QID_BEACON: | 705 | case QID_BEACON: |
| 705 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 706 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 706 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | 707 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); |
| 707 | rt2x00_set_field32(®, CSR14_TBCN, 0); | 708 | rt2x00_set_field32(®, CSR14_TBCN, 0); |
| 708 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 709 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 709 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 710 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 710 | 711 | ||
| 711 | /* | 712 | /* |
| 712 | * Wait for possibly running tbtt tasklets. | 713 | * Wait for possibly running tbtt tasklets. |
| @@ -723,7 +724,7 @@ static void rt2400pci_stop_queue(struct data_queue *queue) | |||
| 723 | */ | 724 | */ |
| 724 | static bool rt2400pci_get_entry_state(struct queue_entry *entry) | 725 | static bool rt2400pci_get_entry_state(struct queue_entry *entry) |
| 725 | { | 726 | { |
| 726 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 727 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 727 | u32 word; | 728 | u32 word; |
| 728 | 729 | ||
| 729 | if (entry->queue->qid == QID_RX) { | 730 | if (entry->queue->qid == QID_RX) { |
| @@ -740,7 +741,7 @@ static bool rt2400pci_get_entry_state(struct queue_entry *entry) | |||
| 740 | 741 | ||
| 741 | static void rt2400pci_clear_entry(struct queue_entry *entry) | 742 | static void rt2400pci_clear_entry(struct queue_entry *entry) |
| 742 | { | 743 | { |
| 743 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 744 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 744 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 745 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 745 | u32 word; | 746 | u32 word; |
| 746 | 747 | ||
| @@ -766,53 +767,53 @@ static void rt2400pci_clear_entry(struct queue_entry *entry) | |||
| 766 | 767 | ||
| 767 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) | 768 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
| 768 | { | 769 | { |
| 769 | struct queue_entry_priv_pci *entry_priv; | 770 | struct queue_entry_priv_mmio *entry_priv; |
| 770 | u32 reg; | 771 | u32 reg; |
| 771 | 772 | ||
| 772 | /* | 773 | /* |
| 773 | * Initialize registers. | 774 | * Initialize registers. |
| 774 | */ | 775 | */ |
| 775 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 776 | rt2x00mmio_register_read(rt2x00dev, TXCSR2, ®); |
| 776 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); | 777 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
| 777 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); | 778 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
| 778 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); | 779 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); |
| 779 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); | 780 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
| 780 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 781 | rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg); |
| 781 | 782 | ||
| 782 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; | 783 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
| 783 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 784 | rt2x00mmio_register_read(rt2x00dev, TXCSR3, ®); |
| 784 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 785 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
| 785 | entry_priv->desc_dma); | 786 | entry_priv->desc_dma); |
| 786 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 787 | rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg); |
| 787 | 788 | ||
| 788 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; | 789 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
| 789 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 790 | rt2x00mmio_register_read(rt2x00dev, TXCSR5, ®); |
| 790 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 791 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
| 791 | entry_priv->desc_dma); | 792 | entry_priv->desc_dma); |
| 792 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 793 | rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg); |
| 793 | 794 | ||
| 794 | entry_priv = rt2x00dev->atim->entries[0].priv_data; | 795 | entry_priv = rt2x00dev->atim->entries[0].priv_data; |
| 795 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 796 | rt2x00mmio_register_read(rt2x00dev, TXCSR4, ®); |
| 796 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 797 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
| 797 | entry_priv->desc_dma); | 798 | entry_priv->desc_dma); |
| 798 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 799 | rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg); |
| 799 | 800 | ||
| 800 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; | 801 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; |
| 801 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 802 | rt2x00mmio_register_read(rt2x00dev, TXCSR6, ®); |
| 802 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 803 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
| 803 | entry_priv->desc_dma); | 804 | entry_priv->desc_dma); |
| 804 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 805 | rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg); |
| 805 | 806 | ||
| 806 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 807 | rt2x00mmio_register_read(rt2x00dev, RXCSR1, ®); |
| 807 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 808 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
| 808 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); | 809 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
| 809 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 810 | rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg); |
| 810 | 811 | ||
| 811 | entry_priv = rt2x00dev->rx->entries[0].priv_data; | 812 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
| 812 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 813 | rt2x00mmio_register_read(rt2x00dev, RXCSR2, ®); |
| 813 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 814 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, |
| 814 | entry_priv->desc_dma); | 815 | entry_priv->desc_dma); |
| 815 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 816 | rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg); |
| 816 | 817 | ||
| 817 | return 0; | 818 | return 0; |
| 818 | } | 819 | } |
| @@ -821,23 +822,23 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 821 | { | 822 | { |
| 822 | u32 reg; | 823 | u32 reg; |
| 823 | 824 | ||
| 824 | rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); | 825 | rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002); |
| 825 | rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); | 826 | rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002); |
| 826 | rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00023f20); | 827 | rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00023f20); |
| 827 | rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); | 828 | rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002); |
| 828 | 829 | ||
| 829 | rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); | 830 | rt2x00mmio_register_read(rt2x00dev, TIMECSR, ®); |
| 830 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); | 831 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); |
| 831 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); | 832 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); |
| 832 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); | 833 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); |
| 833 | rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); | 834 | rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg); |
| 834 | 835 | ||
| 835 | rt2x00pci_register_read(rt2x00dev, CSR9, ®); | 836 | rt2x00mmio_register_read(rt2x00dev, CSR9, ®); |
| 836 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, | 837 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, |
| 837 | (rt2x00dev->rx->data_size / 128)); | 838 | (rt2x00dev->rx->data_size / 128)); |
| 838 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 839 | rt2x00mmio_register_write(rt2x00dev, CSR9, reg); |
| 839 | 840 | ||
| 840 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 841 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 841 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | 842 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); |
| 842 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | 843 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); |
| 843 | rt2x00_set_field32(®, CSR14_TBCN, 0); | 844 | rt2x00_set_field32(®, CSR14_TBCN, 0); |
| @@ -846,63 +847,63 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 846 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 847 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 847 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); | 848 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); |
| 848 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); | 849 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); |
| 849 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 850 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 850 | 851 | ||
| 851 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | 852 | rt2x00mmio_register_write(rt2x00dev, CNT3, 0x3f080000); |
| 852 | 853 | ||
| 853 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | 854 | rt2x00mmio_register_read(rt2x00dev, ARCSR0, ®); |
| 854 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA0, 133); | 855 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA0, 133); |
| 855 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID0, 134); | 856 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID0, 134); |
| 856 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA1, 136); | 857 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA1, 136); |
| 857 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID1, 135); | 858 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID1, 135); |
| 858 | rt2x00pci_register_write(rt2x00dev, ARCSR0, reg); | 859 | rt2x00mmio_register_write(rt2x00dev, ARCSR0, reg); |
| 859 | 860 | ||
| 860 | rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); | 861 | rt2x00mmio_register_read(rt2x00dev, RXCSR3, ®); |
| 861 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 3); /* Tx power.*/ | 862 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 3); /* Tx power.*/ |
| 862 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); | 863 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); |
| 863 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 32); /* Signal */ | 864 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 32); /* Signal */ |
| 864 | rt2x00_set_field32(®, RXCSR3_BBP_ID1_VALID, 1); | 865 | rt2x00_set_field32(®, RXCSR3_BBP_ID1_VALID, 1); |
| 865 | rt2x00_set_field32(®, RXCSR3_BBP_ID2, 36); /* Rssi */ | 866 | rt2x00_set_field32(®, RXCSR3_BBP_ID2, 36); /* Rssi */ |
| 866 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); | 867 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); |
| 867 | rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); | 868 | rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg); |
| 868 | 869 | ||
| 869 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); | 870 | rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); |
| 870 | 871 | ||
| 871 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | 872 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) |
| 872 | return -EBUSY; | 873 | return -EBUSY; |
| 873 | 874 | ||
| 874 | rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00217223); | 875 | rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00217223); |
| 875 | rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); | 876 | rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518); |
| 876 | 877 | ||
| 877 | rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); | 878 | rt2x00mmio_register_read(rt2x00dev, MACCSR2, ®); |
| 878 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); | 879 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); |
| 879 | rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); | 880 | rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg); |
| 880 | 881 | ||
| 881 | rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); | 882 | rt2x00mmio_register_read(rt2x00dev, RALINKCSR, ®); |
| 882 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); | 883 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); |
| 883 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 154); | 884 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 154); |
| 884 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); | 885 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); |
| 885 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 154); | 886 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 154); |
| 886 | rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); | 887 | rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg); |
| 887 | 888 | ||
| 888 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | 889 | rt2x00mmio_register_read(rt2x00dev, CSR1, ®); |
| 889 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); | 890 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); |
| 890 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); | 891 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); |
| 891 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); | 892 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); |
| 892 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | 893 | rt2x00mmio_register_write(rt2x00dev, CSR1, reg); |
| 893 | 894 | ||
| 894 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | 895 | rt2x00mmio_register_read(rt2x00dev, CSR1, ®); |
| 895 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); | 896 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); |
| 896 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); | 897 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); |
| 897 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | 898 | rt2x00mmio_register_write(rt2x00dev, CSR1, reg); |
| 898 | 899 | ||
| 899 | /* | 900 | /* |
| 900 | * We must clear the FCS and FIFO error count. | 901 | * We must clear the FCS and FIFO error count. |
| 901 | * These registers are cleared on read, | 902 | * These registers are cleared on read, |
| 902 | * so we may pass a useless variable to store the value. | 903 | * so we may pass a useless variable to store the value. |
| 903 | */ | 904 | */ |
| 904 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | 905 | rt2x00mmio_register_read(rt2x00dev, CNT0, ®); |
| 905 | rt2x00pci_register_read(rt2x00dev, CNT4, ®); | 906 | rt2x00mmio_register_read(rt2x00dev, CNT4, ®); |
| 906 | 907 | ||
| 907 | return 0; | 908 | return 0; |
| 908 | } | 909 | } |
| @@ -919,7 +920,7 @@ static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 919 | udelay(REGISTER_BUSY_DELAY); | 920 | udelay(REGISTER_BUSY_DELAY); |
| 920 | } | 921 | } |
| 921 | 922 | ||
| 922 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 923 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 923 | return -EACCES; | 924 | return -EACCES; |
| 924 | } | 925 | } |
| 925 | 926 | ||
| @@ -976,8 +977,8 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 976 | * should clear the register to assure a clean state. | 977 | * should clear the register to assure a clean state. |
| 977 | */ | 978 | */ |
| 978 | if (state == STATE_RADIO_IRQ_ON) { | 979 | if (state == STATE_RADIO_IRQ_ON) { |
| 979 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | 980 | rt2x00mmio_register_read(rt2x00dev, CSR7, ®); |
| 980 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | 981 | rt2x00mmio_register_write(rt2x00dev, CSR7, reg); |
| 981 | } | 982 | } |
| 982 | 983 | ||
| 983 | /* | 984 | /* |
| @@ -986,13 +987,13 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 986 | */ | 987 | */ |
| 987 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 988 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); |
| 988 | 989 | ||
| 989 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 990 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 990 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); | 991 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); |
| 991 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); | 992 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); |
| 992 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); | 993 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); |
| 993 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); | 994 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); |
| 994 | rt2x00_set_field32(®, CSR8_RXDONE, mask); | 995 | rt2x00_set_field32(®, CSR8_RXDONE, mask); |
| 995 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 996 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 996 | 997 | ||
| 997 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 998 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); |
| 998 | 999 | ||
| @@ -1025,7 +1026,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 1025 | /* | 1026 | /* |
| 1026 | * Disable power | 1027 | * Disable power |
| 1027 | */ | 1028 | */ |
| 1028 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1029 | rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0); |
| 1029 | } | 1030 | } |
| 1030 | 1031 | ||
| 1031 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | 1032 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, |
| @@ -1039,12 +1040,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
| 1039 | 1040 | ||
| 1040 | put_to_sleep = (state != STATE_AWAKE); | 1041 | put_to_sleep = (state != STATE_AWAKE); |
| 1041 | 1042 | ||
| 1042 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | 1043 | rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®); |
| 1043 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); | 1044 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); |
| 1044 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); | 1045 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); |
| 1045 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); | 1046 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); |
| 1046 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); | 1047 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); |
| 1047 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | 1048 | rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); |
| 1048 | 1049 | ||
| 1049 | /* | 1050 | /* |
| 1050 | * Device is not guaranteed to be in the requested state yet. | 1051 | * Device is not guaranteed to be in the requested state yet. |
| @@ -1052,12 +1053,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
| 1052 | * device has entered the correct state. | 1053 | * device has entered the correct state. |
| 1053 | */ | 1054 | */ |
| 1054 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1055 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
| 1055 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); | 1056 | rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®2); |
| 1056 | bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); | 1057 | bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); |
| 1057 | rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); | 1058 | rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); |
| 1058 | if (bbp_state == state && rf_state == state) | 1059 | if (bbp_state == state && rf_state == state) |
| 1059 | return 0; | 1060 | return 0; |
| 1060 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | 1061 | rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); |
| 1061 | msleep(10); | 1062 | msleep(10); |
| 1062 | } | 1063 | } |
| 1063 | 1064 | ||
| @@ -1092,8 +1093,8 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 1092 | } | 1093 | } |
| 1093 | 1094 | ||
| 1094 | if (unlikely(retval)) | 1095 | if (unlikely(retval)) |
| 1095 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 1096 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 1096 | state, retval); | 1097 | state, retval); |
| 1097 | 1098 | ||
| 1098 | return retval; | 1099 | return retval; |
| 1099 | } | 1100 | } |
| @@ -1105,7 +1106,7 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, | |||
| 1105 | struct txentry_desc *txdesc) | 1106 | struct txentry_desc *txdesc) |
| 1106 | { | 1107 | { |
| 1107 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1108 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 1108 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1109 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1109 | __le32 *txd = entry_priv->desc; | 1110 | __le32 *txd = entry_priv->desc; |
| 1110 | u32 word; | 1111 | u32 word; |
| 1111 | 1112 | ||
| @@ -1182,12 +1183,12 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
| 1182 | * Disable beaconing while we are reloading the beacon data, | 1183 | * Disable beaconing while we are reloading the beacon data, |
| 1183 | * otherwise we might be sending out invalid data. | 1184 | * otherwise we might be sending out invalid data. |
| 1184 | */ | 1185 | */ |
| 1185 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1186 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 1186 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 1187 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 1187 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1188 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 1188 | 1189 | ||
| 1189 | if (rt2x00queue_map_txskb(entry)) { | 1190 | if (rt2x00queue_map_txskb(entry)) { |
| 1190 | ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); | 1191 | rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n"); |
| 1191 | goto out; | 1192 | goto out; |
| 1192 | } | 1193 | } |
| 1193 | /* | 1194 | /* |
| @@ -1208,7 +1209,7 @@ out: | |||
| 1208 | * Enable beaconing again. | 1209 | * Enable beaconing again. |
| 1209 | */ | 1210 | */ |
| 1210 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1211 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
| 1211 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1212 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 1212 | } | 1213 | } |
| 1213 | 1214 | ||
| 1214 | /* | 1215 | /* |
| @@ -1218,7 +1219,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, | |||
| 1218 | struct rxdone_entry_desc *rxdesc) | 1219 | struct rxdone_entry_desc *rxdesc) |
| 1219 | { | 1220 | { |
| 1220 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1221 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| 1221 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1222 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1222 | u32 word0; | 1223 | u32 word0; |
| 1223 | u32 word2; | 1224 | u32 word2; |
| 1224 | u32 word3; | 1225 | u32 word3; |
| @@ -1276,7 +1277,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
| 1276 | const enum data_queue_qid queue_idx) | 1277 | const enum data_queue_qid queue_idx) |
| 1277 | { | 1278 | { |
| 1278 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); | 1279 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
| 1279 | struct queue_entry_priv_pci *entry_priv; | 1280 | struct queue_entry_priv_mmio *entry_priv; |
| 1280 | struct queue_entry *entry; | 1281 | struct queue_entry *entry; |
| 1281 | struct txdone_entry_desc txdesc; | 1282 | struct txdone_entry_desc txdesc; |
| 1282 | u32 word; | 1283 | u32 word; |
| @@ -1322,9 +1323,9 @@ static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | |||
| 1322 | */ | 1323 | */ |
| 1323 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 1324 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 1324 | 1325 | ||
| 1325 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1326 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1326 | rt2x00_set_field32(®, irq_field, 0); | 1327 | rt2x00_set_field32(®, irq_field, 0); |
| 1327 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1328 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1328 | 1329 | ||
| 1329 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 1330 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 1330 | } | 1331 | } |
| @@ -1347,11 +1348,11 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) | |||
| 1347 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { | 1348 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { |
| 1348 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 1349 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 1349 | 1350 | ||
| 1350 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1351 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1351 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); | 1352 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); |
| 1352 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); | 1353 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); |
| 1353 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); | 1354 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); |
| 1354 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1355 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1355 | 1356 | ||
| 1356 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 1357 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 1357 | } | 1358 | } |
| @@ -1368,7 +1369,7 @@ static void rt2400pci_tbtt_tasklet(unsigned long data) | |||
| 1368 | static void rt2400pci_rxdone_tasklet(unsigned long data) | 1369 | static void rt2400pci_rxdone_tasklet(unsigned long data) |
| 1369 | { | 1370 | { |
| 1370 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 1371 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
| 1371 | if (rt2x00pci_rxdone(rt2x00dev)) | 1372 | if (rt2x00mmio_rxdone(rt2x00dev)) |
| 1372 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); | 1373 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); |
| 1373 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 1374 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 1374 | rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); | 1375 | rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); |
| @@ -1383,8 +1384,8 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
| 1383 | * Get the interrupt sources & saved to local variable. | 1384 | * Get the interrupt sources & saved to local variable. |
| 1384 | * Write register value back to clear pending interrupts. | 1385 | * Write register value back to clear pending interrupts. |
| 1385 | */ | 1386 | */ |
| 1386 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | 1387 | rt2x00mmio_register_read(rt2x00dev, CSR7, ®); |
| 1387 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | 1388 | rt2x00mmio_register_write(rt2x00dev, CSR7, reg); |
| 1388 | 1389 | ||
| 1389 | if (!reg) | 1390 | if (!reg) |
| 1390 | return IRQ_NONE; | 1391 | return IRQ_NONE; |
| @@ -1421,9 +1422,9 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
| 1421 | */ | 1422 | */ |
| 1422 | spin_lock(&rt2x00dev->irqmask_lock); | 1423 | spin_lock(&rt2x00dev->irqmask_lock); |
| 1423 | 1424 | ||
| 1424 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1425 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1425 | reg |= mask; | 1426 | reg |= mask; |
| 1426 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1427 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1427 | 1428 | ||
| 1428 | spin_unlock(&rt2x00dev->irqmask_lock); | 1429 | spin_unlock(&rt2x00dev->irqmask_lock); |
| 1429 | 1430 | ||
| @@ -1442,7 +1443,7 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1442 | u16 word; | 1443 | u16 word; |
| 1443 | u8 *mac; | 1444 | u8 *mac; |
| 1444 | 1445 | ||
| 1445 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | 1446 | rt2x00mmio_register_read(rt2x00dev, CSR21, ®); |
| 1446 | 1447 | ||
| 1447 | eeprom.data = rt2x00dev; | 1448 | eeprom.data = rt2x00dev; |
| 1448 | eeprom.register_read = rt2400pci_eepromregister_read; | 1449 | eeprom.register_read = rt2400pci_eepromregister_read; |
| @@ -1463,12 +1464,12 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1463 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 1464 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 1464 | if (!is_valid_ether_addr(mac)) { | 1465 | if (!is_valid_ether_addr(mac)) { |
| 1465 | eth_random_addr(mac); | 1466 | eth_random_addr(mac); |
| 1466 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 1467 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 1467 | } | 1468 | } |
| 1468 | 1469 | ||
| 1469 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 1470 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); |
| 1470 | if (word == 0xffff) { | 1471 | if (word == 0xffff) { |
| 1471 | ERROR(rt2x00dev, "Invalid EEPROM data detected.\n"); | 1472 | rt2x00_err(rt2x00dev, "Invalid EEPROM data detected\n"); |
| 1472 | return -EINVAL; | 1473 | return -EINVAL; |
| 1473 | } | 1474 | } |
| 1474 | 1475 | ||
| @@ -1490,12 +1491,12 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1490 | * Identify RF chipset. | 1491 | * Identify RF chipset. |
| 1491 | */ | 1492 | */ |
| 1492 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1493 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
| 1493 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | 1494 | rt2x00mmio_register_read(rt2x00dev, CSR0, ®); |
| 1494 | rt2x00_set_chip(rt2x00dev, RT2460, value, | 1495 | rt2x00_set_chip(rt2x00dev, RT2460, value, |
| 1495 | rt2x00_get_field32(reg, CSR0_REVISION)); | 1496 | rt2x00_get_field32(reg, CSR0_REVISION)); |
| 1496 | 1497 | ||
| 1497 | if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) { | 1498 | if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) { |
| 1498 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 1499 | rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); |
| 1499 | return -ENODEV; | 1500 | return -ENODEV; |
| 1500 | } | 1501 | } |
| 1501 | 1502 | ||
| @@ -1635,9 +1636,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 1635 | * Enable rfkill polling by setting GPIO direction of the | 1636 | * Enable rfkill polling by setting GPIO direction of the |
| 1636 | * rfkill switch GPIO pin correctly. | 1637 | * rfkill switch GPIO pin correctly. |
| 1637 | */ | 1638 | */ |
| 1638 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | 1639 | rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); |
| 1639 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | 1640 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); |
| 1640 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | 1641 | rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg); |
| 1641 | 1642 | ||
| 1642 | /* | 1643 | /* |
| 1643 | * Initialize hw specifications. | 1644 | * Initialize hw specifications. |
| @@ -1697,9 +1698,9 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw, | |||
| 1697 | u64 tsf; | 1698 | u64 tsf; |
| 1698 | u32 reg; | 1699 | u32 reg; |
| 1699 | 1700 | ||
| 1700 | rt2x00pci_register_read(rt2x00dev, CSR17, ®); | 1701 | rt2x00mmio_register_read(rt2x00dev, CSR17, ®); |
| 1701 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; | 1702 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; |
| 1702 | rt2x00pci_register_read(rt2x00dev, CSR16, ®); | 1703 | rt2x00mmio_register_read(rt2x00dev, CSR16, ®); |
| 1703 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); | 1704 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); |
| 1704 | 1705 | ||
| 1705 | return tsf; | 1706 | return tsf; |
| @@ -1710,7 +1711,7 @@ static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | |||
| 1710 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1711 | struct rt2x00_dev *rt2x00dev = hw->priv; |
| 1711 | u32 reg; | 1712 | u32 reg; |
| 1712 | 1713 | ||
| 1713 | rt2x00pci_register_read(rt2x00dev, CSR15, ®); | 1714 | rt2x00mmio_register_read(rt2x00dev, CSR15, ®); |
| 1714 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); | 1715 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); |
| 1715 | } | 1716 | } |
| 1716 | 1717 | ||
| @@ -1743,8 +1744,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
| 1743 | .tbtt_tasklet = rt2400pci_tbtt_tasklet, | 1744 | .tbtt_tasklet = rt2400pci_tbtt_tasklet, |
| 1744 | .rxdone_tasklet = rt2400pci_rxdone_tasklet, | 1745 | .rxdone_tasklet = rt2400pci_rxdone_tasklet, |
| 1745 | .probe_hw = rt2400pci_probe_hw, | 1746 | .probe_hw = rt2400pci_probe_hw, |
| 1746 | .initialize = rt2x00pci_initialize, | 1747 | .initialize = rt2x00mmio_initialize, |
| 1747 | .uninitialize = rt2x00pci_uninitialize, | 1748 | .uninitialize = rt2x00mmio_uninitialize, |
| 1748 | .get_entry_state = rt2400pci_get_entry_state, | 1749 | .get_entry_state = rt2400pci_get_entry_state, |
| 1749 | .clear_entry = rt2400pci_clear_entry, | 1750 | .clear_entry = rt2400pci_clear_entry, |
| 1750 | .set_device_state = rt2400pci_set_device_state, | 1751 | .set_device_state = rt2400pci_set_device_state, |
| @@ -1755,7 +1756,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
| 1755 | .start_queue = rt2400pci_start_queue, | 1756 | .start_queue = rt2400pci_start_queue, |
| 1756 | .kick_queue = rt2400pci_kick_queue, | 1757 | .kick_queue = rt2400pci_kick_queue, |
| 1757 | .stop_queue = rt2400pci_stop_queue, | 1758 | .stop_queue = rt2400pci_stop_queue, |
| 1758 | .flush_queue = rt2x00pci_flush_queue, | 1759 | .flush_queue = rt2x00mmio_flush_queue, |
| 1759 | .write_tx_desc = rt2400pci_write_tx_desc, | 1760 | .write_tx_desc = rt2400pci_write_tx_desc, |
| 1760 | .write_beacon = rt2400pci_write_beacon, | 1761 | .write_beacon = rt2400pci_write_beacon, |
| 1761 | .fill_rxdone = rt2400pci_fill_rxdone, | 1762 | .fill_rxdone = rt2400pci_fill_rxdone, |
| @@ -1770,28 +1771,28 @@ static const struct data_queue_desc rt2400pci_queue_rx = { | |||
| 1770 | .entry_num = 24, | 1771 | .entry_num = 24, |
| 1771 | .data_size = DATA_FRAME_SIZE, | 1772 | .data_size = DATA_FRAME_SIZE, |
| 1772 | .desc_size = RXD_DESC_SIZE, | 1773 | .desc_size = RXD_DESC_SIZE, |
| 1773 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1774 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 1774 | }; | 1775 | }; |
| 1775 | 1776 | ||
| 1776 | static const struct data_queue_desc rt2400pci_queue_tx = { | 1777 | static const struct data_queue_desc rt2400pci_queue_tx = { |
| 1777 | .entry_num = 24, | 1778 | .entry_num = 24, |
| 1778 | .data_size = DATA_FRAME_SIZE, | 1779 | .data_size = DATA_FRAME_SIZE, |
| 1779 | .desc_size = TXD_DESC_SIZE, | 1780 | .desc_size = TXD_DESC_SIZE, |
| 1780 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1781 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 1781 | }; | 1782 | }; |
| 1782 | 1783 | ||
| 1783 | static const struct data_queue_desc rt2400pci_queue_bcn = { | 1784 | static const struct data_queue_desc rt2400pci_queue_bcn = { |
| 1784 | .entry_num = 1, | 1785 | .entry_num = 1, |
| 1785 | .data_size = MGMT_FRAME_SIZE, | 1786 | .data_size = MGMT_FRAME_SIZE, |
| 1786 | .desc_size = TXD_DESC_SIZE, | 1787 | .desc_size = TXD_DESC_SIZE, |
| 1787 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1788 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 1788 | }; | 1789 | }; |
| 1789 | 1790 | ||
| 1790 | static const struct data_queue_desc rt2400pci_queue_atim = { | 1791 | static const struct data_queue_desc rt2400pci_queue_atim = { |
| 1791 | .entry_num = 8, | 1792 | .entry_num = 8, |
| 1792 | .data_size = DATA_FRAME_SIZE, | 1793 | .data_size = DATA_FRAME_SIZE, |
| 1793 | .desc_size = TXD_DESC_SIZE, | 1794 | .desc_size = TXD_DESC_SIZE, |
| 1794 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1795 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 1795 | }; | 1796 | }; |
| 1796 | 1797 | ||
| 1797 | static const struct rt2x00_ops rt2400pci_ops = { | 1798 | static const struct rt2x00_ops rt2400pci_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index e1d2dc9ed28a..77e45b223d15 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | /* | 41 | /* |
| 42 | * Register access. | 42 | * Register access. |
| 43 | * All access to the CSR registers will go through the methods | 43 | * All access to the CSR registers will go through the methods |
| 44 | * rt2x00pci_register_read and rt2x00pci_register_write. | 44 | * rt2x00mmio_register_read and rt2x00mmio_register_write. |
| 45 | * BBP and RF register require indirect register access, | 45 | * BBP and RF register require indirect register access, |
| 46 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | 46 | * and use the CSR registers BBPCSR and RFCSR to achieve this. |
| 47 | * These indirect registers work with busy bits, | 47 | * These indirect registers work with busy bits, |
| @@ -52,9 +52,9 @@ | |||
| 52 | * and we will print an error. | 52 | * and we will print an error. |
| 53 | */ | 53 | */ |
| 54 | #define WAIT_FOR_BBP(__dev, __reg) \ | 54 | #define WAIT_FOR_BBP(__dev, __reg) \ |
| 55 | rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) | 55 | rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) |
| 56 | #define WAIT_FOR_RF(__dev, __reg) \ | 56 | #define WAIT_FOR_RF(__dev, __reg) \ |
| 57 | rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) | 57 | rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) |
| 58 | 58 | ||
| 59 | static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 59 | static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
| 60 | const unsigned int word, const u8 value) | 60 | const unsigned int word, const u8 value) |
| @@ -74,7 +74,7 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
| 74 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | 74 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
| 75 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | 75 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); |
| 76 | 76 | ||
| 77 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 77 | rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | mutex_unlock(&rt2x00dev->csr_mutex); | 80 | mutex_unlock(&rt2x00dev->csr_mutex); |
| @@ -101,7 +101,7 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
| 101 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | 101 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
| 102 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | 102 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); |
| 103 | 103 | ||
| 104 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 104 | rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); |
| 105 | 105 | ||
| 106 | WAIT_FOR_BBP(rt2x00dev, ®); | 106 | WAIT_FOR_BBP(rt2x00dev, ®); |
| 107 | } | 107 | } |
| @@ -129,7 +129,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
| 129 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | 129 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); |
| 130 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | 130 | rt2x00_set_field32(®, RFCSR_BUSY, 1); |
| 131 | 131 | ||
| 132 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | 132 | rt2x00mmio_register_write(rt2x00dev, RFCSR, reg); |
| 133 | rt2x00_rf_write(rt2x00dev, word, value); | 133 | rt2x00_rf_write(rt2x00dev, word, value); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| @@ -141,7 +141,7 @@ static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | |||
| 141 | struct rt2x00_dev *rt2x00dev = eeprom->data; | 141 | struct rt2x00_dev *rt2x00dev = eeprom->data; |
| 142 | u32 reg; | 142 | u32 reg; |
| 143 | 143 | ||
| 144 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | 144 | rt2x00mmio_register_read(rt2x00dev, CSR21, ®); |
| 145 | 145 | ||
| 146 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); | 146 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); |
| 147 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); | 147 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); |
| @@ -163,15 +163,15 @@ static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
| 163 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, | 163 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, |
| 164 | !!eeprom->reg_chip_select); | 164 | !!eeprom->reg_chip_select); |
| 165 | 165 | ||
| 166 | rt2x00pci_register_write(rt2x00dev, CSR21, reg); | 166 | rt2x00mmio_register_write(rt2x00dev, CSR21, reg); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 169 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
| 170 | static const struct rt2x00debug rt2500pci_rt2x00debug = { | 170 | static const struct rt2x00debug rt2500pci_rt2x00debug = { |
| 171 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
| 172 | .csr = { | 172 | .csr = { |
| 173 | .read = rt2x00pci_register_read, | 173 | .read = rt2x00mmio_register_read, |
| 174 | .write = rt2x00pci_register_write, | 174 | .write = rt2x00mmio_register_write, |
| 175 | .flags = RT2X00DEBUGFS_OFFSET, | 175 | .flags = RT2X00DEBUGFS_OFFSET, |
| 176 | .word_base = CSR_REG_BASE, | 176 | .word_base = CSR_REG_BASE, |
| 177 | .word_size = sizeof(u32), | 177 | .word_size = sizeof(u32), |
| @@ -205,7 +205,7 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
| 205 | { | 205 | { |
| 206 | u32 reg; | 206 | u32 reg; |
| 207 | 207 | ||
| 208 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | 208 | rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); |
| 209 | return rt2x00_get_field32(reg, GPIOCSR_VAL0); | 209 | return rt2x00_get_field32(reg, GPIOCSR_VAL0); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| @@ -218,14 +218,14 @@ static void rt2500pci_brightness_set(struct led_classdev *led_cdev, | |||
| 218 | unsigned int enabled = brightness != LED_OFF; | 218 | unsigned int enabled = brightness != LED_OFF; |
| 219 | u32 reg; | 219 | u32 reg; |
| 220 | 220 | ||
| 221 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | 221 | rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); |
| 222 | 222 | ||
| 223 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) | 223 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) |
| 224 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); | 224 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
| 225 | else if (led->type == LED_TYPE_ACTIVITY) | 225 | else if (led->type == LED_TYPE_ACTIVITY) |
| 226 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); | 226 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); |
| 227 | 227 | ||
| 228 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | 228 | rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | static int rt2500pci_blink_set(struct led_classdev *led_cdev, | 231 | static int rt2500pci_blink_set(struct led_classdev *led_cdev, |
| @@ -236,10 +236,10 @@ static int rt2500pci_blink_set(struct led_classdev *led_cdev, | |||
| 236 | container_of(led_cdev, struct rt2x00_led, led_dev); | 236 | container_of(led_cdev, struct rt2x00_led, led_dev); |
| 237 | u32 reg; | 237 | u32 reg; |
| 238 | 238 | ||
| 239 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); | 239 | rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); |
| 240 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); | 240 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); |
| 241 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); | 241 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); |
| 242 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | 242 | rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); |
| 243 | 243 | ||
| 244 | return 0; | 244 | return 0; |
| 245 | } | 245 | } |
| @@ -270,7 +270,7 @@ static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 270 | * and broadcast frames will always be accepted since | 270 | * and broadcast frames will always be accepted since |
| 271 | * there is no filter for it at this time. | 271 | * there is no filter for it at this time. |
| 272 | */ | 272 | */ |
| 273 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 273 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 274 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, | 274 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, |
| 275 | !(filter_flags & FIF_FCSFAIL)); | 275 | !(filter_flags & FIF_FCSFAIL)); |
| 276 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, | 276 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, |
| @@ -286,7 +286,7 @@ static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 286 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, | 286 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, |
| 287 | !(filter_flags & FIF_ALLMULTI)); | 287 | !(filter_flags & FIF_ALLMULTI)); |
| 288 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); | 288 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); |
| 289 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 289 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | 292 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, |
| @@ -303,25 +303,25 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
| 303 | * Enable beacon config | 303 | * Enable beacon config |
| 304 | */ | 304 | */ |
| 305 | bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); | 305 | bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); |
| 306 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 306 | rt2x00mmio_register_read(rt2x00dev, BCNCSR1, ®); |
| 307 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | 307 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
| 308 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | 308 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); |
| 309 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 309 | rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg); |
| 310 | 310 | ||
| 311 | /* | 311 | /* |
| 312 | * Enable synchronisation. | 312 | * Enable synchronisation. |
| 313 | */ | 313 | */ |
| 314 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 314 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 315 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 315 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
| 316 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 316 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | if (flags & CONFIG_UPDATE_MAC) | 319 | if (flags & CONFIG_UPDATE_MAC) |
| 320 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | 320 | rt2x00mmio_register_multiwrite(rt2x00dev, CSR3, |
| 321 | conf->mac, sizeof(conf->mac)); | 321 | conf->mac, sizeof(conf->mac)); |
| 322 | 322 | ||
| 323 | if (flags & CONFIG_UPDATE_BSSID) | 323 | if (flags & CONFIG_UPDATE_BSSID) |
| 324 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | 324 | rt2x00mmio_register_multiwrite(rt2x00dev, CSR5, |
| 325 | conf->bssid, sizeof(conf->bssid)); | 325 | conf->bssid, sizeof(conf->bssid)); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| @@ -338,68 +338,68 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
| 338 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 338 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
| 339 | preamble_mask = erp->short_preamble << 3; | 339 | preamble_mask = erp->short_preamble << 3; |
| 340 | 340 | ||
| 341 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 341 | rt2x00mmio_register_read(rt2x00dev, TXCSR1, ®); |
| 342 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); | 342 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); |
| 343 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); | 343 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); |
| 344 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | 344 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); |
| 345 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | 345 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); |
| 346 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 346 | rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg); |
| 347 | 347 | ||
| 348 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 348 | rt2x00mmio_register_read(rt2x00dev, ARCSR2, ®); |
| 349 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 349 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
| 350 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 350 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
| 351 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 351 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 352 | GET_DURATION(ACK_SIZE, 10)); | 352 | GET_DURATION(ACK_SIZE, 10)); |
| 353 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 353 | rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg); |
| 354 | 354 | ||
| 355 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | 355 | rt2x00mmio_register_read(rt2x00dev, ARCSR3, ®); |
| 356 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 356 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
| 357 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 357 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
| 358 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 358 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 359 | GET_DURATION(ACK_SIZE, 20)); | 359 | GET_DURATION(ACK_SIZE, 20)); |
| 360 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | 360 | rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg); |
| 361 | 361 | ||
| 362 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | 362 | rt2x00mmio_register_read(rt2x00dev, ARCSR4, ®); |
| 363 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 363 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
| 364 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 364 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); |
| 365 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 365 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 366 | GET_DURATION(ACK_SIZE, 55)); | 366 | GET_DURATION(ACK_SIZE, 55)); |
| 367 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | 367 | rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg); |
| 368 | 368 | ||
| 369 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | 369 | rt2x00mmio_register_read(rt2x00dev, ARCSR5, ®); |
| 370 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 370 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); |
| 371 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 371 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
| 372 | rt2x00_set_field32(®, ARCSR2_LENGTH, | 372 | rt2x00_set_field32(®, ARCSR2_LENGTH, |
| 373 | GET_DURATION(ACK_SIZE, 110)); | 373 | GET_DURATION(ACK_SIZE, 110)); |
| 374 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 374 | rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg); |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | if (changed & BSS_CHANGED_BASIC_RATES) | 377 | if (changed & BSS_CHANGED_BASIC_RATES) |
| 378 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); | 378 | rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates); |
| 379 | 379 | ||
| 380 | if (changed & BSS_CHANGED_ERP_SLOT) { | 380 | if (changed & BSS_CHANGED_ERP_SLOT) { |
| 381 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 381 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 382 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); | 382 | rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); |
| 383 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 383 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 384 | 384 | ||
| 385 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); | 385 | rt2x00mmio_register_read(rt2x00dev, CSR18, ®); |
| 386 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); | 386 | rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); |
| 387 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); | 387 | rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); |
| 388 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | 388 | rt2x00mmio_register_write(rt2x00dev, CSR18, reg); |
| 389 | 389 | ||
| 390 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | 390 | rt2x00mmio_register_read(rt2x00dev, CSR19, ®); |
| 391 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); | 391 | rt2x00_set_field32(®, CSR19_DIFS, erp->difs); |
| 392 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); | 392 | rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); |
| 393 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | 393 | rt2x00mmio_register_write(rt2x00dev, CSR19, reg); |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | if (changed & BSS_CHANGED_BEACON_INT) { | 396 | if (changed & BSS_CHANGED_BEACON_INT) { |
| 397 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | 397 | rt2x00mmio_register_read(rt2x00dev, CSR12, ®); |
| 398 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, | 398 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, |
| 399 | erp->beacon_int * 16); | 399 | erp->beacon_int * 16); |
| 400 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, | 400 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, |
| 401 | erp->beacon_int * 16); | 401 | erp->beacon_int * 16); |
| 402 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 402 | rt2x00mmio_register_write(rt2x00dev, CSR12, reg); |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | } | 405 | } |
| @@ -418,7 +418,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, | |||
| 418 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | 418 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || |
| 419 | ant->tx == ANTENNA_SW_DIVERSITY); | 419 | ant->tx == ANTENNA_SW_DIVERSITY); |
| 420 | 420 | ||
| 421 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); | 421 | rt2x00mmio_register_read(rt2x00dev, BBPCSR1, ®); |
| 422 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); | 422 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); |
| 423 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); | 423 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); |
| 424 | 424 | ||
| @@ -470,7 +470,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, | |||
| 470 | rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 0); | 470 | rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 0); |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg); | 473 | rt2x00mmio_register_write(rt2x00dev, BBPCSR1, reg); |
| 474 | rt2500pci_bbp_write(rt2x00dev, 14, r14); | 474 | rt2500pci_bbp_write(rt2x00dev, 14, r14); |
| 475 | rt2500pci_bbp_write(rt2x00dev, 2, r2); | 475 | rt2500pci_bbp_write(rt2x00dev, 2, r2); |
| 476 | } | 476 | } |
| @@ -541,7 +541,7 @@ static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 541 | /* | 541 | /* |
| 542 | * Clear false CRC during channel switch. | 542 | * Clear false CRC during channel switch. |
| 543 | */ | 543 | */ |
| 544 | rt2x00pci_register_read(rt2x00dev, CNT0, &rf->rf1); | 544 | rt2x00mmio_register_read(rt2x00dev, CNT0, &rf->rf1); |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, | 547 | static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, |
| @@ -559,12 +559,12 @@ static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, | |||
| 559 | { | 559 | { |
| 560 | u32 reg; | 560 | u32 reg; |
| 561 | 561 | ||
| 562 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 562 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 563 | rt2x00_set_field32(®, CSR11_LONG_RETRY, | 563 | rt2x00_set_field32(®, CSR11_LONG_RETRY, |
| 564 | libconf->conf->long_frame_max_tx_count); | 564 | libconf->conf->long_frame_max_tx_count); |
| 565 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, | 565 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, |
| 566 | libconf->conf->short_frame_max_tx_count); | 566 | libconf->conf->short_frame_max_tx_count); |
| 567 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 567 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | 570 | static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, |
| @@ -576,7 +576,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 576 | u32 reg; | 576 | u32 reg; |
| 577 | 577 | ||
| 578 | if (state == STATE_SLEEP) { | 578 | if (state == STATE_SLEEP) { |
| 579 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | 579 | rt2x00mmio_register_read(rt2x00dev, CSR20, ®); |
| 580 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | 580 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, |
| 581 | (rt2x00dev->beacon_int - 20) * 16); | 581 | (rt2x00dev->beacon_int - 20) * 16); |
| 582 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | 582 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, |
| @@ -584,14 +584,14 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 584 | 584 | ||
| 585 | /* We must first disable autowake before it can be enabled */ | 585 | /* We must first disable autowake before it can be enabled */ |
| 586 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | 586 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); |
| 587 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 587 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 588 | 588 | ||
| 589 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | 589 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); |
| 590 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 590 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 591 | } else { | 591 | } else { |
| 592 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | 592 | rt2x00mmio_register_read(rt2x00dev, CSR20, ®); |
| 593 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | 593 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); |
| 594 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | 594 | rt2x00mmio_register_write(rt2x00dev, CSR20, reg); |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | 597 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); |
| @@ -625,13 +625,13 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
| 625 | /* | 625 | /* |
| 626 | * Update FCS error count from register. | 626 | * Update FCS error count from register. |
| 627 | */ | 627 | */ |
| 628 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | 628 | rt2x00mmio_register_read(rt2x00dev, CNT0, ®); |
| 629 | qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); | 629 | qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); |
| 630 | 630 | ||
| 631 | /* | 631 | /* |
| 632 | * Update False CCA count from register. | 632 | * Update False CCA count from register. |
| 633 | */ | 633 | */ |
| 634 | rt2x00pci_register_read(rt2x00dev, CNT3, ®); | 634 | rt2x00mmio_register_read(rt2x00dev, CNT3, ®); |
| 635 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); | 635 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); |
| 636 | } | 636 | } |
| 637 | 637 | ||
| @@ -731,16 +731,16 @@ static void rt2500pci_start_queue(struct data_queue *queue) | |||
| 731 | 731 | ||
| 732 | switch (queue->qid) { | 732 | switch (queue->qid) { |
| 733 | case QID_RX: | 733 | case QID_RX: |
| 734 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 734 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 735 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); | 735 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); |
| 736 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 736 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 737 | break; | 737 | break; |
| 738 | case QID_BEACON: | 738 | case QID_BEACON: |
| 739 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 739 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 740 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 740 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
| 741 | rt2x00_set_field32(®, CSR14_TBCN, 1); | 741 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
| 742 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 742 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
| 743 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 743 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 744 | break; | 744 | break; |
| 745 | default: | 745 | default: |
| 746 | break; | 746 | break; |
| @@ -754,19 +754,19 @@ static void rt2500pci_kick_queue(struct data_queue *queue) | |||
| 754 | 754 | ||
| 755 | switch (queue->qid) { | 755 | switch (queue->qid) { |
| 756 | case QID_AC_VO: | 756 | case QID_AC_VO: |
| 757 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 757 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 758 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | 758 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); |
| 759 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 759 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 760 | break; | 760 | break; |
| 761 | case QID_AC_VI: | 761 | case QID_AC_VI: |
| 762 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 762 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 763 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | 763 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); |
| 764 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 764 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 765 | break; | 765 | break; |
| 766 | case QID_ATIM: | 766 | case QID_ATIM: |
| 767 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 767 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 768 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | 768 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); |
| 769 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 769 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 770 | break; | 770 | break; |
| 771 | default: | 771 | default: |
| 772 | break; | 772 | break; |
| @@ -782,21 +782,21 @@ static void rt2500pci_stop_queue(struct data_queue *queue) | |||
| 782 | case QID_AC_VO: | 782 | case QID_AC_VO: |
| 783 | case QID_AC_VI: | 783 | case QID_AC_VI: |
| 784 | case QID_ATIM: | 784 | case QID_ATIM: |
| 785 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 785 | rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); |
| 786 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | 786 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); |
| 787 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 787 | rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); |
| 788 | break; | 788 | break; |
| 789 | case QID_RX: | 789 | case QID_RX: |
| 790 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 790 | rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); |
| 791 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); | 791 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); |
| 792 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 792 | rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); |
| 793 | break; | 793 | break; |
| 794 | case QID_BEACON: | 794 | case QID_BEACON: |
| 795 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 795 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 796 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | 796 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); |
| 797 | rt2x00_set_field32(®, CSR14_TBCN, 0); | 797 | rt2x00_set_field32(®, CSR14_TBCN, 0); |
| 798 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 798 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 799 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 799 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 800 | 800 | ||
| 801 | /* | 801 | /* |
| 802 | * Wait for possibly running tbtt tasklets. | 802 | * Wait for possibly running tbtt tasklets. |
| @@ -813,7 +813,7 @@ static void rt2500pci_stop_queue(struct data_queue *queue) | |||
| 813 | */ | 813 | */ |
| 814 | static bool rt2500pci_get_entry_state(struct queue_entry *entry) | 814 | static bool rt2500pci_get_entry_state(struct queue_entry *entry) |
| 815 | { | 815 | { |
| 816 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 816 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 817 | u32 word; | 817 | u32 word; |
| 818 | 818 | ||
| 819 | if (entry->queue->qid == QID_RX) { | 819 | if (entry->queue->qid == QID_RX) { |
| @@ -830,7 +830,7 @@ static bool rt2500pci_get_entry_state(struct queue_entry *entry) | |||
| 830 | 830 | ||
| 831 | static void rt2500pci_clear_entry(struct queue_entry *entry) | 831 | static void rt2500pci_clear_entry(struct queue_entry *entry) |
| 832 | { | 832 | { |
| 833 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 833 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 834 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 834 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 835 | u32 word; | 835 | u32 word; |
| 836 | 836 | ||
| @@ -852,53 +852,53 @@ static void rt2500pci_clear_entry(struct queue_entry *entry) | |||
| 852 | 852 | ||
| 853 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) | 853 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
| 854 | { | 854 | { |
| 855 | struct queue_entry_priv_pci *entry_priv; | 855 | struct queue_entry_priv_mmio *entry_priv; |
| 856 | u32 reg; | 856 | u32 reg; |
| 857 | 857 | ||
| 858 | /* | 858 | /* |
| 859 | * Initialize registers. | 859 | * Initialize registers. |
| 860 | */ | 860 | */ |
| 861 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 861 | rt2x00mmio_register_read(rt2x00dev, TXCSR2, ®); |
| 862 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); | 862 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
| 863 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); | 863 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
| 864 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); | 864 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); |
| 865 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); | 865 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
| 866 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 866 | rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg); |
| 867 | 867 | ||
| 868 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; | 868 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
| 869 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 869 | rt2x00mmio_register_read(rt2x00dev, TXCSR3, ®); |
| 870 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 870 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
| 871 | entry_priv->desc_dma); | 871 | entry_priv->desc_dma); |
| 872 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 872 | rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg); |
| 873 | 873 | ||
| 874 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; | 874 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
| 875 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 875 | rt2x00mmio_register_read(rt2x00dev, TXCSR5, ®); |
| 876 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 876 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
| 877 | entry_priv->desc_dma); | 877 | entry_priv->desc_dma); |
| 878 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 878 | rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg); |
| 879 | 879 | ||
| 880 | entry_priv = rt2x00dev->atim->entries[0].priv_data; | 880 | entry_priv = rt2x00dev->atim->entries[0].priv_data; |
| 881 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 881 | rt2x00mmio_register_read(rt2x00dev, TXCSR4, ®); |
| 882 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 882 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
| 883 | entry_priv->desc_dma); | 883 | entry_priv->desc_dma); |
| 884 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 884 | rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg); |
| 885 | 885 | ||
| 886 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; | 886 | entry_priv = rt2x00dev->bcn->entries[0].priv_data; |
| 887 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 887 | rt2x00mmio_register_read(rt2x00dev, TXCSR6, ®); |
| 888 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 888 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
| 889 | entry_priv->desc_dma); | 889 | entry_priv->desc_dma); |
| 890 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 890 | rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg); |
| 891 | 891 | ||
| 892 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 892 | rt2x00mmio_register_read(rt2x00dev, RXCSR1, ®); |
| 893 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 893 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
| 894 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); | 894 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
| 895 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 895 | rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg); |
| 896 | 896 | ||
| 897 | entry_priv = rt2x00dev->rx->entries[0].priv_data; | 897 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
| 898 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 898 | rt2x00mmio_register_read(rt2x00dev, RXCSR2, ®); |
| 899 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 899 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, |
| 900 | entry_priv->desc_dma); | 900 | entry_priv->desc_dma); |
| 901 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 901 | rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg); |
| 902 | 902 | ||
| 903 | return 0; | 903 | return 0; |
| 904 | } | 904 | } |
| @@ -907,30 +907,30 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 907 | { | 907 | { |
| 908 | u32 reg; | 908 | u32 reg; |
| 909 | 909 | ||
| 910 | rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); | 910 | rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002); |
| 911 | rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); | 911 | rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002); |
| 912 | rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00020002); | 912 | rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00020002); |
| 913 | rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); | 913 | rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002); |
| 914 | 914 | ||
| 915 | rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); | 915 | rt2x00mmio_register_read(rt2x00dev, TIMECSR, ®); |
| 916 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); | 916 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); |
| 917 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); | 917 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); |
| 918 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); | 918 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); |
| 919 | rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); | 919 | rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg); |
| 920 | 920 | ||
| 921 | rt2x00pci_register_read(rt2x00dev, CSR9, ®); | 921 | rt2x00mmio_register_read(rt2x00dev, CSR9, ®); |
| 922 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, | 922 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, |
| 923 | rt2x00dev->rx->data_size / 128); | 923 | rt2x00dev->rx->data_size / 128); |
| 924 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 924 | rt2x00mmio_register_write(rt2x00dev, CSR9, reg); |
| 925 | 925 | ||
| 926 | /* | 926 | /* |
| 927 | * Always use CWmin and CWmax set in descriptor. | 927 | * Always use CWmin and CWmax set in descriptor. |
| 928 | */ | 928 | */ |
| 929 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 929 | rt2x00mmio_register_read(rt2x00dev, CSR11, ®); |
| 930 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 930 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
| 931 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 931 | rt2x00mmio_register_write(rt2x00dev, CSR11, reg); |
| 932 | 932 | ||
| 933 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 933 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 934 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | 934 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); |
| 935 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | 935 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); |
| 936 | rt2x00_set_field32(®, CSR14_TBCN, 0); | 936 | rt2x00_set_field32(®, CSR14_TBCN, 0); |
| @@ -939,11 +939,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 939 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 939 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 940 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); | 940 | rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); |
| 941 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); | 941 | rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); |
| 942 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 942 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 943 | 943 | ||
| 944 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 944 | rt2x00mmio_register_write(rt2x00dev, CNT3, 0); |
| 945 | 945 | ||
| 946 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 946 | rt2x00mmio_register_read(rt2x00dev, TXCSR8, ®); |
| 947 | rt2x00_set_field32(®, TXCSR8_BBP_ID0, 10); | 947 | rt2x00_set_field32(®, TXCSR8_BBP_ID0, 10); |
| 948 | rt2x00_set_field32(®, TXCSR8_BBP_ID0_VALID, 1); | 948 | rt2x00_set_field32(®, TXCSR8_BBP_ID0_VALID, 1); |
| 949 | rt2x00_set_field32(®, TXCSR8_BBP_ID1, 11); | 949 | rt2x00_set_field32(®, TXCSR8_BBP_ID1, 11); |
| @@ -952,30 +952,30 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 952 | rt2x00_set_field32(®, TXCSR8_BBP_ID2_VALID, 1); | 952 | rt2x00_set_field32(®, TXCSR8_BBP_ID2_VALID, 1); |
| 953 | rt2x00_set_field32(®, TXCSR8_BBP_ID3, 12); | 953 | rt2x00_set_field32(®, TXCSR8_BBP_ID3, 12); |
| 954 | rt2x00_set_field32(®, TXCSR8_BBP_ID3_VALID, 1); | 954 | rt2x00_set_field32(®, TXCSR8_BBP_ID3_VALID, 1); |
| 955 | rt2x00pci_register_write(rt2x00dev, TXCSR8, reg); | 955 | rt2x00mmio_register_write(rt2x00dev, TXCSR8, reg); |
| 956 | 956 | ||
| 957 | rt2x00pci_register_read(rt2x00dev, ARTCSR0, ®); | 957 | rt2x00mmio_register_read(rt2x00dev, ARTCSR0, ®); |
| 958 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_1MBS, 112); | 958 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_1MBS, 112); |
| 959 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_2MBS, 56); | 959 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_2MBS, 56); |
| 960 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_5_5MBS, 20); | 960 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_5_5MBS, 20); |
| 961 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_11MBS, 10); | 961 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_11MBS, 10); |
| 962 | rt2x00pci_register_write(rt2x00dev, ARTCSR0, reg); | 962 | rt2x00mmio_register_write(rt2x00dev, ARTCSR0, reg); |
| 963 | 963 | ||
| 964 | rt2x00pci_register_read(rt2x00dev, ARTCSR1, ®); | 964 | rt2x00mmio_register_read(rt2x00dev, ARTCSR1, ®); |
| 965 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_6MBS, 45); | 965 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_6MBS, 45); |
| 966 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_9MBS, 37); | 966 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_9MBS, 37); |
| 967 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_12MBS, 33); | 967 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_12MBS, 33); |
| 968 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_18MBS, 29); | 968 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_18MBS, 29); |
| 969 | rt2x00pci_register_write(rt2x00dev, ARTCSR1, reg); | 969 | rt2x00mmio_register_write(rt2x00dev, ARTCSR1, reg); |
| 970 | 970 | ||
| 971 | rt2x00pci_register_read(rt2x00dev, ARTCSR2, ®); | 971 | rt2x00mmio_register_read(rt2x00dev, ARTCSR2, ®); |
| 972 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_24MBS, 29); | 972 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_24MBS, 29); |
| 973 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_36MBS, 25); | 973 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_36MBS, 25); |
| 974 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_48MBS, 25); | 974 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_48MBS, 25); |
| 975 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_54MBS, 25); | 975 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_54MBS, 25); |
| 976 | rt2x00pci_register_write(rt2x00dev, ARTCSR2, reg); | 976 | rt2x00mmio_register_write(rt2x00dev, ARTCSR2, reg); |
| 977 | 977 | ||
| 978 | rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); | 978 | rt2x00mmio_register_read(rt2x00dev, RXCSR3, ®); |
| 979 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 47); /* CCK Signal */ | 979 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 47); /* CCK Signal */ |
| 980 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); | 980 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); |
| 981 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 51); /* Rssi */ | 981 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 51); /* Rssi */ |
| @@ -984,9 +984,9 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 984 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); | 984 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); |
| 985 | rt2x00_set_field32(®, RXCSR3_BBP_ID3, 51); /* RSSI */ | 985 | rt2x00_set_field32(®, RXCSR3_BBP_ID3, 51); /* RSSI */ |
| 986 | rt2x00_set_field32(®, RXCSR3_BBP_ID3_VALID, 1); | 986 | rt2x00_set_field32(®, RXCSR3_BBP_ID3_VALID, 1); |
| 987 | rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); | 987 | rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg); |
| 988 | 988 | ||
| 989 | rt2x00pci_register_read(rt2x00dev, PCICSR, ®); | 989 | rt2x00mmio_register_read(rt2x00dev, PCICSR, ®); |
| 990 | rt2x00_set_field32(®, PCICSR_BIG_ENDIAN, 0); | 990 | rt2x00_set_field32(®, PCICSR_BIG_ENDIAN, 0); |
| 991 | rt2x00_set_field32(®, PCICSR_RX_TRESHOLD, 0); | 991 | rt2x00_set_field32(®, PCICSR_RX_TRESHOLD, 0); |
| 992 | rt2x00_set_field32(®, PCICSR_TX_TRESHOLD, 3); | 992 | rt2x00_set_field32(®, PCICSR_TX_TRESHOLD, 3); |
| @@ -994,54 +994,54 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 994 | rt2x00_set_field32(®, PCICSR_ENABLE_CLK, 1); | 994 | rt2x00_set_field32(®, PCICSR_ENABLE_CLK, 1); |
| 995 | rt2x00_set_field32(®, PCICSR_READ_MULTIPLE, 1); | 995 | rt2x00_set_field32(®, PCICSR_READ_MULTIPLE, 1); |
| 996 | rt2x00_set_field32(®, PCICSR_WRITE_INVALID, 1); | 996 | rt2x00_set_field32(®, PCICSR_WRITE_INVALID, 1); |
| 997 | rt2x00pci_register_write(rt2x00dev, PCICSR, reg); | 997 | rt2x00mmio_register_write(rt2x00dev, PCICSR, reg); |
| 998 | 998 | ||
| 999 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); | 999 | rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); |
| 1000 | 1000 | ||
| 1001 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, 0x0000ff00); | 1001 | rt2x00mmio_register_write(rt2x00dev, GPIOCSR, 0x0000ff00); |
| 1002 | rt2x00pci_register_write(rt2x00dev, TESTCSR, 0x000000f0); | 1002 | rt2x00mmio_register_write(rt2x00dev, TESTCSR, 0x000000f0); |
| 1003 | 1003 | ||
| 1004 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | 1004 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) |
| 1005 | return -EBUSY; | 1005 | return -EBUSY; |
| 1006 | 1006 | ||
| 1007 | rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00213223); | 1007 | rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00213223); |
| 1008 | rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); | 1008 | rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518); |
| 1009 | 1009 | ||
| 1010 | rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); | 1010 | rt2x00mmio_register_read(rt2x00dev, MACCSR2, ®); |
| 1011 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); | 1011 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); |
| 1012 | rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); | 1012 | rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg); |
| 1013 | 1013 | ||
| 1014 | rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); | 1014 | rt2x00mmio_register_read(rt2x00dev, RALINKCSR, ®); |
| 1015 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); | 1015 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); |
| 1016 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 26); | 1016 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 26); |
| 1017 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID0, 1); | 1017 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID0, 1); |
| 1018 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); | 1018 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); |
| 1019 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 26); | 1019 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 26); |
| 1020 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID1, 1); | 1020 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID1, 1); |
| 1021 | rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); | 1021 | rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg); |
| 1022 | 1022 | ||
| 1023 | rt2x00pci_register_write(rt2x00dev, BBPCSR1, 0x82188200); | 1023 | rt2x00mmio_register_write(rt2x00dev, BBPCSR1, 0x82188200); |
| 1024 | 1024 | ||
| 1025 | rt2x00pci_register_write(rt2x00dev, TXACKCSR0, 0x00000020); | 1025 | rt2x00mmio_register_write(rt2x00dev, TXACKCSR0, 0x00000020); |
| 1026 | 1026 | ||
| 1027 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | 1027 | rt2x00mmio_register_read(rt2x00dev, CSR1, ®); |
| 1028 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); | 1028 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); |
| 1029 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); | 1029 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); |
| 1030 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); | 1030 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); |
| 1031 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | 1031 | rt2x00mmio_register_write(rt2x00dev, CSR1, reg); |
| 1032 | 1032 | ||
| 1033 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | 1033 | rt2x00mmio_register_read(rt2x00dev, CSR1, ®); |
| 1034 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); | 1034 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); |
| 1035 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); | 1035 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); |
| 1036 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | 1036 | rt2x00mmio_register_write(rt2x00dev, CSR1, reg); |
| 1037 | 1037 | ||
| 1038 | /* | 1038 | /* |
| 1039 | * We must clear the FCS and FIFO error count. | 1039 | * We must clear the FCS and FIFO error count. |
| 1040 | * These registers are cleared on read, | 1040 | * These registers are cleared on read, |
| 1041 | * so we may pass a useless variable to store the value. | 1041 | * so we may pass a useless variable to store the value. |
| 1042 | */ | 1042 | */ |
| 1043 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | 1043 | rt2x00mmio_register_read(rt2x00dev, CNT0, ®); |
| 1044 | rt2x00pci_register_read(rt2x00dev, CNT4, ®); | 1044 | rt2x00mmio_register_read(rt2x00dev, CNT4, ®); |
| 1045 | 1045 | ||
| 1046 | return 0; | 1046 | return 0; |
| 1047 | } | 1047 | } |
| @@ -1058,7 +1058,7 @@ static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 1058 | udelay(REGISTER_BUSY_DELAY); | 1058 | udelay(REGISTER_BUSY_DELAY); |
| 1059 | } | 1059 | } |
| 1060 | 1060 | ||
| 1061 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1061 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 1062 | return -EACCES; | 1062 | return -EACCES; |
| 1063 | } | 1063 | } |
| 1064 | 1064 | ||
| @@ -1131,8 +1131,8 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 1131 | * should clear the register to assure a clean state. | 1131 | * should clear the register to assure a clean state. |
| 1132 | */ | 1132 | */ |
| 1133 | if (state == STATE_RADIO_IRQ_ON) { | 1133 | if (state == STATE_RADIO_IRQ_ON) { |
| 1134 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | 1134 | rt2x00mmio_register_read(rt2x00dev, CSR7, ®); |
| 1135 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | 1135 | rt2x00mmio_register_write(rt2x00dev, CSR7, reg); |
| 1136 | } | 1136 | } |
| 1137 | 1137 | ||
| 1138 | /* | 1138 | /* |
| @@ -1141,13 +1141,13 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 1141 | */ | 1141 | */ |
| 1142 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1142 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); |
| 1143 | 1143 | ||
| 1144 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1144 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1145 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); | 1145 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); |
| 1146 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); | 1146 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); |
| 1147 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); | 1147 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); |
| 1148 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); | 1148 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); |
| 1149 | rt2x00_set_field32(®, CSR8_RXDONE, mask); | 1149 | rt2x00_set_field32(®, CSR8_RXDONE, mask); |
| 1150 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1150 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1151 | 1151 | ||
| 1152 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1152 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); |
| 1153 | 1153 | ||
| @@ -1179,7 +1179,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 1179 | /* | 1179 | /* |
| 1180 | * Disable power | 1180 | * Disable power |
| 1181 | */ | 1181 | */ |
| 1182 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1182 | rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0); |
| 1183 | } | 1183 | } |
| 1184 | 1184 | ||
| 1185 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | 1185 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, |
| @@ -1193,12 +1193,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
| 1193 | 1193 | ||
| 1194 | put_to_sleep = (state != STATE_AWAKE); | 1194 | put_to_sleep = (state != STATE_AWAKE); |
| 1195 | 1195 | ||
| 1196 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | 1196 | rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®); |
| 1197 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); | 1197 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); |
| 1198 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); | 1198 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); |
| 1199 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); | 1199 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); |
| 1200 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); | 1200 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); |
| 1201 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | 1201 | rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); |
| 1202 | 1202 | ||
| 1203 | /* | 1203 | /* |
| 1204 | * Device is not guaranteed to be in the requested state yet. | 1204 | * Device is not guaranteed to be in the requested state yet. |
| @@ -1206,12 +1206,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
| 1206 | * device has entered the correct state. | 1206 | * device has entered the correct state. |
| 1207 | */ | 1207 | */ |
| 1208 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1208 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
| 1209 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); | 1209 | rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®2); |
| 1210 | bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); | 1210 | bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); |
| 1211 | rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); | 1211 | rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); |
| 1212 | if (bbp_state == state && rf_state == state) | 1212 | if (bbp_state == state && rf_state == state) |
| 1213 | return 0; | 1213 | return 0; |
| 1214 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | 1214 | rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); |
| 1215 | msleep(10); | 1215 | msleep(10); |
| 1216 | } | 1216 | } |
| 1217 | 1217 | ||
| @@ -1246,8 +1246,8 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 1246 | } | 1246 | } |
| 1247 | 1247 | ||
| 1248 | if (unlikely(retval)) | 1248 | if (unlikely(retval)) |
| 1249 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 1249 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 1250 | state, retval); | 1250 | state, retval); |
| 1251 | 1251 | ||
| 1252 | return retval; | 1252 | return retval; |
| 1253 | } | 1253 | } |
| @@ -1259,7 +1259,7 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, | |||
| 1259 | struct txentry_desc *txdesc) | 1259 | struct txentry_desc *txdesc) |
| 1260 | { | 1260 | { |
| 1261 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1261 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 1262 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1262 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1263 | __le32 *txd = entry_priv->desc; | 1263 | __le32 *txd = entry_priv->desc; |
| 1264 | u32 word; | 1264 | u32 word; |
| 1265 | 1265 | ||
| @@ -1335,12 +1335,12 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
| 1335 | * Disable beaconing while we are reloading the beacon data, | 1335 | * Disable beaconing while we are reloading the beacon data, |
| 1336 | * otherwise we might be sending out invalid data. | 1336 | * otherwise we might be sending out invalid data. |
| 1337 | */ | 1337 | */ |
| 1338 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1338 | rt2x00mmio_register_read(rt2x00dev, CSR14, ®); |
| 1339 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 1339 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
| 1340 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1340 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 1341 | 1341 | ||
| 1342 | if (rt2x00queue_map_txskb(entry)) { | 1342 | if (rt2x00queue_map_txskb(entry)) { |
| 1343 | ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); | 1343 | rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n"); |
| 1344 | goto out; | 1344 | goto out; |
| 1345 | } | 1345 | } |
| 1346 | 1346 | ||
| @@ -1358,7 +1358,7 @@ out: | |||
| 1358 | * Enable beaconing again. | 1358 | * Enable beaconing again. |
| 1359 | */ | 1359 | */ |
| 1360 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1360 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
| 1361 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1361 | rt2x00mmio_register_write(rt2x00dev, CSR14, reg); |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | /* | 1364 | /* |
| @@ -1367,7 +1367,7 @@ out: | |||
| 1367 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, | 1367 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
| 1368 | struct rxdone_entry_desc *rxdesc) | 1368 | struct rxdone_entry_desc *rxdesc) |
| 1369 | { | 1369 | { |
| 1370 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1370 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1371 | u32 word0; | 1371 | u32 word0; |
| 1372 | u32 word2; | 1372 | u32 word2; |
| 1373 | 1373 | ||
| @@ -1405,7 +1405,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
| 1405 | const enum data_queue_qid queue_idx) | 1405 | const enum data_queue_qid queue_idx) |
| 1406 | { | 1406 | { |
| 1407 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); | 1407 | struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); |
| 1408 | struct queue_entry_priv_pci *entry_priv; | 1408 | struct queue_entry_priv_mmio *entry_priv; |
| 1409 | struct queue_entry *entry; | 1409 | struct queue_entry *entry; |
| 1410 | struct txdone_entry_desc txdesc; | 1410 | struct txdone_entry_desc txdesc; |
| 1411 | u32 word; | 1411 | u32 word; |
| @@ -1451,9 +1451,9 @@ static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | |||
| 1451 | */ | 1451 | */ |
| 1452 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 1452 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 1453 | 1453 | ||
| 1454 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1454 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1455 | rt2x00_set_field32(®, irq_field, 0); | 1455 | rt2x00_set_field32(®, irq_field, 0); |
| 1456 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1456 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1457 | 1457 | ||
| 1458 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 1458 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 1459 | } | 1459 | } |
| @@ -1476,11 +1476,11 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) | |||
| 1476 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { | 1476 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { |
| 1477 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 1477 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 1478 | 1478 | ||
| 1479 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1479 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1480 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); | 1480 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); |
| 1481 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); | 1481 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); |
| 1482 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); | 1482 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); |
| 1483 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1483 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1484 | 1484 | ||
| 1485 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 1485 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 1486 | } | 1486 | } |
| @@ -1497,7 +1497,7 @@ static void rt2500pci_tbtt_tasklet(unsigned long data) | |||
| 1497 | static void rt2500pci_rxdone_tasklet(unsigned long data) | 1497 | static void rt2500pci_rxdone_tasklet(unsigned long data) |
| 1498 | { | 1498 | { |
| 1499 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 1499 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
| 1500 | if (rt2x00pci_rxdone(rt2x00dev)) | 1500 | if (rt2x00mmio_rxdone(rt2x00dev)) |
| 1501 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); | 1501 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); |
| 1502 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 1502 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 1503 | rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); | 1503 | rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); |
| @@ -1512,8 +1512,8 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
| 1512 | * Get the interrupt sources & saved to local variable. | 1512 | * Get the interrupt sources & saved to local variable. |
| 1513 | * Write register value back to clear pending interrupts. | 1513 | * Write register value back to clear pending interrupts. |
| 1514 | */ | 1514 | */ |
| 1515 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | 1515 | rt2x00mmio_register_read(rt2x00dev, CSR7, ®); |
| 1516 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | 1516 | rt2x00mmio_register_write(rt2x00dev, CSR7, reg); |
| 1517 | 1517 | ||
| 1518 | if (!reg) | 1518 | if (!reg) |
| 1519 | return IRQ_NONE; | 1519 | return IRQ_NONE; |
| @@ -1550,9 +1550,9 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
| 1550 | */ | 1550 | */ |
| 1551 | spin_lock(&rt2x00dev->irqmask_lock); | 1551 | spin_lock(&rt2x00dev->irqmask_lock); |
| 1552 | 1552 | ||
| 1553 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | 1553 | rt2x00mmio_register_read(rt2x00dev, CSR8, ®); |
| 1554 | reg |= mask; | 1554 | reg |= mask; |
| 1555 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | 1555 | rt2x00mmio_register_write(rt2x00dev, CSR8, reg); |
| 1556 | 1556 | ||
| 1557 | spin_unlock(&rt2x00dev->irqmask_lock); | 1557 | spin_unlock(&rt2x00dev->irqmask_lock); |
| 1558 | 1558 | ||
| @@ -1569,7 +1569,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1569 | u16 word; | 1569 | u16 word; |
| 1570 | u8 *mac; | 1570 | u8 *mac; |
| 1571 | 1571 | ||
| 1572 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | 1572 | rt2x00mmio_register_read(rt2x00dev, CSR21, ®); |
| 1573 | 1573 | ||
| 1574 | eeprom.data = rt2x00dev; | 1574 | eeprom.data = rt2x00dev; |
| 1575 | eeprom.register_read = rt2500pci_eepromregister_read; | 1575 | eeprom.register_read = rt2500pci_eepromregister_read; |
| @@ -1590,7 +1590,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1590 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 1590 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 1591 | if (!is_valid_ether_addr(mac)) { | 1591 | if (!is_valid_ether_addr(mac)) { |
| 1592 | eth_random_addr(mac); | 1592 | eth_random_addr(mac); |
| 1593 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 1593 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 1594 | } | 1594 | } |
| 1595 | 1595 | ||
| 1596 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 1596 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); |
| @@ -1606,7 +1606,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1606 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | 1606 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); |
| 1607 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); | 1607 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); |
| 1608 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 1608 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); |
| 1609 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 1609 | rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); |
| 1610 | } | 1610 | } |
| 1611 | 1611 | ||
| 1612 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | 1612 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); |
| @@ -1615,7 +1615,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1615 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); | 1615 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); |
| 1616 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); | 1616 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); |
| 1617 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | 1617 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); |
| 1618 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 1618 | rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); |
| 1619 | } | 1619 | } |
| 1620 | 1620 | ||
| 1621 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); | 1621 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); |
| @@ -1623,7 +1623,8 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1623 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, | 1623 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, |
| 1624 | DEFAULT_RSSI_OFFSET); | 1624 | DEFAULT_RSSI_OFFSET); |
| 1625 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); | 1625 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); |
| 1626 | EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); | 1626 | rt2x00_eeprom_dbg(rt2x00dev, "Calibrate offset: 0x%04x\n", |
| 1627 | word); | ||
| 1627 | } | 1628 | } |
| 1628 | 1629 | ||
| 1629 | return 0; | 1630 | return 0; |
| @@ -1644,7 +1645,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1644 | * Identify RF chipset. | 1645 | * Identify RF chipset. |
| 1645 | */ | 1646 | */ |
| 1646 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1647 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
| 1647 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | 1648 | rt2x00mmio_register_read(rt2x00dev, CSR0, ®); |
| 1648 | rt2x00_set_chip(rt2x00dev, RT2560, value, | 1649 | rt2x00_set_chip(rt2x00dev, RT2560, value, |
| 1649 | rt2x00_get_field32(reg, CSR0_REVISION)); | 1650 | rt2x00_get_field32(reg, CSR0_REVISION)); |
| 1650 | 1651 | ||
| @@ -1654,7 +1655,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1654 | !rt2x00_rf(rt2x00dev, RF2525) && | 1655 | !rt2x00_rf(rt2x00dev, RF2525) && |
| 1655 | !rt2x00_rf(rt2x00dev, RF2525E) && | 1656 | !rt2x00_rf(rt2x00dev, RF2525E) && |
| 1656 | !rt2x00_rf(rt2x00dev, RF5222)) { | 1657 | !rt2x00_rf(rt2x00dev, RF5222)) { |
| 1657 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 1658 | rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); |
| 1658 | return -ENODEV; | 1659 | return -ENODEV; |
| 1659 | } | 1660 | } |
| 1660 | 1661 | ||
| @@ -1950,9 +1951,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 1950 | * Enable rfkill polling by setting GPIO direction of the | 1951 | * Enable rfkill polling by setting GPIO direction of the |
| 1951 | * rfkill switch GPIO pin correctly. | 1952 | * rfkill switch GPIO pin correctly. |
| 1952 | */ | 1953 | */ |
| 1953 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | 1954 | rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); |
| 1954 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | 1955 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); |
| 1955 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | 1956 | rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg); |
| 1956 | 1957 | ||
| 1957 | /* | 1958 | /* |
| 1958 | * Initialize hw specifications. | 1959 | * Initialize hw specifications. |
| @@ -1986,9 +1987,9 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw, | |||
| 1986 | u64 tsf; | 1987 | u64 tsf; |
| 1987 | u32 reg; | 1988 | u32 reg; |
| 1988 | 1989 | ||
| 1989 | rt2x00pci_register_read(rt2x00dev, CSR17, ®); | 1990 | rt2x00mmio_register_read(rt2x00dev, CSR17, ®); |
| 1990 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; | 1991 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; |
| 1991 | rt2x00pci_register_read(rt2x00dev, CSR16, ®); | 1992 | rt2x00mmio_register_read(rt2x00dev, CSR16, ®); |
| 1992 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); | 1993 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); |
| 1993 | 1994 | ||
| 1994 | return tsf; | 1995 | return tsf; |
| @@ -1999,7 +2000,7 @@ static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | |||
| 1999 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2000 | struct rt2x00_dev *rt2x00dev = hw->priv; |
| 2000 | u32 reg; | 2001 | u32 reg; |
| 2001 | 2002 | ||
| 2002 | rt2x00pci_register_read(rt2x00dev, CSR15, ®); | 2003 | rt2x00mmio_register_read(rt2x00dev, CSR15, ®); |
| 2003 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); | 2004 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); |
| 2004 | } | 2005 | } |
| 2005 | 2006 | ||
| @@ -2032,8 +2033,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
| 2032 | .tbtt_tasklet = rt2500pci_tbtt_tasklet, | 2033 | .tbtt_tasklet = rt2500pci_tbtt_tasklet, |
| 2033 | .rxdone_tasklet = rt2500pci_rxdone_tasklet, | 2034 | .rxdone_tasklet = rt2500pci_rxdone_tasklet, |
| 2034 | .probe_hw = rt2500pci_probe_hw, | 2035 | .probe_hw = rt2500pci_probe_hw, |
| 2035 | .initialize = rt2x00pci_initialize, | 2036 | .initialize = rt2x00mmio_initialize, |
| 2036 | .uninitialize = rt2x00pci_uninitialize, | 2037 | .uninitialize = rt2x00mmio_uninitialize, |
| 2037 | .get_entry_state = rt2500pci_get_entry_state, | 2038 | .get_entry_state = rt2500pci_get_entry_state, |
| 2038 | .clear_entry = rt2500pci_clear_entry, | 2039 | .clear_entry = rt2500pci_clear_entry, |
| 2039 | .set_device_state = rt2500pci_set_device_state, | 2040 | .set_device_state = rt2500pci_set_device_state, |
| @@ -2044,7 +2045,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
| 2044 | .start_queue = rt2500pci_start_queue, | 2045 | .start_queue = rt2500pci_start_queue, |
| 2045 | .kick_queue = rt2500pci_kick_queue, | 2046 | .kick_queue = rt2500pci_kick_queue, |
| 2046 | .stop_queue = rt2500pci_stop_queue, | 2047 | .stop_queue = rt2500pci_stop_queue, |
| 2047 | .flush_queue = rt2x00pci_flush_queue, | 2048 | .flush_queue = rt2x00mmio_flush_queue, |
| 2048 | .write_tx_desc = rt2500pci_write_tx_desc, | 2049 | .write_tx_desc = rt2500pci_write_tx_desc, |
| 2049 | .write_beacon = rt2500pci_write_beacon, | 2050 | .write_beacon = rt2500pci_write_beacon, |
| 2050 | .fill_rxdone = rt2500pci_fill_rxdone, | 2051 | .fill_rxdone = rt2500pci_fill_rxdone, |
| @@ -2059,28 +2060,28 @@ static const struct data_queue_desc rt2500pci_queue_rx = { | |||
| 2059 | .entry_num = 32, | 2060 | .entry_num = 32, |
| 2060 | .data_size = DATA_FRAME_SIZE, | 2061 | .data_size = DATA_FRAME_SIZE, |
| 2061 | .desc_size = RXD_DESC_SIZE, | 2062 | .desc_size = RXD_DESC_SIZE, |
| 2062 | .priv_size = sizeof(struct queue_entry_priv_pci), | 2063 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 2063 | }; | 2064 | }; |
| 2064 | 2065 | ||
| 2065 | static const struct data_queue_desc rt2500pci_queue_tx = { | 2066 | static const struct data_queue_desc rt2500pci_queue_tx = { |
| 2066 | .entry_num = 32, | 2067 | .entry_num = 32, |
| 2067 | .data_size = DATA_FRAME_SIZE, | 2068 | .data_size = DATA_FRAME_SIZE, |
| 2068 | .desc_size = TXD_DESC_SIZE, | 2069 | .desc_size = TXD_DESC_SIZE, |
| 2069 | .priv_size = sizeof(struct queue_entry_priv_pci), | 2070 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 2070 | }; | 2071 | }; |
| 2071 | 2072 | ||
| 2072 | static const struct data_queue_desc rt2500pci_queue_bcn = { | 2073 | static const struct data_queue_desc rt2500pci_queue_bcn = { |
| 2073 | .entry_num = 1, | 2074 | .entry_num = 1, |
| 2074 | .data_size = MGMT_FRAME_SIZE, | 2075 | .data_size = MGMT_FRAME_SIZE, |
| 2075 | .desc_size = TXD_DESC_SIZE, | 2076 | .desc_size = TXD_DESC_SIZE, |
| 2076 | .priv_size = sizeof(struct queue_entry_priv_pci), | 2077 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 2077 | }; | 2078 | }; |
| 2078 | 2079 | ||
| 2079 | static const struct data_queue_desc rt2500pci_queue_atim = { | 2080 | static const struct data_queue_desc rt2500pci_queue_atim = { |
| 2080 | .entry_num = 8, | 2081 | .entry_num = 8, |
| 2081 | .data_size = DATA_FRAME_SIZE, | 2082 | .data_size = DATA_FRAME_SIZE, |
| 2082 | .desc_size = TXD_DESC_SIZE, | 2083 | .desc_size = TXD_DESC_SIZE, |
| 2083 | .priv_size = sizeof(struct queue_entry_priv_pci), | 2084 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 2084 | }; | 2085 | }; |
| 2085 | 2086 | ||
| 2086 | static const struct rt2x00_ops rt2500pci_ops = { | 2087 | static const struct rt2x00_ops rt2500pci_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6b2e1e431dd2..a7f7b365eff4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -134,8 +134,8 @@ static int rt2500usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
| 134 | udelay(REGISTER_BUSY_DELAY); | 134 | udelay(REGISTER_BUSY_DELAY); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | ERROR(rt2x00dev, "Indirect register access failed: " | 137 | rt2x00_err(rt2x00dev, "Indirect register access failed: offset=0x%.08x, value=0x%.08x\n", |
| 138 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | 138 | offset, *reg); |
| 139 | *reg = ~0; | 139 | *reg = ~0; |
| 140 | 140 | ||
| 141 | return 0; | 141 | return 0; |
| @@ -916,7 +916,7 @@ static int rt2500usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 916 | udelay(REGISTER_BUSY_DELAY); | 916 | udelay(REGISTER_BUSY_DELAY); |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 919 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 920 | return -EACCES; | 920 | return -EACCES; |
| 921 | } | 921 | } |
| 922 | 922 | ||
| @@ -1069,8 +1069,8 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 1069 | } | 1069 | } |
| 1070 | 1070 | ||
| 1071 | if (unlikely(retval)) | 1071 | if (unlikely(retval)) |
| 1072 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 1072 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 1073 | state, retval); | 1073 | state, retval); |
| 1074 | 1074 | ||
| 1075 | return retval; | 1075 | return retval; |
| 1076 | } | 1076 | } |
| @@ -1353,7 +1353,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1353 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 1353 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 1354 | if (!is_valid_ether_addr(mac)) { | 1354 | if (!is_valid_ether_addr(mac)) { |
| 1355 | eth_random_addr(mac); | 1355 | eth_random_addr(mac); |
| 1356 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 1356 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 1357 | } | 1357 | } |
| 1358 | 1358 | ||
| 1359 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 1359 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); |
| @@ -1369,7 +1369,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1369 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | 1369 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); |
| 1370 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); | 1370 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); |
| 1371 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 1371 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); |
| 1372 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 1372 | rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); |
| 1373 | } | 1373 | } |
| 1374 | 1374 | ||
| 1375 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | 1375 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); |
| @@ -1378,7 +1378,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1378 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); | 1378 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); |
| 1379 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); | 1379 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); |
| 1380 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | 1380 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); |
| 1381 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 1381 | rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); | 1384 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); |
| @@ -1386,14 +1386,15 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1386 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, | 1386 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, |
| 1387 | DEFAULT_RSSI_OFFSET); | 1387 | DEFAULT_RSSI_OFFSET); |
| 1388 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); | 1388 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); |
| 1389 | EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); | 1389 | rt2x00_eeprom_dbg(rt2x00dev, "Calibrate offset: 0x%04x\n", |
| 1390 | word); | ||
| 1390 | } | 1391 | } |
| 1391 | 1392 | ||
| 1392 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &word); | 1393 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &word); |
| 1393 | if (word == 0xffff) { | 1394 | if (word == 0xffff) { |
| 1394 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_THRESHOLD, 45); | 1395 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_THRESHOLD, 45); |
| 1395 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE, word); | 1396 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE, word); |
| 1396 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1397 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune: 0x%04x\n", word); |
| 1397 | } | 1398 | } |
| 1398 | 1399 | ||
| 1399 | /* | 1400 | /* |
| @@ -1408,7 +1409,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1408 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1409 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
| 1409 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | 1410 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); |
| 1410 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1411 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
| 1411 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1412 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
| 1412 | } else { | 1413 | } else { |
| 1413 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | 1414 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); |
| 1414 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1415 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
| @@ -1419,7 +1420,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1419 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_LOW, 0x48); | 1420 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_LOW, 0x48); |
| 1420 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1421 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
| 1421 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1422 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
| 1422 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1423 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
| 1423 | } | 1424 | } |
| 1424 | 1425 | ||
| 1425 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1426 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
| @@ -1427,7 +1428,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1427 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_LOW, 0x40); | 1428 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_LOW, 0x40); |
| 1428 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_HIGH, 0x80); | 1429 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_HIGH, 0x80); |
| 1429 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R24, word); | 1430 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R24, word); |
| 1430 | EEPROM(rt2x00dev, "BBPtune r24: 0x%04x\n", word); | 1431 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r24: 0x%04x\n", word); |
| 1431 | } | 1432 | } |
| 1432 | 1433 | ||
| 1433 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &word); | 1434 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &word); |
| @@ -1435,7 +1436,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1435 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_LOW, 0x40); | 1436 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_LOW, 0x40); |
| 1436 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_HIGH, 0x50); | 1437 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_HIGH, 0x50); |
| 1437 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R25, word); | 1438 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R25, word); |
| 1438 | EEPROM(rt2x00dev, "BBPtune r25: 0x%04x\n", word); | 1439 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r25: 0x%04x\n", word); |
| 1439 | } | 1440 | } |
| 1440 | 1441 | ||
| 1441 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &word); | 1442 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &word); |
| @@ -1443,7 +1444,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1443 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_LOW, 0x60); | 1444 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_LOW, 0x60); |
| 1444 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_HIGH, 0x6d); | 1445 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_HIGH, 0x6d); |
| 1445 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R61, word); | 1446 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R61, word); |
| 1446 | EEPROM(rt2x00dev, "BBPtune r61: 0x%04x\n", word); | 1447 | rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r61: 0x%04x\n", word); |
| 1447 | } | 1448 | } |
| 1448 | 1449 | ||
| 1449 | return 0; | 1450 | return 0; |
| @@ -1468,7 +1469,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1468 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); | 1469 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); |
| 1469 | 1470 | ||
| 1470 | if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) { | 1471 | if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) { |
| 1471 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 1472 | rt2x00_err(rt2x00dev, "Invalid RT chipset detected\n"); |
| 1472 | return -ENODEV; | 1473 | return -ENODEV; |
| 1473 | } | 1474 | } |
| 1474 | 1475 | ||
| @@ -1478,7 +1479,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1478 | !rt2x00_rf(rt2x00dev, RF2525) && | 1479 | !rt2x00_rf(rt2x00dev, RF2525) && |
| 1479 | !rt2x00_rf(rt2x00dev, RF2525E) && | 1480 | !rt2x00_rf(rt2x00dev, RF2525E) && |
| 1480 | !rt2x00_rf(rt2x00dev, RF5222)) { | 1481 | !rt2x00_rf(rt2x00dev, RF5222)) { |
| 1481 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 1482 | rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); |
| 1482 | return -ENODEV; | 1483 | return -ENODEV; |
| 1483 | } | 1484 | } |
| 1484 | 1485 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 7deac4d2459f..b52d70c75e1a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -80,7 +80,7 @@ static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev) | |||
| 80 | rt2x00_rf(rt2x00dev, RF3022)) | 80 | rt2x00_rf(rt2x00dev, RF3022)) |
| 81 | return true; | 81 | return true; |
| 82 | 82 | ||
| 83 | WARNING(rt2x00dev, "Unknown RF chipset on rt305x\n"); | 83 | rt2x00_warn(rt2x00dev, "Unknown RF chipset on rt305x\n"); |
| 84 | return false; | 84 | return false; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -328,7 +328,7 @@ int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) | |||
| 328 | msleep(1); | 328 | msleep(1); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 331 | rt2x00_err(rt2x00dev, "Unstable hardware\n"); |
| 332 | return -EBUSY; | 332 | return -EBUSY; |
| 333 | } | 333 | } |
| 334 | EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); | 334 | EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); |
| @@ -351,7 +351,7 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | |||
| 351 | msleep(10); | 351 | msleep(10); |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | ERROR(rt2x00dev, "WPDMA TX/RX busy [0x%08x].\n", reg); | 354 | rt2x00_err(rt2x00dev, "WPDMA TX/RX busy [0x%08x]\n", reg); |
| 355 | return -EACCES; | 355 | return -EACCES; |
| 356 | } | 356 | } |
| 357 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); | 357 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); |
| @@ -512,7 +512,7 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | if (i == REGISTER_BUSY_COUNT) { | 514 | if (i == REGISTER_BUSY_COUNT) { |
| 515 | ERROR(rt2x00dev, "PBF system register not ready.\n"); | 515 | rt2x00_err(rt2x00dev, "PBF system register not ready\n"); |
| 516 | return -EBUSY; | 516 | return -EBUSY; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| @@ -542,6 +542,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
| 542 | { | 542 | { |
| 543 | __le32 *txwi = rt2800_drv_get_txwi(entry); | 543 | __le32 *txwi = rt2800_drv_get_txwi(entry); |
| 544 | u32 word; | 544 | u32 word; |
| 545 | int i; | ||
| 545 | 546 | ||
| 546 | /* | 547 | /* |
| 547 | * Initialize TX Info descriptor | 548 | * Initialize TX Info descriptor |
| @@ -584,14 +585,16 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
| 584 | rt2x00_desc_write(txwi, 1, word); | 585 | rt2x00_desc_write(txwi, 1, word); |
| 585 | 586 | ||
| 586 | /* | 587 | /* |
| 587 | * Always write 0 to IV/EIV fields, hardware will insert the IV | 588 | * Always write 0 to IV/EIV fields (word 2 and 3), hardware will insert |
| 588 | * from the IVEIV register when TXD_W3_WIV is set to 0. | 589 | * the IV from the IVEIV register when TXD_W3_WIV is set to 0. |
| 589 | * When TXD_W3_WIV is set to 1 it will use the IV data | 590 | * When TXD_W3_WIV is set to 1 it will use the IV data |
| 590 | * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which | 591 | * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which |
| 591 | * crypto entry in the registers should be used to encrypt the frame. | 592 | * crypto entry in the registers should be used to encrypt the frame. |
| 593 | * | ||
| 594 | * Nulify all remaining words as well, we don't know how to program them. | ||
| 592 | */ | 595 | */ |
| 593 | _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | 596 | for (i = 2; i < entry->queue->winfo_size / sizeof(__le32); i++) |
| 594 | _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | 597 | _rt2x00_desc_write(txwi, i, 0); |
| 595 | } | 598 | } |
| 596 | EXPORT_SYMBOL_GPL(rt2800_write_tx_data); | 599 | EXPORT_SYMBOL_GPL(rt2800_write_tx_data); |
| 597 | 600 | ||
| @@ -676,6 +679,10 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
| 676 | * Convert descriptor AGC value to RSSI value. | 679 | * Convert descriptor AGC value to RSSI value. |
| 677 | */ | 680 | */ |
| 678 | rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); | 681 | rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); |
| 682 | /* | ||
| 683 | * Remove RXWI descriptor from start of the buffer. | ||
| 684 | */ | ||
| 685 | skb_pull(entry->skb, entry->queue->winfo_size); | ||
| 679 | } | 686 | } |
| 680 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 687 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
| 681 | 688 | ||
| @@ -766,6 +773,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
| 766 | unsigned int beacon_base; | 773 | unsigned int beacon_base; |
| 767 | unsigned int padding_len; | 774 | unsigned int padding_len; |
| 768 | u32 orig_reg, reg; | 775 | u32 orig_reg, reg; |
| 776 | const int txwi_desc_size = entry->queue->winfo_size; | ||
| 769 | 777 | ||
| 770 | /* | 778 | /* |
| 771 | * Disable beaconing while we are reloading the beacon data, | 779 | * Disable beaconing while we are reloading the beacon data, |
| @@ -779,14 +787,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
| 779 | /* | 787 | /* |
| 780 | * Add space for the TXWI in front of the skb. | 788 | * Add space for the TXWI in front of the skb. |
| 781 | */ | 789 | */ |
| 782 | memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); | 790 | memset(skb_push(entry->skb, txwi_desc_size), 0, txwi_desc_size); |
| 783 | 791 | ||
| 784 | /* | 792 | /* |
| 785 | * Register descriptor details in skb frame descriptor. | 793 | * Register descriptor details in skb frame descriptor. |
| 786 | */ | 794 | */ |
| 787 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | 795 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; |
| 788 | skbdesc->desc = entry->skb->data; | 796 | skbdesc->desc = entry->skb->data; |
| 789 | skbdesc->desc_len = TXWI_DESC_SIZE; | 797 | skbdesc->desc_len = txwi_desc_size; |
| 790 | 798 | ||
| 791 | /* | 799 | /* |
| 792 | * Add the TXWI for the beacon to the skb. | 800 | * Add the TXWI for the beacon to the skb. |
| @@ -803,7 +811,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
| 803 | */ | 811 | */ |
| 804 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 812 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
| 805 | if (padding_len && skb_pad(entry->skb, padding_len)) { | 813 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
| 806 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | 814 | rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); |
| 807 | /* skb freed by skb_pad() on failure */ | 815 | /* skb freed by skb_pad() on failure */ |
| 808 | entry->skb = NULL; | 816 | entry->skb = NULL; |
| 809 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); | 817 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); |
| @@ -832,13 +840,14 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev, | |||
| 832 | unsigned int beacon_base) | 840 | unsigned int beacon_base) |
| 833 | { | 841 | { |
| 834 | int i; | 842 | int i; |
| 843 | const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size; | ||
| 835 | 844 | ||
| 836 | /* | 845 | /* |
| 837 | * For the Beacon base registers we only need to clear | 846 | * For the Beacon base registers we only need to clear |
| 838 | * the whole TXWI which (when set to 0) will invalidate | 847 | * the whole TXWI which (when set to 0) will invalidate |
| 839 | * the entire beacon. | 848 | * the entire beacon. |
| 840 | */ | 849 | */ |
| 841 | for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32)) | 850 | for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) |
| 842 | rt2800_register_write(rt2x00dev, beacon_base + i, 0); | 851 | rt2800_register_write(rt2x00dev, beacon_base + i, 0); |
| 843 | } | 852 | } |
| 844 | 853 | ||
| @@ -3147,7 +3156,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
| 3147 | 3156 | ||
| 3148 | void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) | 3157 | void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) |
| 3149 | { | 3158 | { |
| 3150 | rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel, | 3159 | rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan, |
| 3151 | rt2x00dev->tx_power); | 3160 | rt2x00dev->tx_power); |
| 3152 | } | 3161 | } |
| 3153 | EXPORT_SYMBOL_GPL(rt2800_gain_calibration); | 3162 | EXPORT_SYMBOL_GPL(rt2800_gain_calibration); |
| @@ -3282,11 +3291,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, | |||
| 3282 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { | 3291 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 3283 | rt2800_config_channel(rt2x00dev, libconf->conf, | 3292 | rt2800_config_channel(rt2x00dev, libconf->conf, |
| 3284 | &libconf->rf, &libconf->channel); | 3293 | &libconf->rf, &libconf->channel); |
| 3285 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel, | 3294 | rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, |
| 3286 | libconf->conf->power_level); | 3295 | libconf->conf->power_level); |
| 3287 | } | 3296 | } |
| 3288 | if (flags & IEEE80211_CONF_CHANGE_POWER) | 3297 | if (flags & IEEE80211_CONF_CHANGE_POWER) |
| 3289 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel, | 3298 | rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, |
| 3290 | libconf->conf->power_level); | 3299 | libconf->conf->power_level); |
| 3291 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 3300 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
| 3292 | rt2800_config_retry_limit(rt2x00dev, libconf); | 3301 | rt2800_config_retry_limit(rt2x00dev, libconf); |
| @@ -3860,7 +3869,7 @@ static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | |||
| 3860 | udelay(REGISTER_BUSY_DELAY); | 3869 | udelay(REGISTER_BUSY_DELAY); |
| 3861 | } | 3870 | } |
| 3862 | 3871 | ||
| 3863 | ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n"); | 3872 | rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n"); |
| 3864 | return -EACCES; | 3873 | return -EACCES; |
| 3865 | } | 3874 | } |
| 3866 | 3875 | ||
| @@ -3884,7 +3893,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 3884 | udelay(REGISTER_BUSY_DELAY); | 3893 | udelay(REGISTER_BUSY_DELAY); |
| 3885 | } | 3894 | } |
| 3886 | 3895 | ||
| 3887 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 3896 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 3888 | return -EACCES; | 3897 | return -EACCES; |
| 3889 | } | 3898 | } |
| 3890 | 3899 | ||
| @@ -3924,7 +3933,7 @@ static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) | |||
| 3924 | } | 3933 | } |
| 3925 | }; | 3934 | }; |
| 3926 | 3935 | ||
| 3927 | static void rt2800_init_bbb_early(struct rt2x00_dev *rt2x00dev) | 3936 | static void rt2800_init_bbp_early(struct rt2x00_dev *rt2x00dev) |
| 3928 | { | 3937 | { |
| 3929 | rt2800_bbp_write(rt2x00dev, 65, 0x2C); | 3938 | rt2800_bbp_write(rt2x00dev, 65, 0x2C); |
| 3930 | rt2800_bbp_write(rt2x00dev, 66, 0x38); | 3939 | rt2800_bbp_write(rt2x00dev, 66, 0x38); |
| @@ -3950,7 +3959,7 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) | |||
| 3950 | u16 eeprom; | 3959 | u16 eeprom; |
| 3951 | u8 value; | 3960 | u8 value; |
| 3952 | 3961 | ||
| 3953 | rt2800_init_bbb_early(rt2x00dev); | 3962 | rt2800_init_bbp_early(rt2x00dev); |
| 3954 | 3963 | ||
| 3955 | rt2800_bbp_read(rt2x00dev, 105, &value); | 3964 | rt2800_bbp_read(rt2x00dev, 105, &value); |
| 3956 | rt2x00_set_field8(&value, BBP105_MLD, | 3965 | rt2x00_set_field8(&value, BBP105_MLD, |
| @@ -4332,8 +4341,17 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
| 4332 | return 0; | 4341 | return 0; |
| 4333 | } | 4342 | } |
| 4334 | 4343 | ||
| 4335 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | 4344 | static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev) |
| 4336 | bool bw40, u8 rfcsr24, u8 filter_target) | 4345 | { |
| 4346 | u32 reg; | ||
| 4347 | |||
| 4348 | rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); | ||
| 4349 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); | ||
| 4350 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); | ||
| 4351 | } | ||
| 4352 | |||
| 4353 | static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, bool bw40, | ||
| 4354 | u8 filter_target) | ||
| 4337 | { | 4355 | { |
| 4338 | unsigned int i; | 4356 | unsigned int i; |
| 4339 | u8 bbp; | 4357 | u8 bbp; |
| @@ -4341,6 +4359,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
| 4341 | u8 passband; | 4359 | u8 passband; |
| 4342 | u8 stopband; | 4360 | u8 stopband; |
| 4343 | u8 overtuned = 0; | 4361 | u8 overtuned = 0; |
| 4362 | u8 rfcsr24 = (bw40) ? 0x27 : 0x07; | ||
| 4344 | 4363 | ||
| 4345 | rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24); | 4364 | rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24); |
| 4346 | 4365 | ||
| @@ -4396,8 +4415,169 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |||
| 4396 | return rfcsr24; | 4415 | return rfcsr24; |
| 4397 | } | 4416 | } |
| 4398 | 4417 | ||
| 4418 | static void rt2800_rf_init_calibration(struct rt2x00_dev *rt2x00dev, | ||
| 4419 | const unsigned int rf_reg) | ||
| 4420 | { | ||
| 4421 | u8 rfcsr; | ||
| 4422 | |||
| 4423 | rt2800_rfcsr_read(rt2x00dev, rf_reg, &rfcsr); | ||
| 4424 | rt2x00_set_field8(&rfcsr, FIELD8(0x80), 1); | ||
| 4425 | rt2800_rfcsr_write(rt2x00dev, rf_reg, rfcsr); | ||
| 4426 | msleep(1); | ||
| 4427 | rt2x00_set_field8(&rfcsr, FIELD8(0x80), 0); | ||
| 4428 | rt2800_rfcsr_write(rt2x00dev, rf_reg, rfcsr); | ||
| 4429 | } | ||
| 4430 | |||
| 4431 | static void rt2800_rx_filter_calibration(struct rt2x00_dev *rt2x00dev) | ||
| 4432 | { | ||
| 4433 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
| 4434 | u8 filter_tgt_bw20; | ||
| 4435 | u8 filter_tgt_bw40; | ||
| 4436 | u8 rfcsr, bbp; | ||
| 4437 | |||
| 4438 | /* | ||
| 4439 | * TODO: sync filter_tgt values with vendor driver | ||
| 4440 | */ | ||
| 4441 | if (rt2x00_rt(rt2x00dev, RT3070)) { | ||
| 4442 | filter_tgt_bw20 = 0x16; | ||
| 4443 | filter_tgt_bw40 = 0x19; | ||
| 4444 | } else { | ||
| 4445 | filter_tgt_bw20 = 0x13; | ||
| 4446 | filter_tgt_bw40 = 0x15; | ||
| 4447 | } | ||
| 4448 | |||
| 4449 | drv_data->calibration_bw20 = | ||
| 4450 | rt2800_init_rx_filter(rt2x00dev, false, filter_tgt_bw20); | ||
| 4451 | drv_data->calibration_bw40 = | ||
| 4452 | rt2800_init_rx_filter(rt2x00dev, true, filter_tgt_bw40); | ||
| 4453 | |||
| 4454 | /* | ||
| 4455 | * Save BBP 25 & 26 values for later use in channel switching (for 3052) | ||
| 4456 | */ | ||
| 4457 | rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); | ||
| 4458 | rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); | ||
| 4459 | |||
| 4460 | /* | ||
| 4461 | * Set back to initial state | ||
| 4462 | */ | ||
| 4463 | rt2800_bbp_write(rt2x00dev, 24, 0); | ||
| 4464 | |||
| 4465 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | ||
| 4466 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); | ||
| 4467 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | ||
| 4468 | |||
| 4469 | /* | ||
| 4470 | * Set BBP back to BW20 | ||
| 4471 | */ | ||
| 4472 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | ||
| 4473 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); | ||
| 4474 | rt2800_bbp_write(rt2x00dev, 4, bbp); | ||
| 4475 | } | ||
| 4476 | |||
| 4477 | static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev) | ||
| 4478 | { | ||
| 4479 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
| 4480 | u8 min_gain, rfcsr, bbp; | ||
| 4481 | u16 eeprom; | ||
| 4482 | |||
| 4483 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | ||
| 4484 | |||
| 4485 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); | ||
| 4486 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
| 4487 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 4488 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | ||
| 4489 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | ||
| 4490 | if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) | ||
| 4491 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | ||
| 4492 | } | ||
| 4493 | |||
| 4494 | min_gain = rt2x00_rt(rt2x00dev, RT3070) ? 1 : 2; | ||
| 4495 | if (drv_data->txmixer_gain_24g >= min_gain) { | ||
| 4496 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, | ||
| 4497 | drv_data->txmixer_gain_24g); | ||
| 4498 | } | ||
| 4499 | |||
| 4500 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
| 4501 | |||
| 4502 | if (rt2x00_rt(rt2x00dev, RT3090)) { | ||
| 4503 | /* Turn off unused DAC1 and ADC1 to reduce power consumption */ | ||
| 4504 | rt2800_bbp_read(rt2x00dev, 138, &bbp); | ||
| 4505 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | ||
| 4506 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | ||
| 4507 | rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); | ||
| 4508 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) | ||
| 4509 | rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); | ||
| 4510 | rt2800_bbp_write(rt2x00dev, 138, bbp); | ||
| 4511 | } | ||
| 4512 | |||
| 4513 | if (rt2x00_rt(rt2x00dev, RT3070)) { | ||
| 4514 | rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); | ||
| 4515 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) | ||
| 4516 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); | ||
| 4517 | else | ||
| 4518 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); | ||
| 4519 | rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0); | ||
| 4520 | rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0); | ||
| 4521 | rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0); | ||
| 4522 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); | ||
| 4523 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | ||
| 4524 | rt2x00_rt(rt2x00dev, RT3090) || | ||
| 4525 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
| 4526 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | ||
| 4527 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | ||
| 4528 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); | ||
| 4529 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); | ||
| 4530 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); | ||
| 4531 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); | ||
| 4532 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | ||
| 4533 | |||
| 4534 | rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr); | ||
| 4535 | rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0); | ||
| 4536 | rt2800_rfcsr_write(rt2x00dev, 15, rfcsr); | ||
| 4537 | |||
| 4538 | rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); | ||
| 4539 | rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0); | ||
| 4540 | rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); | ||
| 4541 | |||
| 4542 | rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); | ||
| 4543 | rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0); | ||
| 4544 | rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); | ||
| 4545 | } | ||
| 4546 | } | ||
| 4547 | |||
| 4548 | static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev) | ||
| 4549 | { | ||
| 4550 | u8 reg; | ||
| 4551 | u16 eeprom; | ||
| 4552 | |||
| 4553 | /* Turn off unused DAC1 and ADC1 to reduce power consumption */ | ||
| 4554 | rt2800_bbp_read(rt2x00dev, 138, ®); | ||
| 4555 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | ||
| 4556 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | ||
| 4557 | rt2x00_set_field8(®, BBP138_RX_ADC1, 0); | ||
| 4558 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) | ||
| 4559 | rt2x00_set_field8(®, BBP138_TX_DAC1, 1); | ||
| 4560 | rt2800_bbp_write(rt2x00dev, 138, reg); | ||
| 4561 | |||
| 4562 | rt2800_rfcsr_read(rt2x00dev, 38, ®); | ||
| 4563 | rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); | ||
| 4564 | rt2800_rfcsr_write(rt2x00dev, 38, reg); | ||
| 4565 | |||
| 4566 | rt2800_rfcsr_read(rt2x00dev, 39, ®); | ||
| 4567 | rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); | ||
| 4568 | rt2800_rfcsr_write(rt2x00dev, 39, reg); | ||
| 4569 | |||
| 4570 | rt2800_bbp4_mac_if_ctrl(rt2x00dev); | ||
| 4571 | |||
| 4572 | rt2800_rfcsr_read(rt2x00dev, 30, ®); | ||
| 4573 | rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); | ||
| 4574 | rt2800_rfcsr_write(rt2x00dev, 30, reg); | ||
| 4575 | } | ||
| 4576 | |||
| 4399 | static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) | 4577 | static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) |
| 4400 | { | 4578 | { |
| 4579 | rt2800_rf_init_calibration(rt2x00dev, 30); | ||
| 4580 | |||
| 4401 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | 4581 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); |
| 4402 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); | 4582 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); |
| 4403 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); | 4583 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); |
| @@ -4434,6 +4614,13 @@ static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) | |||
| 4434 | 4614 | ||
| 4435 | static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) | 4615 | static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) |
| 4436 | { | 4616 | { |
| 4617 | u8 rfcsr; | ||
| 4618 | u16 eeprom; | ||
| 4619 | u32 reg; | ||
| 4620 | |||
| 4621 | /* XXX vendor driver do this only for 3070 */ | ||
| 4622 | rt2800_rf_init_calibration(rt2x00dev, 30); | ||
| 4623 | |||
| 4437 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | 4624 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); |
| 4438 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | 4625 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); |
| 4439 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | 4626 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); |
| @@ -4453,10 +4640,54 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) | |||
| 4453 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | 4640 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); |
| 4454 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | 4641 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); |
| 4455 | rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); | 4642 | rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); |
| 4643 | |||
| 4644 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | ||
| 4645 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4646 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4647 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4648 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4649 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | ||
| 4650 | rt2x00_rt(rt2x00dev, RT3090)) { | ||
| 4651 | rt2800_rfcsr_write(rt2x00dev, 31, 0x14); | ||
| 4652 | |||
| 4653 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 4654 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | ||
| 4655 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 4656 | |||
| 4657 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4658 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4659 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 4660 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { | ||
| 4661 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
| 4662 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) | ||
| 4663 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4664 | else | ||
| 4665 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
| 4666 | } | ||
| 4667 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4668 | |||
| 4669 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
| 4670 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | ||
| 4671 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
| 4672 | } | ||
| 4673 | |||
| 4674 | rt2800_rx_filter_calibration(rt2x00dev); | ||
| 4675 | |||
| 4676 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | ||
| 4677 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 4678 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) | ||
| 4679 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
| 4680 | |||
| 4681 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4682 | rt2800_normal_mode_setup_3xxx(rt2x00dev); | ||
| 4456 | } | 4683 | } |
| 4457 | 4684 | ||
| 4458 | static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) | 4685 | static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) |
| 4459 | { | 4686 | { |
| 4687 | u8 rfcsr; | ||
| 4688 | |||
| 4689 | rt2800_rf_init_calibration(rt2x00dev, 2); | ||
| 4690 | |||
| 4460 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | 4691 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); |
| 4461 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | 4692 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); |
| 4462 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | 4693 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); |
| @@ -4503,10 +4734,19 @@ static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) | |||
| 4503 | rt2800_rfcsr_write(rt2x00dev, 59, 0x09); | 4734 | rt2800_rfcsr_write(rt2x00dev, 59, 0x09); |
| 4504 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | 4735 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); |
| 4505 | rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); | 4736 | rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); |
| 4737 | |||
| 4738 | rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); | ||
| 4739 | rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); | ||
| 4740 | rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); | ||
| 4741 | |||
| 4742 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4743 | rt2800_normal_mode_setup_3xxx(rt2x00dev); | ||
| 4506 | } | 4744 | } |
| 4507 | 4745 | ||
| 4508 | static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) | 4746 | static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) |
| 4509 | { | 4747 | { |
| 4748 | rt2800_rf_init_calibration(rt2x00dev, 30); | ||
| 4749 | |||
| 4510 | rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); | 4750 | rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); |
| 4511 | rt2800_rfcsr_write(rt2x00dev, 1, 0x23); | 4751 | rt2800_rfcsr_write(rt2x00dev, 1, 0x23); |
| 4512 | rt2800_rfcsr_write(rt2x00dev, 2, 0x50); | 4752 | rt2800_rfcsr_write(rt2x00dev, 2, 0x50); |
| @@ -4570,10 +4810,18 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) | |||
| 4570 | rt2800_rfcsr_write(rt2x00dev, 61, 0x00); | 4810 | rt2800_rfcsr_write(rt2x00dev, 61, 0x00); |
| 4571 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | 4811 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); |
| 4572 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | 4812 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); |
| 4813 | |||
| 4814 | rt2800_rx_filter_calibration(rt2x00dev); | ||
| 4815 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4816 | rt2800_normal_mode_setup_3xxx(rt2x00dev); | ||
| 4573 | } | 4817 | } |
| 4574 | 4818 | ||
| 4575 | static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) | 4819 | static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) |
| 4576 | { | 4820 | { |
| 4821 | u32 reg; | ||
| 4822 | |||
| 4823 | rt2800_rf_init_calibration(rt2x00dev, 30); | ||
| 4824 | |||
| 4577 | rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); | 4825 | rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); |
| 4578 | rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); | 4826 | rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); |
| 4579 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | 4827 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); |
| @@ -4606,10 +4854,27 @@ static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) | |||
| 4606 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); | 4854 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); |
| 4607 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); | 4855 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); |
| 4608 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); | 4856 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); |
| 4857 | |||
| 4858 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
| 4859 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | ||
| 4860 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
| 4861 | |||
| 4862 | rt2800_rx_filter_calibration(rt2x00dev); | ||
| 4863 | |||
| 4864 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) | ||
| 4865 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
| 4866 | |||
| 4867 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4868 | rt2800_normal_mode_setup_3xxx(rt2x00dev); | ||
| 4609 | } | 4869 | } |
| 4610 | 4870 | ||
| 4611 | static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) | 4871 | static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) |
| 4612 | { | 4872 | { |
| 4873 | u8 rfcsr; | ||
| 4874 | u32 reg; | ||
| 4875 | |||
| 4876 | rt2800_rf_init_calibration(rt2x00dev, 30); | ||
| 4877 | |||
| 4613 | rt2800_rfcsr_write(rt2x00dev, 0, 0x70); | 4878 | rt2800_rfcsr_write(rt2x00dev, 0, 0x70); |
| 4614 | rt2800_rfcsr_write(rt2x00dev, 1, 0x81); | 4879 | rt2800_rfcsr_write(rt2x00dev, 1, 0x81); |
| 4615 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | 4880 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); |
| @@ -4641,10 +4906,30 @@ static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) | |||
| 4641 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); | 4906 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); |
| 4642 | rt2800_rfcsr_write(rt2x00dev, 30, 0x09); | 4907 | rt2800_rfcsr_write(rt2x00dev, 30, 0x09); |
| 4643 | rt2800_rfcsr_write(rt2x00dev, 31, 0x10); | 4908 | rt2800_rfcsr_write(rt2x00dev, 31, 0x10); |
| 4909 | |||
| 4910 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 4911 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | ||
| 4912 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 4913 | |||
| 4914 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4915 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4916 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4917 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4918 | msleep(1); | ||
| 4919 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4920 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
| 4921 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4922 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4923 | |||
| 4924 | rt2800_rx_filter_calibration(rt2x00dev); | ||
| 4925 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4926 | rt2800_normal_mode_setup_3xxx(rt2x00dev); | ||
| 4644 | } | 4927 | } |
| 4645 | 4928 | ||
| 4646 | static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) | 4929 | static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) |
| 4647 | { | 4930 | { |
| 4931 | rt2800_rf_init_calibration(rt2x00dev, 2); | ||
| 4932 | |||
| 4648 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | 4933 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); |
| 4649 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | 4934 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); |
| 4650 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | 4935 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); |
| @@ -4725,10 +5010,16 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) | |||
| 4725 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | 5010 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); |
| 4726 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | 5011 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); |
| 4727 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | 5012 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); |
| 5013 | |||
| 5014 | rt2800_normal_mode_setup_5xxx(rt2x00dev); | ||
| 5015 | |||
| 5016 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4728 | } | 5017 | } |
| 4729 | 5018 | ||
| 4730 | static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) | 5019 | static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) |
| 4731 | { | 5020 | { |
| 5021 | rt2800_rf_init_calibration(rt2x00dev, 2); | ||
| 5022 | |||
| 4732 | rt2800_rfcsr_write(rt2x00dev, 1, 0x17); | 5023 | rt2800_rfcsr_write(rt2x00dev, 1, 0x17); |
| 4733 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | 5024 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); |
| 4734 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | 5025 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); |
| @@ -4788,12 +5079,15 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) | |||
| 4788 | rt2800_rfcsr_write(rt2x00dev, 61, 0x91); | 5079 | rt2800_rfcsr_write(rt2x00dev, 61, 0x91); |
| 4789 | rt2800_rfcsr_write(rt2x00dev, 62, 0x39); | 5080 | rt2800_rfcsr_write(rt2x00dev, 62, 0x39); |
| 4790 | rt2800_rfcsr_write(rt2x00dev, 63, 0x07); | 5081 | rt2800_rfcsr_write(rt2x00dev, 63, 0x07); |
| 5082 | |||
| 5083 | rt2800_normal_mode_setup_5xxx(rt2x00dev); | ||
| 5084 | |||
| 5085 | rt2800_led_open_drain_enable(rt2x00dev); | ||
| 4791 | } | 5086 | } |
| 4792 | 5087 | ||
| 4793 | static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) | 5088 | static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) |
| 4794 | { | 5089 | { |
| 4795 | u8 reg; | 5090 | rt2800_rf_init_calibration(rt2x00dev, 30); |
| 4796 | u16 eeprom; | ||
| 4797 | 5091 | ||
| 4798 | rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); | 5092 | rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); |
| 4799 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | 5093 | rt2800_rfcsr_write(rt2x00dev, 3, 0x08); |
| @@ -4823,83 +5117,23 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) | |||
| 4823 | 5117 | ||
| 4824 | rt2800_adjust_freq_offset(rt2x00dev); | 5118 | rt2800_adjust_freq_offset(rt2x00dev); |
| 4825 | 5119 | ||
| 4826 | rt2800_bbp_read(rt2x00dev, 138, ®); | ||
| 4827 | |||
| 4828 | /* Turn off unused DAC1 and ADC1 to reduce power consumption */ | ||
| 4829 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | ||
| 4830 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | ||
| 4831 | rt2x00_set_field8(®, BBP138_RX_ADC1, 0); | ||
| 4832 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) | ||
| 4833 | rt2x00_set_field8(®, BBP138_TX_DAC1, 1); | ||
| 4834 | |||
| 4835 | rt2800_bbp_write(rt2x00dev, 138, reg); | ||
| 4836 | |||
| 4837 | /* Enable DC filter */ | 5120 | /* Enable DC filter */ |
| 4838 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) | 5121 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) |
| 4839 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 5122 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
| 4840 | 5123 | ||
| 4841 | rt2800_rfcsr_read(rt2x00dev, 38, ®); | 5124 | rt2800_normal_mode_setup_5xxx(rt2x00dev); |
| 4842 | rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); | ||
| 4843 | rt2800_rfcsr_write(rt2x00dev, 38, reg); | ||
| 4844 | |||
| 4845 | rt2800_rfcsr_read(rt2x00dev, 39, ®); | ||
| 4846 | rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); | ||
| 4847 | rt2800_rfcsr_write(rt2x00dev, 39, reg); | ||
| 4848 | 5125 | ||
| 4849 | rt2800_bbp4_mac_if_ctrl(rt2x00dev); | 5126 | if (rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C)) |
| 5127 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
| 4850 | 5128 | ||
| 4851 | rt2800_rfcsr_read(rt2x00dev, 30, ®); | 5129 | rt2800_led_open_drain_enable(rt2x00dev); |
| 4852 | rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); | ||
| 4853 | rt2800_rfcsr_write(rt2x00dev, 30, reg); | ||
| 4854 | } | 5130 | } |
| 4855 | 5131 | ||
| 4856 | static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | 5132 | static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) |
| 4857 | { | 5133 | { |
| 4858 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
| 4859 | u8 rfcsr; | ||
| 4860 | u8 bbp; | ||
| 4861 | u32 reg; | ||
| 4862 | u16 eeprom; | ||
| 4863 | |||
| 4864 | if (!rt2x00_rt(rt2x00dev, RT3070) && | ||
| 4865 | !rt2x00_rt(rt2x00dev, RT3071) && | ||
| 4866 | !rt2x00_rt(rt2x00dev, RT3090) && | ||
| 4867 | !rt2x00_rt(rt2x00dev, RT3290) && | ||
| 4868 | !rt2x00_rt(rt2x00dev, RT3352) && | ||
| 4869 | !rt2x00_rt(rt2x00dev, RT3390) && | ||
| 4870 | !rt2x00_rt(rt2x00dev, RT3572) && | ||
| 4871 | !rt2x00_rt(rt2x00dev, RT5390) && | ||
| 4872 | !rt2x00_rt(rt2x00dev, RT5392) && | ||
| 4873 | !rt2x00_rt(rt2x00dev, RT5392) && | ||
| 4874 | !rt2x00_rt(rt2x00dev, RT5592) && | ||
| 4875 | !rt2800_is_305x_soc(rt2x00dev)) | ||
| 4876 | return 0; | ||
| 4877 | |||
| 4878 | /* | ||
| 4879 | * Init RF calibration. | ||
| 4880 | */ | ||
| 4881 | |||
| 4882 | if (rt2x00_rt(rt2x00dev, RT3290) || | ||
| 4883 | rt2x00_rt(rt2x00dev, RT5390) || | ||
| 4884 | rt2x00_rt(rt2x00dev, RT5392)) { | ||
| 4885 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); | ||
| 4886 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); | ||
| 4887 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | ||
| 4888 | msleep(1); | ||
| 4889 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); | ||
| 4890 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | ||
| 4891 | } else { | ||
| 4892 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
| 4893 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
| 4894 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
| 4895 | msleep(1); | ||
| 4896 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | ||
| 4897 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
| 4898 | } | ||
| 4899 | |||
| 4900 | if (rt2800_is_305x_soc(rt2x00dev)) { | 5134 | if (rt2800_is_305x_soc(rt2x00dev)) { |
| 4901 | rt2800_init_rfcsr_305x_soc(rt2x00dev); | 5135 | rt2800_init_rfcsr_305x_soc(rt2x00dev); |
| 4902 | return 0; | 5136 | return; |
| 4903 | } | 5137 | } |
| 4904 | 5138 | ||
| 4905 | switch (rt2x00dev->chip.rt) { | 5139 | switch (rt2x00dev->chip.rt) { |
| @@ -4928,202 +5162,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 4928 | break; | 5162 | break; |
| 4929 | case RT5592: | 5163 | case RT5592: |
| 4930 | rt2800_init_rfcsr_5592(rt2x00dev); | 5164 | rt2800_init_rfcsr_5592(rt2x00dev); |
| 4931 | return 0; | 5165 | break; |
| 4932 | } | ||
| 4933 | |||
| 4934 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | ||
| 4935 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4936 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4937 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4938 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4939 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | ||
| 4940 | rt2x00_rt(rt2x00dev, RT3090)) { | ||
| 4941 | rt2800_rfcsr_write(rt2x00dev, 31, 0x14); | ||
| 4942 | |||
| 4943 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 4944 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | ||
| 4945 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 4946 | |||
| 4947 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4948 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4949 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 4950 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { | ||
| 4951 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
| 4952 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) | ||
| 4953 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4954 | else | ||
| 4955 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
| 4956 | } | ||
| 4957 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4958 | |||
| 4959 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
| 4960 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | ||
| 4961 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
| 4962 | } else if (rt2x00_rt(rt2x00dev, RT3390)) { | ||
| 4963 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
| 4964 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | ||
| 4965 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
| 4966 | } else if (rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 4967 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 4968 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | ||
| 4969 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 4970 | |||
| 4971 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4972 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 4973 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4974 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4975 | msleep(1); | ||
| 4976 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 4977 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
| 4978 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 4979 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 4980 | } | ||
| 4981 | |||
| 4982 | /* | ||
| 4983 | * Set RX Filter calibration for 20MHz and 40MHz | ||
| 4984 | */ | ||
| 4985 | if (rt2x00_rt(rt2x00dev, RT3070)) { | ||
| 4986 | drv_data->calibration_bw20 = | ||
| 4987 | rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16); | ||
| 4988 | drv_data->calibration_bw40 = | ||
| 4989 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); | ||
| 4990 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | ||
| 4991 | rt2x00_rt(rt2x00dev, RT3090) || | ||
| 4992 | rt2x00_rt(rt2x00dev, RT3352) || | ||
| 4993 | rt2x00_rt(rt2x00dev, RT3390) || | ||
| 4994 | rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 4995 | drv_data->calibration_bw20 = | ||
| 4996 | rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); | ||
| 4997 | drv_data->calibration_bw40 = | ||
| 4998 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); | ||
| 4999 | } | ||
| 5000 | |||
| 5001 | /* | ||
| 5002 | * Save BBP 25 & 26 values for later use in channel switching | ||
| 5003 | */ | ||
| 5004 | rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); | ||
| 5005 | rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); | ||
| 5006 | |||
| 5007 | if (!rt2x00_rt(rt2x00dev, RT5390) && | ||
| 5008 | !rt2x00_rt(rt2x00dev, RT5392)) { | ||
| 5009 | /* | ||
| 5010 | * Set back to initial state | ||
| 5011 | */ | ||
| 5012 | rt2800_bbp_write(rt2x00dev, 24, 0); | ||
| 5013 | |||
| 5014 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | ||
| 5015 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); | ||
| 5016 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | ||
| 5017 | |||
| 5018 | /* | ||
| 5019 | * Set BBP back to BW20 | ||
| 5020 | */ | ||
| 5021 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | ||
| 5022 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); | ||
| 5023 | rt2800_bbp_write(rt2x00dev, 4, bbp); | ||
| 5024 | } | ||
| 5025 | |||
| 5026 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | ||
| 5027 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 5028 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | ||
| 5029 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E) || | ||
| 5030 | rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C)) | ||
| 5031 | rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | ||
| 5032 | |||
| 5033 | rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); | ||
| 5034 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); | ||
| 5035 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); | ||
| 5036 | |||
| 5037 | if (!rt2x00_rt(rt2x00dev, RT5390) && | ||
| 5038 | !rt2x00_rt(rt2x00dev, RT5392)) { | ||
| 5039 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | ||
| 5040 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); | ||
| 5041 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
| 5042 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | ||
| 5043 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | ||
| 5044 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | ||
| 5045 | if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, | ||
| 5046 | &rt2x00dev->cap_flags)) | ||
| 5047 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | ||
| 5048 | } | ||
| 5049 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, | ||
| 5050 | drv_data->txmixer_gain_24g); | ||
| 5051 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
| 5052 | } | ||
| 5053 | |||
| 5054 | if (rt2x00_rt(rt2x00dev, RT3090) || | ||
| 5055 | rt2x00_rt(rt2x00dev, RT5592)) { | ||
| 5056 | rt2800_bbp_read(rt2x00dev, 138, &bbp); | ||
| 5057 | |||
| 5058 | /* Turn off unused DAC1 and ADC1 to reduce power consumption */ | ||
| 5059 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | ||
| 5060 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | ||
| 5061 | rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); | ||
| 5062 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) | ||
| 5063 | rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); | ||
| 5064 | |||
| 5065 | rt2800_bbp_write(rt2x00dev, 138, bbp); | ||
| 5066 | } | ||
| 5067 | |||
| 5068 | if (rt2x00_rt(rt2x00dev, RT3071) || | ||
| 5069 | rt2x00_rt(rt2x00dev, RT3090) || | ||
| 5070 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
| 5071 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | ||
| 5072 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | ||
| 5073 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); | ||
| 5074 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); | ||
| 5075 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); | ||
| 5076 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); | ||
| 5077 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | ||
| 5078 | |||
| 5079 | rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr); | ||
| 5080 | rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0); | ||
| 5081 | rt2800_rfcsr_write(rt2x00dev, 15, rfcsr); | ||
| 5082 | |||
| 5083 | rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); | ||
| 5084 | rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0); | ||
| 5085 | rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); | ||
| 5086 | |||
| 5087 | rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); | ||
| 5088 | rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0); | ||
| 5089 | rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); | ||
| 5090 | } | ||
| 5091 | |||
| 5092 | if (rt2x00_rt(rt2x00dev, RT3070)) { | ||
| 5093 | rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); | ||
| 5094 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) | ||
| 5095 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); | ||
| 5096 | else | ||
| 5097 | rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); | ||
| 5098 | rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0); | ||
| 5099 | rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0); | ||
| 5100 | rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0); | ||
| 5101 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); | ||
| 5102 | } | ||
| 5103 | |||
| 5104 | if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
| 5105 | rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); | ||
| 5106 | rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); | ||
| 5107 | rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); | ||
| 5108 | } | ||
| 5109 | |||
| 5110 | if (rt2x00_rt(rt2x00dev, RT5390) || | ||
| 5111 | rt2x00_rt(rt2x00dev, RT5392) || | ||
| 5112 | rt2x00_rt(rt2x00dev, RT5592)) { | ||
| 5113 | rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); | ||
| 5114 | rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); | ||
| 5115 | rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); | ||
| 5116 | |||
| 5117 | rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); | ||
| 5118 | rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); | ||
| 5119 | rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); | ||
| 5120 | |||
| 5121 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
| 5122 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); | ||
| 5123 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
| 5124 | } | 5166 | } |
| 5125 | |||
| 5126 | return 0; | ||
| 5127 | } | 5167 | } |
| 5128 | 5168 | ||
| 5129 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | 5169 | int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) |
| @@ -5149,10 +5189,11 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 5149 | } | 5189 | } |
| 5150 | msleep(1); | 5190 | msleep(1); |
| 5151 | 5191 | ||
| 5152 | if (unlikely(rt2800_init_bbp(rt2x00dev) || | 5192 | if (unlikely(rt2800_init_bbp(rt2x00dev))) |
| 5153 | rt2800_init_rfcsr(rt2x00dev))) | ||
| 5154 | return -EIO; | 5193 | return -EIO; |
| 5155 | 5194 | ||
| 5195 | rt2800_init_rfcsr(rt2x00dev); | ||
| 5196 | |||
| 5156 | if (rt2x00_is_usb(rt2x00dev) && | 5197 | if (rt2x00_is_usb(rt2x00dev) && |
| 5157 | (rt2x00_rt(rt2x00dev, RT3070) || | 5198 | (rt2x00_rt(rt2x00dev, RT3070) || |
| 5158 | rt2x00_rt(rt2x00dev, RT3071) || | 5199 | rt2x00_rt(rt2x00dev, RT3071) || |
| @@ -5312,7 +5353,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 5312 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 5353 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 5313 | if (!is_valid_ether_addr(mac)) { | 5354 | if (!is_valid_ether_addr(mac)) { |
| 5314 | eth_random_addr(mac); | 5355 | eth_random_addr(mac); |
| 5315 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 5356 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 5316 | } | 5357 | } |
| 5317 | 5358 | ||
| 5318 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); | 5359 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); |
| @@ -5321,7 +5362,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 5321 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); | 5362 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); |
| 5322 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); | 5363 | rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); |
| 5323 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); | 5364 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); |
| 5324 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 5365 | rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); |
| 5325 | } else if (rt2x00_rt(rt2x00dev, RT2860) || | 5366 | } else if (rt2x00_rt(rt2x00dev, RT2860) || |
| 5326 | rt2x00_rt(rt2x00dev, RT2872)) { | 5367 | rt2x00_rt(rt2x00dev, RT2872)) { |
| 5327 | /* | 5368 | /* |
| @@ -5350,14 +5391,14 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 5350 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); | 5391 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); |
| 5351 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); | 5392 | rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); |
| 5352 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); | 5393 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); |
| 5353 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 5394 | rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); |
| 5354 | } | 5395 | } |
| 5355 | 5396 | ||
| 5356 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | 5397 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); |
| 5357 | if ((word & 0x00ff) == 0x00ff) { | 5398 | if ((word & 0x00ff) == 0x00ff) { |
| 5358 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | 5399 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); |
| 5359 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | 5400 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); |
| 5360 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | 5401 | rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); |
| 5361 | } | 5402 | } |
| 5362 | if ((word & 0xff00) == 0xff00) { | 5403 | if ((word & 0xff00) == 0xff00) { |
| 5363 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, | 5404 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, |
| @@ -5367,7 +5408,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 5367 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); | 5408 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); |
| 5368 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); | 5409 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); |
| 5369 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); | 5410 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); |
| 5370 | EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); | 5411 | rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word); |
| 5371 | } | 5412 | } |
| 5372 | 5413 | ||
| 5373 | /* | 5414 | /* |
| @@ -5473,7 +5514,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 5473 | case RF5592: | 5514 | case RF5592: |
| 5474 | break; | 5515 | break; |
| 5475 | default: | 5516 | default: |
| 5476 | ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", rf); | 5517 | rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", |
| 5518 | rf); | ||
| 5477 | return -ENODEV; | 5519 | return -ENODEV; |
| 5478 | } | 5520 | } |
| 5479 | 5521 | ||
| @@ -6062,9 +6104,8 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev) | |||
| 6062 | case RT5592: | 6104 | case RT5592: |
| 6063 | break; | 6105 | break; |
| 6064 | default: | 6106 | default: |
| 6065 | ERROR(rt2x00dev, | 6107 | rt2x00_err(rt2x00dev, "Invalid RT chipset 0x%04x, rev %04x detected\n", |
| 6066 | "Invalid RT chipset 0x%04x, rev %04x detected.\n", | 6108 | rt, rev); |
| 6067 | rt, rev); | ||
| 6068 | return -ENODEV; | 6109 | return -ENODEV; |
| 6069 | } | 6110 | } |
| 6070 | 6111 | ||
| @@ -6323,7 +6364,8 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 6323 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 6364 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
| 6324 | break; | 6365 | break; |
| 6325 | default: | 6366 | default: |
| 6326 | WARNING((struct rt2x00_dev *)hw->priv, "Unknown AMPDU action\n"); | 6367 | rt2x00_warn((struct rt2x00_dev *)hw->priv, |
| 6368 | "Unknown AMPDU action\n"); | ||
| 6327 | } | 6369 | } |
| 6328 | 6370 | ||
| 6329 | return ret; | 6371 | return ret; |
| @@ -6340,7 +6382,7 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 6340 | if (idx != 0) | 6382 | if (idx != 0) |
| 6341 | return -ENOENT; | 6383 | return -ENOENT; |
| 6342 | 6384 | ||
| 6343 | survey->channel = conf->channel; | 6385 | survey->channel = conf->chandef.chan; |
| 6344 | 6386 | ||
| 6345 | rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle); | 6387 | rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle); |
| 6346 | rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy); | 6388 | rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 565a80d0e564..6f4a861af336 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
| @@ -72,7 +72,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) | |||
| 72 | return; | 72 | return; |
| 73 | 73 | ||
| 74 | for (i = 0; i < 200; i++) { | 74 | for (i = 0; i < 200; i++) { |
| 75 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); | 75 | rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); |
| 76 | 76 | ||
| 77 | if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || | 77 | if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || |
| 78 | (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || | 78 | (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) || |
| @@ -84,10 +84,10 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | if (i == 200) | 86 | if (i == 200) |
| 87 | ERROR(rt2x00dev, "MCU request failed, no response from hardware\n"); | 87 | rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); |
| 88 | 88 | ||
| 89 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 89 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
| 90 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 90 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) | 93 | #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) |
| @@ -116,7 +116,7 @@ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | |||
| 116 | struct rt2x00_dev *rt2x00dev = eeprom->data; | 116 | struct rt2x00_dev *rt2x00dev = eeprom->data; |
| 117 | u32 reg; | 117 | u32 reg; |
| 118 | 118 | ||
| 119 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | 119 | rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); |
| 120 | 120 | ||
| 121 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); | 121 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); |
| 122 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); | 122 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); |
| @@ -138,7 +138,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
| 138 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, | 138 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, |
| 139 | !!eeprom->reg_chip_select); | 139 | !!eeprom->reg_chip_select); |
| 140 | 140 | ||
| 141 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); | 141 | rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | 144 | static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) |
| @@ -146,7 +146,7 @@ static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | |||
| 146 | struct eeprom_93cx6 eeprom; | 146 | struct eeprom_93cx6 eeprom; |
| 147 | u32 reg; | 147 | u32 reg; |
| 148 | 148 | ||
| 149 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | 149 | rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); |
| 150 | 150 | ||
| 151 | eeprom.data = rt2x00dev; | 151 | eeprom.data = rt2x00dev; |
| 152 | eeprom.register_read = rt2800pci_eepromregister_read; | 152 | eeprom.register_read = rt2800pci_eepromregister_read; |
| @@ -210,20 +210,20 @@ static void rt2800pci_start_queue(struct data_queue *queue) | |||
| 210 | 210 | ||
| 211 | switch (queue->qid) { | 211 | switch (queue->qid) { |
| 212 | case QID_RX: | 212 | case QID_RX: |
| 213 | rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 213 | rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
| 214 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); | 214 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); |
| 215 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 215 | rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
| 216 | break; | 216 | break; |
| 217 | case QID_BEACON: | 217 | case QID_BEACON: |
| 218 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 218 | rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
| 219 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | 219 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); |
| 220 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | 220 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); |
| 221 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 221 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); |
| 222 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 222 | rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
| 223 | 223 | ||
| 224 | rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); | 224 | rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); |
| 225 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); | 225 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); |
| 226 | rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); | 226 | rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); |
| 227 | break; | 227 | break; |
| 228 | default: | 228 | default: |
| 229 | break; | 229 | break; |
| @@ -241,13 +241,13 @@ static void rt2800pci_kick_queue(struct data_queue *queue) | |||
| 241 | case QID_AC_BE: | 241 | case QID_AC_BE: |
| 242 | case QID_AC_BK: | 242 | case QID_AC_BK: |
| 243 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 243 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
| 244 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), | 244 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), |
| 245 | entry->entry_idx); | 245 | entry->entry_idx); |
| 246 | break; | 246 | break; |
| 247 | case QID_MGMT: | 247 | case QID_MGMT: |
| 248 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | 248 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
| 249 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5), | 249 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5), |
| 250 | entry->entry_idx); | 250 | entry->entry_idx); |
| 251 | break; | 251 | break; |
| 252 | default: | 252 | default: |
| 253 | break; | 253 | break; |
| @@ -261,20 +261,20 @@ static void rt2800pci_stop_queue(struct data_queue *queue) | |||
| 261 | 261 | ||
| 262 | switch (queue->qid) { | 262 | switch (queue->qid) { |
| 263 | case QID_RX: | 263 | case QID_RX: |
| 264 | rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 264 | rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
| 265 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); | 265 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); |
| 266 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 266 | rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
| 267 | break; | 267 | break; |
| 268 | case QID_BEACON: | 268 | case QID_BEACON: |
| 269 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 269 | rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
| 270 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); | 270 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); |
| 271 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | 271 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); |
| 272 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 272 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); |
| 273 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 273 | rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
| 274 | 274 | ||
| 275 | rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); | 275 | rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); |
| 276 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); | 276 | rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); |
| 277 | rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); | 277 | rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); |
| 278 | 278 | ||
| 279 | /* | 279 | /* |
| 280 | * Wait for current invocation to finish. The tasklet | 280 | * Wait for current invocation to finish. The tasklet |
| @@ -314,19 +314,19 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 314 | */ | 314 | */ |
| 315 | reg = 0; | 315 | reg = 0; |
| 316 | rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); | 316 | rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); |
| 317 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg); | 317 | rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg); |
| 318 | 318 | ||
| 319 | /* | 319 | /* |
| 320 | * Write firmware to device. | 320 | * Write firmware to device. |
| 321 | */ | 321 | */ |
| 322 | rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 322 | rt2x00mmio_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
| 323 | data, len); | 323 | data, len); |
| 324 | 324 | ||
| 325 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); | 325 | rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); |
| 326 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); | 326 | rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); |
| 327 | 327 | ||
| 328 | rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | 328 | rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0); |
| 329 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 329 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
| 330 | 330 | ||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| @@ -336,7 +336,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 336 | */ | 336 | */ |
| 337 | static bool rt2800pci_get_entry_state(struct queue_entry *entry) | 337 | static bool rt2800pci_get_entry_state(struct queue_entry *entry) |
| 338 | { | 338 | { |
| 339 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 339 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 340 | u32 word; | 340 | u32 word; |
| 341 | 341 | ||
| 342 | if (entry->queue->qid == QID_RX) { | 342 | if (entry->queue->qid == QID_RX) { |
| @@ -352,7 +352,7 @@ static bool rt2800pci_get_entry_state(struct queue_entry *entry) | |||
| 352 | 352 | ||
| 353 | static void rt2800pci_clear_entry(struct queue_entry *entry) | 353 | static void rt2800pci_clear_entry(struct queue_entry *entry) |
| 354 | { | 354 | { |
| 355 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 355 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 356 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 356 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 357 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 357 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| 358 | u32 word; | 358 | u32 word; |
| @@ -370,8 +370,8 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) | |||
| 370 | * Set RX IDX in register to inform hardware that we have | 370 | * Set RX IDX in register to inform hardware that we have |
| 371 | * handled this entry and it is available for reuse again. | 371 | * handled this entry and it is available for reuse again. |
| 372 | */ | 372 | */ |
| 373 | rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, | 373 | rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, |
| 374 | entry->entry_idx); | 374 | entry->entry_idx); |
| 375 | } else { | 375 | } else { |
| 376 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 376 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
| 377 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); | 377 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); |
| @@ -381,60 +381,65 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) | |||
| 381 | 381 | ||
| 382 | static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) | 382 | static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) |
| 383 | { | 383 | { |
| 384 | struct queue_entry_priv_pci *entry_priv; | 384 | struct queue_entry_priv_mmio *entry_priv; |
| 385 | 385 | ||
| 386 | /* | 386 | /* |
| 387 | * Initialize registers. | 387 | * Initialize registers. |
| 388 | */ | 388 | */ |
| 389 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; | 389 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
| 390 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); | 390 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, |
| 391 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0, | 391 | entry_priv->desc_dma); |
| 392 | rt2x00dev->tx[0].limit); | 392 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, |
| 393 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0); | 393 | rt2x00dev->tx[0].limit); |
| 394 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0); | 394 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); |
| 395 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); | ||
| 395 | 396 | ||
| 396 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; | 397 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
| 397 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); | 398 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, |
| 398 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1, | 399 | entry_priv->desc_dma); |
| 399 | rt2x00dev->tx[1].limit); | 400 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, |
| 400 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0); | 401 | rt2x00dev->tx[1].limit); |
| 401 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0); | 402 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); |
| 403 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); | ||
| 402 | 404 | ||
| 403 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; | 405 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; |
| 404 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); | 406 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, |
| 405 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2, | 407 | entry_priv->desc_dma); |
| 406 | rt2x00dev->tx[2].limit); | 408 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, |
| 407 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0); | 409 | rt2x00dev->tx[2].limit); |
| 408 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0); | 410 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); |
| 411 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); | ||
| 409 | 412 | ||
| 410 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; | 413 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; |
| 411 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); | 414 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, |
| 412 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3, | 415 | entry_priv->desc_dma); |
| 413 | rt2x00dev->tx[3].limit); | 416 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, |
| 414 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0); | 417 | rt2x00dev->tx[3].limit); |
| 415 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0); | 418 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); |
| 416 | 419 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); | |
| 417 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR4, 0); | 420 | |
| 418 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT4, 0); | 421 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); |
| 419 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX4, 0); | 422 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); |
| 420 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX4, 0); | 423 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0); |
| 421 | 424 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0); | |
| 422 | rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR5, 0); | 425 | |
| 423 | rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT5, 0); | 426 | rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0); |
| 424 | rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX5, 0); | 427 | rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0); |
| 425 | rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX5, 0); | 428 | rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0); |
| 429 | rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0); | ||
| 426 | 430 | ||
| 427 | entry_priv = rt2x00dev->rx->entries[0].priv_data; | 431 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
| 428 | rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); | 432 | rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR, |
| 429 | rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, | 433 | entry_priv->desc_dma); |
| 430 | rt2x00dev->rx[0].limit); | 434 | rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT, |
| 431 | rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, | 435 | rt2x00dev->rx[0].limit); |
| 432 | rt2x00dev->rx[0].limit - 1); | 436 | rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, |
| 433 | rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0); | 437 | rt2x00dev->rx[0].limit - 1); |
| 438 | rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0); | ||
| 434 | 439 | ||
| 435 | rt2800_disable_wpdma(rt2x00dev); | 440 | rt2800_disable_wpdma(rt2x00dev); |
| 436 | 441 | ||
| 437 | rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0); | 442 | rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0); |
| 438 | 443 | ||
| 439 | return 0; | 444 | return 0; |
| 440 | } | 445 | } |
| @@ -453,8 +458,8 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 453 | * should clear the register to assure a clean state. | 458 | * should clear the register to assure a clean state. |
| 454 | */ | 459 | */ |
| 455 | if (state == STATE_RADIO_IRQ_ON) { | 460 | if (state == STATE_RADIO_IRQ_ON) { |
| 456 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 461 | rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
| 457 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 462 | rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
| 458 | } | 463 | } |
| 459 | 464 | ||
| 460 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 465 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); |
| @@ -466,7 +471,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 466 | rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); | 471 | rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); |
| 467 | rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); | 472 | rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); |
| 468 | } | 473 | } |
| 469 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 474 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 470 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 475 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); |
| 471 | 476 | ||
| 472 | if (state == STATE_RADIO_IRQ_OFF) { | 477 | if (state == STATE_RADIO_IRQ_OFF) { |
| @@ -488,7 +493,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 488 | /* | 493 | /* |
| 489 | * Reset DMA indexes | 494 | * Reset DMA indexes |
| 490 | */ | 495 | */ |
| 491 | rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | 496 | rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, ®); |
| 492 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); | 497 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); |
| 493 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); | 498 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); |
| 494 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); | 499 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); |
| @@ -496,29 +501,29 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 496 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); | 501 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); |
| 497 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); | 502 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); |
| 498 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); | 503 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); |
| 499 | rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | 504 | rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); |
| 500 | 505 | ||
| 501 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 506 | rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
| 502 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 507 | rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
| 503 | 508 | ||
| 504 | if (rt2x00_is_pcie(rt2x00dev) && | 509 | if (rt2x00_is_pcie(rt2x00dev) && |
| 505 | (rt2x00_rt(rt2x00dev, RT3572) || | 510 | (rt2x00_rt(rt2x00dev, RT3572) || |
| 506 | rt2x00_rt(rt2x00dev, RT5390) || | 511 | rt2x00_rt(rt2x00dev, RT5390) || |
| 507 | rt2x00_rt(rt2x00dev, RT5392))) { | 512 | rt2x00_rt(rt2x00dev, RT5392))) { |
| 508 | rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); | 513 | rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, ®); |
| 509 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 514 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
| 510 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 515 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
| 511 | rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg); | 516 | rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg); |
| 512 | } | 517 | } |
| 513 | 518 | ||
| 514 | rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | 519 | rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); |
| 515 | 520 | ||
| 516 | reg = 0; | 521 | reg = 0; |
| 517 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | 522 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); |
| 518 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | 523 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); |
| 519 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 524 | rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
| 520 | 525 | ||
| 521 | rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | 526 | rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); |
| 522 | 527 | ||
| 523 | return 0; | 528 | return 0; |
| 524 | } | 529 | } |
| @@ -538,8 +543,8 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 538 | return retval; | 543 | return retval; |
| 539 | 544 | ||
| 540 | /* After resume MCU_BOOT_SIGNAL will trash these. */ | 545 | /* After resume MCU_BOOT_SIGNAL will trash these. */ |
| 541 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 546 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
| 542 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 547 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
| 543 | 548 | ||
| 544 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); | 549 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); |
| 545 | rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); | 550 | rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); |
| @@ -554,8 +559,8 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 554 | { | 559 | { |
| 555 | if (rt2x00_is_soc(rt2x00dev)) { | 560 | if (rt2x00_is_soc(rt2x00dev)) { |
| 556 | rt2800_disable_radio(rt2x00dev); | 561 | rt2800_disable_radio(rt2x00dev); |
| 557 | rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0); | 562 | rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); |
| 558 | rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0); | 563 | rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); |
| 559 | } | 564 | } |
| 560 | } | 565 | } |
| 561 | 566 | ||
| @@ -567,10 +572,10 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
| 567 | 0, 0x02); | 572 | 0, 0x02); |
| 568 | rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); | 573 | rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); |
| 569 | } else if (state == STATE_SLEEP) { | 574 | } else if (state == STATE_SLEEP) { |
| 570 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, | 575 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, |
| 571 | 0xffffffff); | 576 | 0xffffffff); |
| 572 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, | 577 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, |
| 573 | 0xffffffff); | 578 | 0xffffffff); |
| 574 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, | 579 | rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, |
| 575 | 0xff, 0x01); | 580 | 0xff, 0x01); |
| 576 | } | 581 | } |
| @@ -611,8 +616,8 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 611 | } | 616 | } |
| 612 | 617 | ||
| 613 | if (unlikely(retval)) | 618 | if (unlikely(retval)) |
| 614 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 619 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 615 | state, retval); | 620 | state, retval); |
| 616 | 621 | ||
| 617 | return retval; | 622 | return retval; |
| 618 | } | 623 | } |
| @@ -629,7 +634,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, | |||
| 629 | struct txentry_desc *txdesc) | 634 | struct txentry_desc *txdesc) |
| 630 | { | 635 | { |
| 631 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 636 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 632 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 637 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 633 | __le32 *txd = entry_priv->desc; | 638 | __le32 *txd = entry_priv->desc; |
| 634 | u32 word; | 639 | u32 word; |
| 635 | 640 | ||
| @@ -683,7 +688,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, | |||
| 683 | static void rt2800pci_fill_rxdone(struct queue_entry *entry, | 688 | static void rt2800pci_fill_rxdone(struct queue_entry *entry, |
| 684 | struct rxdone_entry_desc *rxdesc) | 689 | struct rxdone_entry_desc *rxdesc) |
| 685 | { | 690 | { |
| 686 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 691 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 687 | __le32 *rxd = entry_priv->desc; | 692 | __le32 *rxd = entry_priv->desc; |
| 688 | u32 word; | 693 | u32 word; |
| 689 | 694 | ||
| @@ -730,11 +735,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
| 730 | * Process the RXWI structure that is at the start of the buffer. | 735 | * Process the RXWI structure that is at the start of the buffer. |
| 731 | */ | 736 | */ |
| 732 | rt2800_process_rxwi(entry, rxdesc); | 737 | rt2800_process_rxwi(entry, rxdesc); |
| 733 | |||
| 734 | /* | ||
| 735 | * Remove RXWI descriptor from start of buffer. | ||
| 736 | */ | ||
| 737 | skb_pull(entry->skb, RXWI_DESC_SIZE); | ||
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | /* | 740 | /* |
| @@ -843,8 +843,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 843 | * Unknown queue, this shouldn't happen. Just drop | 843 | * Unknown queue, this shouldn't happen. Just drop |
| 844 | * this tx status. | 844 | * this tx status. |
| 845 | */ | 845 | */ |
| 846 | WARNING(rt2x00dev, "Got TX status report with " | 846 | rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", |
| 847 | "unexpected pid %u, dropping\n", qid); | 847 | qid); |
| 848 | break; | 848 | break; |
| 849 | } | 849 | } |
| 850 | 850 | ||
| @@ -854,8 +854,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 854 | * The queue is NULL, this shouldn't happen. Stop | 854 | * The queue is NULL, this shouldn't happen. Stop |
| 855 | * processing here and drop the tx status | 855 | * processing here and drop the tx status |
| 856 | */ | 856 | */ |
| 857 | WARNING(rt2x00dev, "Got TX status for an unavailable " | 857 | rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", |
| 858 | "queue %u, dropping\n", qid); | 858 | qid); |
| 859 | break; | 859 | break; |
| 860 | } | 860 | } |
| 861 | 861 | ||
| @@ -864,8 +864,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 864 | * The queue is empty. Stop processing here | 864 | * The queue is empty. Stop processing here |
| 865 | * and drop the tx status. | 865 | * and drop the tx status. |
| 866 | */ | 866 | */ |
| 867 | WARNING(rt2x00dev, "Got TX status for an empty " | 867 | rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", |
| 868 | "queue %u, dropping\n", qid); | 868 | qid); |
| 869 | break; | 869 | break; |
| 870 | } | 870 | } |
| 871 | 871 | ||
| @@ -883,9 +883,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 883 | if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, | 883 | if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, |
| 884 | Q_INDEX, &status, | 884 | Q_INDEX, &status, |
| 885 | rt2800pci_txdone_match_first)) { | 885 | rt2800pci_txdone_match_first)) { |
| 886 | WARNING(rt2x00dev, "No frame found for TX " | 886 | rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", |
| 887 | "status on queue %u, dropping\n", | 887 | qid); |
| 888 | qid); | ||
| 889 | break; | 888 | break; |
| 890 | } | 889 | } |
| 891 | } | 890 | } |
| @@ -914,9 +913,9 @@ static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | |||
| 914 | * access needs locking. | 913 | * access needs locking. |
| 915 | */ | 914 | */ |
| 916 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 915 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 917 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 916 | rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); |
| 918 | rt2x00_set_field32(®, irq_field, 1); | 917 | rt2x00_set_field32(®, irq_field, 1); |
| 919 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 918 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 920 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 919 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 921 | } | 920 | } |
| 922 | 921 | ||
| @@ -957,15 +956,15 @@ static void rt2800pci_tbtt_tasklet(unsigned long data) | |||
| 957 | * interval every 64 beacons by 64us to mitigate this effect. | 956 | * interval every 64 beacons by 64us to mitigate this effect. |
| 958 | */ | 957 | */ |
| 959 | if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { | 958 | if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { |
| 960 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 959 | rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
| 961 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | 960 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, |
| 962 | (rt2x00dev->beacon_int * 16) - 1); | 961 | (rt2x00dev->beacon_int * 16) - 1); |
| 963 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 962 | rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
| 964 | } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { | 963 | } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { |
| 965 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 964 | rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
| 966 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | 965 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, |
| 967 | (rt2x00dev->beacon_int * 16)); | 966 | (rt2x00dev->beacon_int * 16)); |
| 968 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 967 | rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
| 969 | } | 968 | } |
| 970 | drv_data->tbtt_tick++; | 969 | drv_data->tbtt_tick++; |
| 971 | drv_data->tbtt_tick %= BCN_TBTT_OFFSET; | 970 | drv_data->tbtt_tick %= BCN_TBTT_OFFSET; |
| @@ -978,7 +977,7 @@ static void rt2800pci_tbtt_tasklet(unsigned long data) | |||
| 978 | static void rt2800pci_rxdone_tasklet(unsigned long data) | 977 | static void rt2800pci_rxdone_tasklet(unsigned long data) |
| 979 | { | 978 | { |
| 980 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 979 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
| 981 | if (rt2x00pci_rxdone(rt2x00dev)) | 980 | if (rt2x00mmio_rxdone(rt2x00dev)) |
| 982 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); | 981 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); |
| 983 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 982 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 984 | rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); | 983 | rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); |
| @@ -1016,14 +1015,13 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) | |||
| 1016 | * need to lock the kfifo. | 1015 | * need to lock the kfifo. |
| 1017 | */ | 1016 | */ |
| 1018 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { | 1017 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { |
| 1019 | rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status); | 1018 | rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); |
| 1020 | 1019 | ||
| 1021 | if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) | 1020 | if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) |
| 1022 | break; | 1021 | break; |
| 1023 | 1022 | ||
| 1024 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { | 1023 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { |
| 1025 | WARNING(rt2x00dev, "TX status FIFO overrun," | 1024 | rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); |
| 1026 | "drop tx status report.\n"); | ||
| 1027 | break; | 1025 | break; |
| 1028 | } | 1026 | } |
| 1029 | } | 1027 | } |
| @@ -1038,8 +1036,8 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
| 1038 | u32 reg, mask; | 1036 | u32 reg, mask; |
| 1039 | 1037 | ||
| 1040 | /* Read status and ACK all interrupts */ | 1038 | /* Read status and ACK all interrupts */ |
| 1041 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 1039 | rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
| 1042 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 1040 | rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
| 1043 | 1041 | ||
| 1044 | if (!reg) | 1042 | if (!reg) |
| 1045 | return IRQ_NONE; | 1043 | return IRQ_NONE; |
| @@ -1079,9 +1077,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
| 1079 | * the tasklet will reenable the appropriate interrupts. | 1077 | * the tasklet will reenable the appropriate interrupts. |
| 1080 | */ | 1078 | */ |
| 1081 | spin_lock(&rt2x00dev->irqmask_lock); | 1079 | spin_lock(&rt2x00dev->irqmask_lock); |
| 1082 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 1080 | rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); |
| 1083 | reg &= mask; | 1081 | reg &= mask; |
| 1084 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 1082 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 1085 | spin_unlock(&rt2x00dev->irqmask_lock); | 1083 | spin_unlock(&rt2x00dev->irqmask_lock); |
| 1086 | 1084 | ||
| 1087 | return IRQ_HANDLED; | 1085 | return IRQ_HANDLED; |
| @@ -1132,13 +1130,13 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { | |||
| 1132 | }; | 1130 | }; |
| 1133 | 1131 | ||
| 1134 | static const struct rt2800_ops rt2800pci_rt2800_ops = { | 1132 | static const struct rt2800_ops rt2800pci_rt2800_ops = { |
| 1135 | .register_read = rt2x00pci_register_read, | 1133 | .register_read = rt2x00mmio_register_read, |
| 1136 | .register_read_lock = rt2x00pci_register_read, /* same for PCI */ | 1134 | .register_read_lock = rt2x00mmio_register_read, /* same for PCI */ |
| 1137 | .register_write = rt2x00pci_register_write, | 1135 | .register_write = rt2x00mmio_register_write, |
| 1138 | .register_write_lock = rt2x00pci_register_write, /* same for PCI */ | 1136 | .register_write_lock = rt2x00mmio_register_write, /* same for PCI */ |
| 1139 | .register_multiread = rt2x00pci_register_multiread, | 1137 | .register_multiread = rt2x00mmio_register_multiread, |
| 1140 | .register_multiwrite = rt2x00pci_register_multiwrite, | 1138 | .register_multiwrite = rt2x00mmio_register_multiwrite, |
| 1141 | .regbusy_read = rt2x00pci_regbusy_read, | 1139 | .regbusy_read = rt2x00mmio_regbusy_read, |
| 1142 | .read_eeprom = rt2800pci_read_eeprom, | 1140 | .read_eeprom = rt2800pci_read_eeprom, |
| 1143 | .hwcrypt_disabled = rt2800pci_hwcrypt_disabled, | 1141 | .hwcrypt_disabled = rt2800pci_hwcrypt_disabled, |
| 1144 | .drv_write_firmware = rt2800pci_write_firmware, | 1142 | .drv_write_firmware = rt2800pci_write_firmware, |
| @@ -1157,8 +1155,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
| 1157 | .get_firmware_name = rt2800pci_get_firmware_name, | 1155 | .get_firmware_name = rt2800pci_get_firmware_name, |
| 1158 | .check_firmware = rt2800_check_firmware, | 1156 | .check_firmware = rt2800_check_firmware, |
| 1159 | .load_firmware = rt2800_load_firmware, | 1157 | .load_firmware = rt2800_load_firmware, |
| 1160 | .initialize = rt2x00pci_initialize, | 1158 | .initialize = rt2x00mmio_initialize, |
| 1161 | .uninitialize = rt2x00pci_uninitialize, | 1159 | .uninitialize = rt2x00mmio_uninitialize, |
| 1162 | .get_entry_state = rt2800pci_get_entry_state, | 1160 | .get_entry_state = rt2800pci_get_entry_state, |
| 1163 | .clear_entry = rt2800pci_clear_entry, | 1161 | .clear_entry = rt2800pci_clear_entry, |
| 1164 | .set_device_state = rt2800pci_set_device_state, | 1162 | .set_device_state = rt2800pci_set_device_state, |
| @@ -1171,7 +1169,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
| 1171 | .start_queue = rt2800pci_start_queue, | 1169 | .start_queue = rt2800pci_start_queue, |
| 1172 | .kick_queue = rt2800pci_kick_queue, | 1170 | .kick_queue = rt2800pci_kick_queue, |
| 1173 | .stop_queue = rt2800pci_stop_queue, | 1171 | .stop_queue = rt2800pci_stop_queue, |
| 1174 | .flush_queue = rt2x00pci_flush_queue, | 1172 | .flush_queue = rt2x00mmio_flush_queue, |
| 1175 | .write_tx_desc = rt2800pci_write_tx_desc, | 1173 | .write_tx_desc = rt2800pci_write_tx_desc, |
| 1176 | .write_tx_data = rt2800_write_tx_data, | 1174 | .write_tx_data = rt2800_write_tx_data, |
| 1177 | .write_beacon = rt2800_write_beacon, | 1175 | .write_beacon = rt2800_write_beacon, |
| @@ -1192,21 +1190,24 @@ static const struct data_queue_desc rt2800pci_queue_rx = { | |||
| 1192 | .entry_num = 128, | 1190 | .entry_num = 128, |
| 1193 | .data_size = AGGREGATION_SIZE, | 1191 | .data_size = AGGREGATION_SIZE, |
| 1194 | .desc_size = RXD_DESC_SIZE, | 1192 | .desc_size = RXD_DESC_SIZE, |
| 1195 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1193 | .winfo_size = RXWI_DESC_SIZE, |
| 1194 | .priv_size = sizeof(struct queue_entry_priv_mmio), | ||
| 1196 | }; | 1195 | }; |
| 1197 | 1196 | ||
| 1198 | static const struct data_queue_desc rt2800pci_queue_tx = { | 1197 | static const struct data_queue_desc rt2800pci_queue_tx = { |
| 1199 | .entry_num = 64, | 1198 | .entry_num = 64, |
| 1200 | .data_size = AGGREGATION_SIZE, | 1199 | .data_size = AGGREGATION_SIZE, |
| 1201 | .desc_size = TXD_DESC_SIZE, | 1200 | .desc_size = TXD_DESC_SIZE, |
| 1202 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1201 | .winfo_size = TXWI_DESC_SIZE, |
| 1202 | .priv_size = sizeof(struct queue_entry_priv_mmio), | ||
| 1203 | }; | 1203 | }; |
| 1204 | 1204 | ||
| 1205 | static const struct data_queue_desc rt2800pci_queue_bcn = { | 1205 | static const struct data_queue_desc rt2800pci_queue_bcn = { |
| 1206 | .entry_num = 8, | 1206 | .entry_num = 8, |
| 1207 | .data_size = 0, /* No DMA required for beacons */ | 1207 | .data_size = 0, /* No DMA required for beacons */ |
| 1208 | .desc_size = TXWI_DESC_SIZE, | 1208 | .desc_size = TXD_DESC_SIZE, |
| 1209 | .priv_size = sizeof(struct queue_entry_priv_pci), | 1209 | .winfo_size = TXWI_DESC_SIZE, |
| 1210 | .priv_size = sizeof(struct queue_entry_priv_mmio), | ||
| 1210 | }; | 1211 | }; |
| 1211 | 1212 | ||
| 1212 | static const struct rt2x00_ops rt2800pci_ops = { | 1213 | static const struct rt2x00_ops rt2800pci_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f32282009146..ac854d75bd6c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -128,9 +128,9 @@ static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) | |||
| 128 | 128 | ||
| 129 | tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); | 129 | tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); |
| 130 | if (unlikely(tout)) | 130 | if (unlikely(tout)) |
| 131 | WARNING(entry->queue->rt2x00dev, | 131 | rt2x00_warn(entry->queue->rt2x00dev, |
| 132 | "TX status timeout for entry %d in queue %d\n", | 132 | "TX status timeout for entry %d in queue %d\n", |
| 133 | entry->entry_idx, entry->queue->qid); | 133 | entry->entry_idx, entry->queue->qid); |
| 134 | return tout; | 134 | return tout; |
| 135 | 135 | ||
| 136 | } | 136 | } |
| @@ -154,7 +154,8 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | |||
| 154 | bool valid; | 154 | bool valid; |
| 155 | 155 | ||
| 156 | if (urb_status) { | 156 | if (urb_status) { |
| 157 | WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); | 157 | rt2x00_warn(rt2x00dev, "TX status read failed %d\n", |
| 158 | urb_status); | ||
| 158 | 159 | ||
| 159 | goto stop_reading; | 160 | goto stop_reading; |
| 160 | } | 161 | } |
| @@ -162,7 +163,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | |||
| 162 | valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); | 163 | valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); |
| 163 | if (valid) { | 164 | if (valid) { |
| 164 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) | 165 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) |
| 165 | WARNING(rt2x00dev, "TX status FIFO overrun\n"); | 166 | rt2x00_warn(rt2x00dev, "TX status FIFO overrun\n"); |
| 166 | 167 | ||
| 167 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 168 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
| 168 | 169 | ||
| @@ -269,7 +270,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 269 | 0, USB_MODE_FIRMWARE, | 270 | 0, USB_MODE_FIRMWARE, |
| 270 | REGISTER_TIMEOUT_FIRMWARE); | 271 | REGISTER_TIMEOUT_FIRMWARE); |
| 271 | if (status < 0) { | 272 | if (status < 0) { |
| 272 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 273 | rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n"); |
| 273 | return status; | 274 | return status; |
| 274 | } | 275 | } |
| 275 | 276 | ||
| @@ -392,8 +393,8 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 392 | } | 393 | } |
| 393 | 394 | ||
| 394 | if (unlikely(retval)) | 395 | if (unlikely(retval)) |
| 395 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 396 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 396 | state, retval); | 397 | state, retval); |
| 397 | 398 | ||
| 398 | return retval; | 399 | return retval; |
| 399 | } | 400 | } |
| @@ -408,8 +409,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
| 408 | 409 | ||
| 409 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); | 410 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
| 410 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { | 411 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { |
| 411 | WARNING(rt2x00dev, "TX HW queue 0 timed out," | 412 | rt2x00_warn(rt2x00dev, "TX HW queue 0 timed out, invoke forced kick\n"); |
| 412 | " invoke forced kick\n"); | ||
| 413 | 413 | ||
| 414 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); | 414 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); |
| 415 | 415 | ||
| @@ -424,8 +424,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
| 424 | 424 | ||
| 425 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); | 425 | rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
| 426 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { | 426 | if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { |
| 427 | WARNING(rt2x00dev, "TX HW queue 1 timed out," | 427 | rt2x00_warn(rt2x00dev, "TX HW queue 1 timed out, invoke forced kick\n"); |
| 428 | " invoke forced kick\n"); | ||
| 429 | 428 | ||
| 430 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); | 429 | rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); |
| 431 | 430 | ||
| @@ -485,7 +484,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, | |||
| 485 | */ | 484 | */ |
| 486 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | 485 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; |
| 487 | skbdesc->desc = txi; | 486 | skbdesc->desc = txi; |
| 488 | skbdesc->desc_len = entry->queue->desc_size; | 487 | skbdesc->desc_len = TXINFO_DESC_SIZE + entry->queue->winfo_size; |
| 489 | } | 488 | } |
| 490 | 489 | ||
| 491 | /* | 490 | /* |
| @@ -540,9 +539,9 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) | |||
| 540 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | 539 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); |
| 541 | 540 | ||
| 542 | if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { | 541 | if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { |
| 543 | DEBUG(entry->queue->rt2x00dev, | 542 | rt2x00_dbg(entry->queue->rt2x00dev, |
| 544 | "TX status report missed for queue %d entry %d\n", | 543 | "TX status report missed for queue %d entry %d\n", |
| 545 | entry->queue->qid, entry->entry_idx); | 544 | entry->queue->qid, entry->entry_idx); |
| 546 | return TXDONE_UNKNOWN; | 545 | return TXDONE_UNKNOWN; |
| 547 | } | 546 | } |
| 548 | 547 | ||
| @@ -566,8 +565,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 566 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | 565 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
| 567 | 566 | ||
| 568 | if (unlikely(rt2x00queue_empty(queue))) { | 567 | if (unlikely(rt2x00queue_empty(queue))) { |
| 569 | WARNING(rt2x00dev, "Got TX status for an empty " | 568 | rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", |
| 570 | "queue %u, dropping\n", qid); | 569 | qid); |
| 571 | break; | 570 | break; |
| 572 | } | 571 | } |
| 573 | 572 | ||
| @@ -575,8 +574,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 575 | 574 | ||
| 576 | if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | 575 | if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
| 577 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { | 576 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { |
| 578 | WARNING(rt2x00dev, "Data pending for entry %u " | 577 | rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", |
| 579 | "in queue %u\n", entry->entry_idx, qid); | 578 | entry->entry_idx, qid); |
| 580 | break; | 579 | break; |
| 581 | } | 580 | } |
| 582 | 581 | ||
| @@ -677,8 +676,8 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
| 677 | */ | 676 | */ |
| 678 | if (unlikely(rx_pkt_len == 0 || | 677 | if (unlikely(rx_pkt_len == 0 || |
| 679 | rx_pkt_len > entry->queue->data_size)) { | 678 | rx_pkt_len > entry->queue->data_size)) { |
| 680 | ERROR(entry->queue->rt2x00dev, | 679 | rt2x00_err(entry->queue->rt2x00dev, |
| 681 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); | 680 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); |
| 682 | return; | 681 | return; |
| 683 | } | 682 | } |
| 684 | 683 | ||
| @@ -730,11 +729,6 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
| 730 | * Process the RXWI structure. | 729 | * Process the RXWI structure. |
| 731 | */ | 730 | */ |
| 732 | rt2800_process_rxwi(entry, rxdesc); | 731 | rt2800_process_rxwi(entry, rxdesc); |
| 733 | |||
| 734 | /* | ||
| 735 | * Remove RXWI descriptor from start of buffer. | ||
| 736 | */ | ||
| 737 | skb_pull(entry->skb, entry->queue->desc_size - RXINFO_DESC_SIZE); | ||
| 738 | } | 732 | } |
| 739 | 733 | ||
| 740 | /* | 734 | /* |
| @@ -858,21 +852,24 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
| 858 | static const struct data_queue_desc rt2800usb_queue_rx = { | 852 | static const struct data_queue_desc rt2800usb_queue_rx = { |
| 859 | .entry_num = 128, | 853 | .entry_num = 128, |
| 860 | .data_size = AGGREGATION_SIZE, | 854 | .data_size = AGGREGATION_SIZE, |
| 861 | .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE, | 855 | .desc_size = RXINFO_DESC_SIZE, |
| 856 | .winfo_size = RXWI_DESC_SIZE, | ||
| 862 | .priv_size = sizeof(struct queue_entry_priv_usb), | 857 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 863 | }; | 858 | }; |
| 864 | 859 | ||
| 865 | static const struct data_queue_desc rt2800usb_queue_tx = { | 860 | static const struct data_queue_desc rt2800usb_queue_tx = { |
| 866 | .entry_num = 16, | 861 | .entry_num = 16, |
| 867 | .data_size = AGGREGATION_SIZE, | 862 | .data_size = AGGREGATION_SIZE, |
| 868 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, | 863 | .desc_size = TXINFO_DESC_SIZE, |
| 864 | .winfo_size = TXWI_DESC_SIZE, | ||
| 869 | .priv_size = sizeof(struct queue_entry_priv_usb), | 865 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 870 | }; | 866 | }; |
| 871 | 867 | ||
| 872 | static const struct data_queue_desc rt2800usb_queue_bcn = { | 868 | static const struct data_queue_desc rt2800usb_queue_bcn = { |
| 873 | .entry_num = 8, | 869 | .entry_num = 8, |
| 874 | .data_size = MGMT_FRAME_SIZE, | 870 | .data_size = MGMT_FRAME_SIZE, |
| 875 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, | 871 | .desc_size = TXINFO_DESC_SIZE, |
| 872 | .winfo_size = TXWI_DESC_SIZE, | ||
| 876 | .priv_size = sizeof(struct queue_entry_priv_usb), | 873 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 877 | }; | 874 | }; |
| 878 | 875 | ||
| @@ -898,21 +895,24 @@ static const struct rt2x00_ops rt2800usb_ops = { | |||
| 898 | static const struct data_queue_desc rt2800usb_queue_rx_5592 = { | 895 | static const struct data_queue_desc rt2800usb_queue_rx_5592 = { |
| 899 | .entry_num = 128, | 896 | .entry_num = 128, |
| 900 | .data_size = AGGREGATION_SIZE, | 897 | .data_size = AGGREGATION_SIZE, |
| 901 | .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE_5592, | 898 | .desc_size = RXINFO_DESC_SIZE, |
| 899 | .winfo_size = RXWI_DESC_SIZE_5592, | ||
| 902 | .priv_size = sizeof(struct queue_entry_priv_usb), | 900 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 903 | }; | 901 | }; |
| 904 | 902 | ||
| 905 | static const struct data_queue_desc rt2800usb_queue_tx_5592 = { | 903 | static const struct data_queue_desc rt2800usb_queue_tx_5592 = { |
| 906 | .entry_num = 16, | 904 | .entry_num = 16, |
| 907 | .data_size = AGGREGATION_SIZE, | 905 | .data_size = AGGREGATION_SIZE, |
| 908 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, | 906 | .desc_size = TXINFO_DESC_SIZE, |
| 907 | .winfo_size = TXWI_DESC_SIZE_5592, | ||
| 909 | .priv_size = sizeof(struct queue_entry_priv_usb), | 908 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 910 | }; | 909 | }; |
| 911 | 910 | ||
| 912 | static const struct data_queue_desc rt2800usb_queue_bcn_5592 = { | 911 | static const struct data_queue_desc rt2800usb_queue_bcn_5592 = { |
| 913 | .entry_num = 8, | 912 | .entry_num = 8, |
| 914 | .data_size = MGMT_FRAME_SIZE, | 913 | .data_size = MGMT_FRAME_SIZE, |
| 915 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, | 914 | .desc_size = TXINFO_DESC_SIZE, |
| 915 | .winfo_size = TXWI_DESC_SIZE_5592, | ||
| 916 | .priv_size = sizeof(struct queue_entry_priv_usb), | 916 | .priv_size = sizeof(struct queue_entry_priv_usb), |
| 917 | }; | 917 | }; |
| 918 | 918 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0d02d16ca166..7510723a8c37 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
| @@ -54,47 +54,36 @@ | |||
| 54 | #define DRV_VERSION "2.3.0" | 54 | #define DRV_VERSION "2.3.0" |
| 55 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 55 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
| 56 | 56 | ||
| 57 | /* | 57 | /* Debug definitions. |
| 58 | * Debug definitions. | ||
| 59 | * Debug output has to be enabled during compile time. | 58 | * Debug output has to be enabled during compile time. |
| 60 | */ | 59 | */ |
| 61 | #define DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, __args...) \ | ||
| 62 | printk(__kernlvl "%s -> %s: %s - " __msg, \ | ||
| 63 | wiphy_name((__dev)->hw->wiphy), __func__, __lvl, ##__args) | ||
| 64 | |||
| 65 | #define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ | ||
| 66 | printk(__kernlvl "%s -> %s: %s - " __msg, \ | ||
| 67 | KBUILD_MODNAME, __func__, __lvl, ##__args) | ||
| 68 | |||
| 69 | #ifdef CONFIG_RT2X00_DEBUG | 60 | #ifdef CONFIG_RT2X00_DEBUG |
| 70 | #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ | 61 | #define DEBUG |
| 71 | DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args) | ||
| 72 | #else | ||
| 73 | #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ | ||
| 74 | do { } while (0) | ||
| 75 | #endif /* CONFIG_RT2X00_DEBUG */ | 62 | #endif /* CONFIG_RT2X00_DEBUG */ |
| 76 | 63 | ||
| 77 | /* | 64 | /* Utility printing macros |
| 78 | * Various debug levels. | 65 | * rt2x00_probe_err is for messages when rt2x00_dev is uninitialized |
| 79 | * The debug levels PANIC and ERROR both indicate serious problems, | ||
| 80 | * for this reason they should never be ignored. | ||
| 81 | * The special ERROR_PROBE message is for messages that are generated | ||
| 82 | * when the rt2x00_dev is not yet initialized. | ||
| 83 | */ | 66 | */ |
| 84 | #define PANIC(__dev, __msg, __args...) \ | 67 | #define rt2x00_probe_err(fmt, ...) \ |
| 85 | DEBUG_PRINTK_MSG(__dev, KERN_CRIT, "Panic", __msg, ##__args) | 68 | printk(KERN_ERR KBUILD_MODNAME ": %s: Error - " fmt, \ |
| 86 | #define ERROR(__dev, __msg, __args...) \ | 69 | __func__, ##__VA_ARGS__) |
| 87 | DEBUG_PRINTK_MSG(__dev, KERN_ERR, "Error", __msg, ##__args) | 70 | #define rt2x00_err(dev, fmt, ...) \ |
| 88 | #define ERROR_PROBE(__msg, __args...) \ | 71 | wiphy_err((dev)->hw->wiphy, "%s: Error - " fmt, \ |
| 89 | DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args) | 72 | __func__, ##__VA_ARGS__) |
| 90 | #define WARNING(__dev, __msg, __args...) \ | 73 | #define rt2x00_warn(dev, fmt, ...) \ |
| 91 | DEBUG_PRINTK_MSG(__dev, KERN_WARNING, "Warning", __msg, ##__args) | 74 | wiphy_warn((dev)->hw->wiphy, "%s: Warning - " fmt, \ |
| 92 | #define INFO(__dev, __msg, __args...) \ | 75 | __func__, ##__VA_ARGS__) |
| 93 | DEBUG_PRINTK_MSG(__dev, KERN_INFO, "Info", __msg, ##__args) | 76 | #define rt2x00_info(dev, fmt, ...) \ |
| 94 | #define DEBUG(__dev, __msg, __args...) \ | 77 | wiphy_info((dev)->hw->wiphy, "%s: Info - " fmt, \ |
| 95 | DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args) | 78 | __func__, ##__VA_ARGS__) |
| 96 | #define EEPROM(__dev, __msg, __args...) \ | 79 | |
| 97 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) | 80 | /* Various debug levels */ |
| 81 | #define rt2x00_dbg(dev, fmt, ...) \ | ||
| 82 | wiphy_dbg((dev)->hw->wiphy, "%s: Debug - " fmt, \ | ||
| 83 | __func__, ##__VA_ARGS__) | ||
| 84 | #define rt2x00_eeprom_dbg(dev, fmt, ...) \ | ||
| 85 | wiphy_dbg((dev)->hw->wiphy, "%s: EEPROM recovery - " fmt, \ | ||
| 86 | __func__, ##__VA_ARGS__) | ||
| 98 | 87 | ||
| 99 | /* | 88 | /* |
| 100 | * Duration calculations | 89 | * Duration calculations |
| @@ -1101,9 +1090,9 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, | |||
| 1101 | rt2x00dev->chip.rf = rf; | 1090 | rt2x00dev->chip.rf = rf; |
| 1102 | rt2x00dev->chip.rev = rev; | 1091 | rt2x00dev->chip.rev = rev; |
| 1103 | 1092 | ||
| 1104 | INFO(rt2x00dev, | 1093 | rt2x00_info(rt2x00dev, "Chipset detected - rt: %04x, rf: %04x, rev: %04x\n", |
| 1105 | "Chipset detected - rt: %04x, rf: %04x, rev: %04x.\n", | 1094 | rt2x00dev->chip.rt, rt2x00dev->chip.rf, |
| 1106 | rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); | 1095 | rt2x00dev->chip.rev); |
| 1107 | } | 1096 | } |
| 1108 | 1097 | ||
| 1109 | static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, | 1098 | static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, |
| @@ -1112,15 +1101,16 @@ static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, | |||
| 1112 | rt2x00dev->chip.rt = rt; | 1101 | rt2x00dev->chip.rt = rt; |
| 1113 | rt2x00dev->chip.rev = rev; | 1102 | rt2x00dev->chip.rev = rev; |
| 1114 | 1103 | ||
| 1115 | INFO(rt2x00dev, "RT chipset %04x, rev %04x detected\n", | 1104 | rt2x00_info(rt2x00dev, "RT chipset %04x, rev %04x detected\n", |
| 1116 | rt2x00dev->chip.rt, rt2x00dev->chip.rev); | 1105 | rt2x00dev->chip.rt, rt2x00dev->chip.rev); |
| 1117 | } | 1106 | } |
| 1118 | 1107 | ||
| 1119 | static inline void rt2x00_set_rf(struct rt2x00_dev *rt2x00dev, const u16 rf) | 1108 | static inline void rt2x00_set_rf(struct rt2x00_dev *rt2x00dev, const u16 rf) |
| 1120 | { | 1109 | { |
| 1121 | rt2x00dev->chip.rf = rf; | 1110 | rt2x00dev->chip.rf = rf; |
| 1122 | 1111 | ||
| 1123 | INFO(rt2x00dev, "RF chipset %04x detected\n", rt2x00dev->chip.rf); | 1112 | rt2x00_info(rt2x00dev, "RF chipset %04x detected\n", |
| 1113 | rt2x00dev->chip.rf); | ||
| 1124 | } | 1114 | } |
| 1125 | 1115 | ||
| 1126 | static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt) | 1116 | static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 49a63e973934..8cb43f8f3efc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
| @@ -184,7 +184,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | |||
| 184 | /* | 184 | /* |
| 185 | * Initialize center channel to current channel. | 185 | * Initialize center channel to current channel. |
| 186 | */ | 186 | */ |
| 187 | center_channel = spec->channels[conf->channel->hw_value].channel; | 187 | center_channel = spec->channels[conf->chandef.chan->hw_value].channel; |
| 188 | 188 | ||
| 189 | /* | 189 | /* |
| 190 | * Adjust center channel to HT40+ and HT40- operation. | 190 | * Adjust center channel to HT40+ and HT40- operation. |
| @@ -199,7 +199,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | |||
| 199 | return i; | 199 | return i; |
| 200 | 200 | ||
| 201 | WARN_ON(1); | 201 | WARN_ON(1); |
| 202 | return conf->channel->hw_value; | 202 | return conf->chandef.chan->hw_value; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 205 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
| @@ -227,7 +227,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
| 227 | hw_value = rt2x00ht_center_channel(rt2x00dev, conf); | 227 | hw_value = rt2x00ht_center_channel(rt2x00dev, conf); |
| 228 | } else { | 228 | } else { |
| 229 | clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); | 229 | clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); |
| 230 | hw_value = conf->channel->hw_value; | 230 | hw_value = conf->chandef.chan->hw_value; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | memcpy(&libconf.rf, | 233 | memcpy(&libconf.rf, |
| @@ -279,8 +279,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
| 279 | else | 279 | else |
| 280 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | 280 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); |
| 281 | 281 | ||
| 282 | rt2x00dev->curr_band = conf->channel->band; | 282 | rt2x00dev->curr_band = conf->chandef.chan->band; |
| 283 | rt2x00dev->curr_freq = conf->channel->center_freq; | 283 | rt2x00dev->curr_freq = conf->chandef.chan->center_freq; |
| 284 | rt2x00dev->tx_power = conf->power_level; | 284 | rt2x00dev->tx_power = conf->power_level; |
| 285 | rt2x00dev->short_retry = conf->short_frame_max_tx_count; | 285 | rt2x00dev->short_retry = conf->short_frame_max_tx_count; |
| 286 | rt2x00dev->long_retry = conf->long_frame_max_tx_count; | 286 | rt2x00dev->long_retry = conf->long_frame_max_tx_count; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 3bb8cafbac59..fe7a7f63a9ed 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
| @@ -174,7 +174,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
| 174 | do_gettimeofday(×tamp); | 174 | do_gettimeofday(×tamp); |
| 175 | 175 | ||
| 176 | if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { | 176 | if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { |
| 177 | DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); | 177 | rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n"); |
| 178 | return; | 178 | return; |
| 179 | } | 179 | } |
| 180 | 180 | ||
| @@ -185,7 +185,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
| 185 | skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len, | 185 | skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len, |
| 186 | GFP_ATOMIC); | 186 | GFP_ATOMIC); |
| 187 | if (!skbcopy) { | 187 | if (!skbcopy) { |
| 188 | DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); | 188 | rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n"); |
| 189 | return; | 189 | return; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| @@ -657,7 +657,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
| 657 | 657 | ||
| 658 | intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); | 658 | intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); |
| 659 | if (!intf) { | 659 | if (!intf) { |
| 660 | ERROR(rt2x00dev, "Failed to allocate debug handler.\n"); | 660 | rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n"); |
| 661 | return; | 661 | return; |
| 662 | } | 662 | } |
| 663 | 663 | ||
| @@ -760,7 +760,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
| 760 | 760 | ||
| 761 | exit: | 761 | exit: |
| 762 | rt2x00debug_deregister(rt2x00dev); | 762 | rt2x00debug_deregister(rt2x00dev); |
| 763 | ERROR(rt2x00dev, "Failed to register debug handler.\n"); | 763 | rt2x00_err(rt2x00dev, "Failed to register debug handler\n"); |
| 764 | } | 764 | } |
| 765 | 765 | ||
| 766 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | 766 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 189744db65e0..90dc14336980 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -171,7 +171,7 @@ static void rt2x00lib_autowakeup(struct work_struct *work) | |||
| 171 | return; | 171 | return; |
| 172 | 172 | ||
| 173 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | 173 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) |
| 174 | ERROR(rt2x00dev, "Device failed to wakeup.\n"); | 174 | rt2x00_err(rt2x00dev, "Device failed to wakeup\n"); |
| 175 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | 175 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| @@ -673,9 +673,8 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | |||
| 673 | break; | 673 | break; |
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | WARNING(rt2x00dev, "Frame received with unrecognized signal, " | 676 | rt2x00_warn(rt2x00dev, "Frame received with unrecognized signal, mode=0x%.4x, signal=0x%.4x, type=%d\n", |
| 677 | "mode=0x%.4x, signal=0x%.4x, type=%d.\n", | 677 | rxdesc->rate_mode, signal, type); |
| 678 | rxdesc->rate_mode, signal, type); | ||
| 679 | return 0; | 678 | return 0; |
| 680 | } | 679 | } |
| 681 | 680 | ||
| @@ -720,8 +719,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
| 720 | */ | 719 | */ |
| 721 | if (unlikely(rxdesc.size == 0 || | 720 | if (unlikely(rxdesc.size == 0 || |
| 722 | rxdesc.size > entry->queue->data_size)) { | 721 | rxdesc.size > entry->queue->data_size)) { |
| 723 | ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", | 722 | rt2x00_err(rt2x00dev, "Wrong frame size %d max %d\n", |
| 724 | rxdesc.size, entry->queue->data_size); | 723 | rxdesc.size, entry->queue->data_size); |
| 725 | dev_kfree_skb(entry->skb); | 724 | dev_kfree_skb(entry->skb); |
| 726 | goto renew_skb; | 725 | goto renew_skb; |
| 727 | } | 726 | } |
| @@ -1006,7 +1005,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
| 1006 | 1005 | ||
| 1007 | exit_free_channels: | 1006 | exit_free_channels: |
| 1008 | kfree(channels); | 1007 | kfree(channels); |
| 1009 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | 1008 | rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n"); |
| 1010 | return -ENOMEM; | 1009 | return -ENOMEM; |
| 1011 | } | 1010 | } |
| 1012 | 1011 | ||
| @@ -1337,7 +1336,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
| 1337 | */ | 1336 | */ |
| 1338 | retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); | 1337 | retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); |
| 1339 | if (retval) { | 1338 | if (retval) { |
| 1340 | ERROR(rt2x00dev, "Failed to allocate device.\n"); | 1339 | rt2x00_err(rt2x00dev, "Failed to allocate device\n"); |
| 1341 | goto exit; | 1340 | goto exit; |
| 1342 | } | 1341 | } |
| 1343 | 1342 | ||
| @@ -1353,7 +1352,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
| 1353 | */ | 1352 | */ |
| 1354 | retval = rt2x00lib_probe_hw(rt2x00dev); | 1353 | retval = rt2x00lib_probe_hw(rt2x00dev); |
| 1355 | if (retval) { | 1354 | if (retval) { |
| 1356 | ERROR(rt2x00dev, "Failed to initialize hw.\n"); | 1355 | rt2x00_err(rt2x00dev, "Failed to initialize hw\n"); |
| 1357 | goto exit; | 1356 | goto exit; |
| 1358 | } | 1357 | } |
| 1359 | 1358 | ||
| @@ -1451,7 +1450,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | |||
| 1451 | #ifdef CONFIG_PM | 1450 | #ifdef CONFIG_PM |
| 1452 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | 1451 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) |
| 1453 | { | 1452 | { |
| 1454 | DEBUG(rt2x00dev, "Going to sleep.\n"); | 1453 | rt2x00_dbg(rt2x00dev, "Going to sleep\n"); |
| 1455 | 1454 | ||
| 1456 | /* | 1455 | /* |
| 1457 | * Prevent mac80211 from accessing driver while suspended. | 1456 | * Prevent mac80211 from accessing driver while suspended. |
| @@ -1482,8 +1481,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
| 1482 | * device is as good as disabled. | 1481 | * device is as good as disabled. |
| 1483 | */ | 1482 | */ |
| 1484 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) | 1483 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) |
| 1485 | WARNING(rt2x00dev, "Device failed to enter sleep state, " | 1484 | rt2x00_warn(rt2x00dev, "Device failed to enter sleep state, continue suspending\n"); |
| 1486 | "continue suspending.\n"); | ||
| 1487 | 1485 | ||
| 1488 | return 0; | 1486 | return 0; |
| 1489 | } | 1487 | } |
| @@ -1491,7 +1489,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | |||
| 1491 | 1489 | ||
| 1492 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1490 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
| 1493 | { | 1491 | { |
| 1494 | DEBUG(rt2x00dev, "Waking up.\n"); | 1492 | rt2x00_dbg(rt2x00dev, "Waking up\n"); |
| 1495 | 1493 | ||
| 1496 | /* | 1494 | /* |
| 1497 | * Restore/enable extra components. | 1495 | * Restore/enable extra components. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index f316aad30612..1b4254b4272d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
| @@ -42,28 +42,28 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
| 42 | */ | 42 | */ |
| 43 | fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev); | 43 | fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev); |
| 44 | if (!fw_name) { | 44 | if (!fw_name) { |
| 45 | ERROR(rt2x00dev, | 45 | rt2x00_err(rt2x00dev, |
| 46 | "Invalid firmware filename.\n" | 46 | "Invalid firmware filename\n" |
| 47 | "Please file bug report to %s.\n", DRV_PROJECT); | 47 | "Please file bug report to %s\n", DRV_PROJECT); |
| 48 | return -EINVAL; | 48 | return -EINVAL; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name); | 51 | rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); |
| 52 | 52 | ||
| 53 | retval = request_firmware(&fw, fw_name, device); | 53 | retval = request_firmware(&fw, fw_name, device); |
| 54 | if (retval) { | 54 | if (retval) { |
| 55 | ERROR(rt2x00dev, "Failed to request Firmware.\n"); | 55 | rt2x00_err(rt2x00dev, "Failed to request Firmware\n"); |
| 56 | return retval; | 56 | return retval; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | if (!fw || !fw->size || !fw->data) { | 59 | if (!fw || !fw->size || !fw->data) { |
| 60 | ERROR(rt2x00dev, "Failed to read Firmware.\n"); | 60 | rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); |
| 61 | release_firmware(fw); | 61 | release_firmware(fw); |
| 62 | return -ENOENT; | 62 | return -ENOENT; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", | 65 | rt2x00_info(rt2x00dev, "Firmware detected - version: %d.%d\n", |
| 66 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | 66 | fw->data[fw->size - 4], fw->data[fw->size - 3]); |
| 67 | snprintf(rt2x00dev->hw->wiphy->fw_version, | 67 | snprintf(rt2x00dev->hw->wiphy->fw_version, |
| 68 | sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", | 68 | sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", |
| 69 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | 69 | fw->data[fw->size - 4], fw->data[fw->size - 3]); |
| @@ -73,15 +73,14 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
| 73 | case FW_OK: | 73 | case FW_OK: |
| 74 | break; | 74 | break; |
| 75 | case FW_BAD_CRC: | 75 | case FW_BAD_CRC: |
| 76 | ERROR(rt2x00dev, "Firmware checksum error.\n"); | 76 | rt2x00_err(rt2x00dev, "Firmware checksum error\n"); |
| 77 | goto exit; | 77 | goto exit; |
| 78 | case FW_BAD_LENGTH: | 78 | case FW_BAD_LENGTH: |
| 79 | ERROR(rt2x00dev, | 79 | rt2x00_err(rt2x00dev, "Invalid firmware file length (len=%zu)\n", |
| 80 | "Invalid firmware file length (len=%zu)\n", fw->size); | 80 | fw->size); |
| 81 | goto exit; | 81 | goto exit; |
| 82 | case FW_BAD_VERSION: | 82 | case FW_BAD_VERSION: |
| 83 | ERROR(rt2x00dev, | 83 | rt2x00_err(rt2x00dev, "Current firmware does not support detected chipset\n"); |
| 84 | "Current firmware does not support detected chipset.\n"); | ||
| 85 | goto exit; | 84 | goto exit; |
| 86 | } | 85 | } |
| 87 | 86 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 8679d781a264..997a6c89e66e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
| @@ -113,7 +113,7 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | |||
| 113 | 113 | ||
| 114 | retval = led_classdev_register(device, &led->led_dev); | 114 | retval = led_classdev_register(device, &led->led_dev); |
| 115 | if (retval) { | 115 | if (retval) { |
| 116 | ERROR(rt2x00dev, "Failed to register led handler.\n"); | 116 | rt2x00_err(rt2x00dev, "Failed to register led handler\n"); |
| 117 | return retval; | 117 | return retval; |
| 118 | } | 118 | } |
| 119 | 119 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 9161c02d8ff9..f883802f3505 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
| @@ -46,7 +46,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
| 46 | 46 | ||
| 47 | skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom); | 47 | skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom); |
| 48 | if (unlikely(!skb)) { | 48 | if (unlikely(!skb)) { |
| 49 | WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n"); | 49 | rt2x00_warn(rt2x00dev, "Failed to create RTS/CTS frame\n"); |
| 50 | return -ENOMEM; | 50 | return -ENOMEM; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| @@ -93,7 +93,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
| 93 | retval = rt2x00queue_write_tx_frame(queue, skb, true); | 93 | retval = rt2x00queue_write_tx_frame(queue, skb, true); |
| 94 | if (retval) { | 94 | if (retval) { |
| 95 | dev_kfree_skb_any(skb); | 95 | dev_kfree_skb_any(skb); |
| 96 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 96 | rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n"); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | return retval; | 99 | return retval; |
| @@ -126,9 +126,9 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, | |||
| 126 | 126 | ||
| 127 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | 127 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
| 128 | if (unlikely(!queue)) { | 128 | if (unlikely(!queue)) { |
| 129 | ERROR(rt2x00dev, | 129 | rt2x00_err(rt2x00dev, |
| 130 | "Attempt to send packet over invalid queue %d.\n" | 130 | "Attempt to send packet over invalid queue %d\n" |
| 131 | "Please file bug report to %s.\n", qid, DRV_PROJECT); | 131 | "Please file bug report to %s\n", qid, DRV_PROJECT); |
| 132 | goto exit_free_skb; | 132 | goto exit_free_skb; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| @@ -731,9 +731,10 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, | |||
| 731 | queue->aifs = params->aifs; | 731 | queue->aifs = params->aifs; |
| 732 | queue->txop = params->txop; | 732 | queue->txop = params->txop; |
| 733 | 733 | ||
| 734 | DEBUG(rt2x00dev, | 734 | rt2x00_dbg(rt2x00dev, |
| 735 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n", | 735 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d\n", |
| 736 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop); | 736 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs, |
| 737 | queue->txop); | ||
| 737 | 738 | ||
| 738 | return 0; | 739 | return 0; |
| 739 | } | 740 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c index d84a680ba0c9..64b06c6abe58 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mmio.c +++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | /* | 34 | /* |
| 35 | * Register access. | 35 | * Register access. |
| 36 | */ | 36 | */ |
| 37 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00mmio_regbusy_read(struct rt2x00_dev *rt2x00dev, |
| 38 | const unsigned int offset, | 38 | const unsigned int offset, |
| 39 | const struct rt2x00_field32 field, | 39 | const struct rt2x00_field32 field, |
| 40 | u32 *reg) | 40 | u32 *reg) |
| 41 | { | 41 | { |
| 42 | unsigned int i; | 42 | unsigned int i; |
| 43 | 43 | ||
| @@ -45,7 +45,7 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
| 45 | return 0; | 45 | return 0; |
| 46 | 46 | ||
| 47 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 47 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
| 48 | rt2x00pci_register_read(rt2x00dev, offset, reg); | 48 | rt2x00mmio_register_read(rt2x00dev, offset, reg); |
| 49 | if (!rt2x00_get_field32(*reg, field)) | 49 | if (!rt2x00_get_field32(*reg, field)) |
| 50 | return 1; | 50 | return 1; |
| 51 | udelay(REGISTER_BUSY_DELAY); | 51 | udelay(REGISTER_BUSY_DELAY); |
| @@ -57,13 +57,13 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
| 57 | 57 | ||
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); | 60 | EXPORT_SYMBOL_GPL(rt2x00mmio_regbusy_read); |
| 61 | 61 | ||
| 62 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 62 | bool rt2x00mmio_rxdone(struct rt2x00_dev *rt2x00dev) |
| 63 | { | 63 | { |
| 64 | struct data_queue *queue = rt2x00dev->rx; | 64 | struct data_queue *queue = rt2x00dev->rx; |
| 65 | struct queue_entry *entry; | 65 | struct queue_entry *entry; |
| 66 | struct queue_entry_priv_pci *entry_priv; | 66 | struct queue_entry_priv_mmio *entry_priv; |
| 67 | struct skb_frame_desc *skbdesc; | 67 | struct skb_frame_desc *skbdesc; |
| 68 | int max_rx = 16; | 68 | int max_rx = 16; |
| 69 | 69 | ||
| @@ -96,24 +96,24 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
| 96 | 96 | ||
| 97 | return !max_rx; | 97 | return !max_rx; |
| 98 | } | 98 | } |
| 99 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 99 | EXPORT_SYMBOL_GPL(rt2x00mmio_rxdone); |
| 100 | 100 | ||
| 101 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) | 101 | void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop) |
| 102 | { | 102 | { |
| 103 | unsigned int i; | 103 | unsigned int i; |
| 104 | 104 | ||
| 105 | for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) | 105 | for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) |
| 106 | msleep(10); | 106 | msleep(10); |
| 107 | } | 107 | } |
| 108 | EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); | 108 | EXPORT_SYMBOL_GPL(rt2x00mmio_flush_queue); |
| 109 | 109 | ||
| 110 | /* | 110 | /* |
| 111 | * Device initialization handlers. | 111 | * Device initialization handlers. |
| 112 | */ | 112 | */ |
| 113 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | 113 | static int rt2x00mmio_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, |
| 114 | struct data_queue *queue) | 114 | struct data_queue *queue) |
| 115 | { | 115 | { |
| 116 | struct queue_entry_priv_pci *entry_priv; | 116 | struct queue_entry_priv_mmio *entry_priv; |
| 117 | void *addr; | 117 | void *addr; |
| 118 | dma_addr_t dma; | 118 | dma_addr_t dma; |
| 119 | unsigned int i; | 119 | unsigned int i; |
| @@ -141,10 +141,10 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
| 141 | return 0; | 141 | return 0; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | 144 | static void rt2x00mmio_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
| 145 | struct data_queue *queue) | 145 | struct data_queue *queue) |
| 146 | { | 146 | { |
| 147 | struct queue_entry_priv_pci *entry_priv = | 147 | struct queue_entry_priv_mmio *entry_priv = |
| 148 | queue->entries[0].priv_data; | 148 | queue->entries[0].priv_data; |
| 149 | 149 | ||
| 150 | if (entry_priv->desc) | 150 | if (entry_priv->desc) |
| @@ -154,7 +154,7 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
| 154 | entry_priv->desc = NULL; | 154 | entry_priv->desc = NULL; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 157 | int rt2x00mmio_initialize(struct rt2x00_dev *rt2x00dev) |
| 158 | { | 158 | { |
| 159 | struct data_queue *queue; | 159 | struct data_queue *queue; |
| 160 | int status; | 160 | int status; |
| @@ -163,7 +163,7 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | |||
| 163 | * Allocate DMA | 163 | * Allocate DMA |
| 164 | */ | 164 | */ |
| 165 | queue_for_each(rt2x00dev, queue) { | 165 | queue_for_each(rt2x00dev, queue) { |
| 166 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); | 166 | status = rt2x00mmio_alloc_queue_dma(rt2x00dev, queue); |
| 167 | if (status) | 167 | if (status) |
| 168 | goto exit; | 168 | goto exit; |
| 169 | } | 169 | } |
| @@ -175,8 +175,8 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | |||
| 175 | rt2x00dev->ops->lib->irq_handler, | 175 | rt2x00dev->ops->lib->irq_handler, |
| 176 | IRQF_SHARED, rt2x00dev->name, rt2x00dev); | 176 | IRQF_SHARED, rt2x00dev->name, rt2x00dev); |
| 177 | if (status) { | 177 | if (status) { |
| 178 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", | 178 | rt2x00_err(rt2x00dev, "IRQ %d allocation failed (error %d)\n", |
| 179 | rt2x00dev->irq, status); | 179 | rt2x00dev->irq, status); |
| 180 | goto exit; | 180 | goto exit; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| @@ -184,13 +184,13 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | |||
| 184 | 184 | ||
| 185 | exit: | 185 | exit: |
| 186 | queue_for_each(rt2x00dev, queue) | 186 | queue_for_each(rt2x00dev, queue) |
| 187 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | 187 | rt2x00mmio_free_queue_dma(rt2x00dev, queue); |
| 188 | 188 | ||
| 189 | return status; | 189 | return status; |
| 190 | } | 190 | } |
| 191 | EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | 191 | EXPORT_SYMBOL_GPL(rt2x00mmio_initialize); |
| 192 | 192 | ||
| 193 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | 193 | void rt2x00mmio_uninitialize(struct rt2x00_dev *rt2x00dev) |
| 194 | { | 194 | { |
| 195 | struct data_queue *queue; | 195 | struct data_queue *queue; |
| 196 | 196 | ||
| @@ -203,9 +203,9 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
| 203 | * Free DMA | 203 | * Free DMA |
| 204 | */ | 204 | */ |
| 205 | queue_for_each(rt2x00dev, queue) | 205 | queue_for_each(rt2x00dev, queue) |
| 206 | rt2x00pci_free_queue_dma(rt2x00dev, queue); | 206 | rt2x00mmio_free_queue_dma(rt2x00dev, queue); |
| 207 | } | 207 | } |
| 208 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | 208 | EXPORT_SYMBOL_GPL(rt2x00mmio_uninitialize); |
| 209 | 209 | ||
| 210 | /* | 210 | /* |
| 211 | * rt2x00mmio module information. | 211 | * rt2x00mmio module information. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h index 4ecaf60175bf..cda3dbcf7ead 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mmio.h +++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h | |||
| @@ -31,37 +31,37 @@ | |||
| 31 | /* | 31 | /* |
| 32 | * Register access. | 32 | * Register access. |
| 33 | */ | 33 | */ |
| 34 | static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | 34 | static inline void rt2x00mmio_register_read(struct rt2x00_dev *rt2x00dev, |
| 35 | const unsigned int offset, | 35 | const unsigned int offset, |
| 36 | u32 *value) | 36 | u32 *value) |
| 37 | { | 37 | { |
| 38 | *value = readl(rt2x00dev->csr.base + offset); | 38 | *value = readl(rt2x00dev->csr.base + offset); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | 41 | static inline void rt2x00mmio_register_multiread(struct rt2x00_dev *rt2x00dev, |
| 42 | const unsigned int offset, | 42 | const unsigned int offset, |
| 43 | void *value, const u32 length) | 43 | void *value, const u32 length) |
| 44 | { | 44 | { |
| 45 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); | 45 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | 48 | static inline void rt2x00mmio_register_write(struct rt2x00_dev *rt2x00dev, |
| 49 | const unsigned int offset, | 49 | const unsigned int offset, |
| 50 | u32 value) | 50 | u32 value) |
| 51 | { | 51 | { |
| 52 | writel(value, rt2x00dev->csr.base + offset); | 52 | writel(value, rt2x00dev->csr.base + offset); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | 55 | static inline void rt2x00mmio_register_multiwrite(struct rt2x00_dev *rt2x00dev, |
| 56 | const unsigned int offset, | 56 | const unsigned int offset, |
| 57 | const void *value, | 57 | const void *value, |
| 58 | const u32 length) | 58 | const u32 length) |
| 59 | { | 59 | { |
| 60 | __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); | 60 | __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | /** | 63 | /** |
| 64 | * rt2x00pci_regbusy_read - Read from register with busy check | 64 | * rt2x00mmio_regbusy_read - Read from register with busy check |
| 65 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | 65 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. |
| 66 | * @offset: Register offset | 66 | * @offset: Register offset |
| 67 | * @field: Field to check if register is busy | 67 | * @field: Field to check if register is busy |
| @@ -73,47 +73,47 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
| 73 | * is not read after a certain timeout, this function will return | 73 | * is not read after a certain timeout, this function will return |
| 74 | * FALSE. | 74 | * FALSE. |
| 75 | */ | 75 | */ |
| 76 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | 76 | int rt2x00mmio_regbusy_read(struct rt2x00_dev *rt2x00dev, |
| 77 | const unsigned int offset, | 77 | const unsigned int offset, |
| 78 | const struct rt2x00_field32 field, | 78 | const struct rt2x00_field32 field, |
| 79 | u32 *reg); | 79 | u32 *reg); |
| 80 | 80 | ||
| 81 | /** | 81 | /** |
| 82 | * struct queue_entry_priv_pci: Per entry PCI specific information | 82 | * struct queue_entry_priv_mmio: Per entry PCI specific information |
| 83 | * | 83 | * |
| 84 | * @desc: Pointer to device descriptor | 84 | * @desc: Pointer to device descriptor |
| 85 | * @desc_dma: DMA pointer to &desc. | 85 | * @desc_dma: DMA pointer to &desc. |
| 86 | * @data: Pointer to device's entry memory. | 86 | * @data: Pointer to device's entry memory. |
| 87 | * @data_dma: DMA pointer to &data. | 87 | * @data_dma: DMA pointer to &data. |
| 88 | */ | 88 | */ |
| 89 | struct queue_entry_priv_pci { | 89 | struct queue_entry_priv_mmio { |
| 90 | __le32 *desc; | 90 | __le32 *desc; |
| 91 | dma_addr_t desc_dma; | 91 | dma_addr_t desc_dma; |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | /** | 94 | /** |
| 95 | * rt2x00pci_rxdone - Handle RX done events | 95 | * rt2x00mmio_rxdone - Handle RX done events |
| 96 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | 96 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. |
| 97 | * | 97 | * |
| 98 | * Returns true if there are still rx frames pending and false if all | 98 | * Returns true if there are still rx frames pending and false if all |
| 99 | * pending rx frames were processed. | 99 | * pending rx frames were processed. |
| 100 | */ | 100 | */ |
| 101 | bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 101 | bool rt2x00mmio_rxdone(struct rt2x00_dev *rt2x00dev); |
| 102 | 102 | ||
| 103 | /** | 103 | /** |
| 104 | * rt2x00pci_flush_queue - Flush data queue | 104 | * rt2x00mmio_flush_queue - Flush data queue |
| 105 | * @queue: Data queue to stop | 105 | * @queue: Data queue to stop |
| 106 | * @drop: True to drop all pending frames. | 106 | * @drop: True to drop all pending frames. |
| 107 | * | 107 | * |
| 108 | * This will wait for a maximum of 100ms, waiting for the queues | 108 | * This will wait for a maximum of 100ms, waiting for the queues |
| 109 | * to become empty. | 109 | * to become empty. |
| 110 | */ | 110 | */ |
| 111 | void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); | 111 | void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop); |
| 112 | 112 | ||
| 113 | /* | 113 | /* |
| 114 | * Device initialization handlers. | 114 | * Device initialization handlers. |
| 115 | */ | 115 | */ |
| 116 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); | 116 | int rt2x00mmio_initialize(struct rt2x00_dev *rt2x00dev); |
| 117 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); | 117 | void rt2x00mmio_uninitialize(struct rt2x00_dev *rt2x00dev); |
| 118 | 118 | ||
| 119 | #endif /* RT2X00MMIO_H */ | 119 | #endif /* RT2X00MMIO_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index e87865e33113..dc49e525ae5e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
| @@ -68,7 +68,7 @@ static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
| 68 | return 0; | 68 | return 0; |
| 69 | 69 | ||
| 70 | exit: | 70 | exit: |
| 71 | ERROR_PROBE("Failed to allocate registers.\n"); | 71 | rt2x00_probe_err("Failed to allocate registers\n"); |
| 72 | 72 | ||
| 73 | rt2x00pci_free_reg(rt2x00dev); | 73 | rt2x00pci_free_reg(rt2x00dev); |
| 74 | 74 | ||
| @@ -84,30 +84,30 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) | |||
| 84 | 84 | ||
| 85 | retval = pci_enable_device(pci_dev); | 85 | retval = pci_enable_device(pci_dev); |
| 86 | if (retval) { | 86 | if (retval) { |
| 87 | ERROR_PROBE("Enable device failed.\n"); | 87 | rt2x00_probe_err("Enable device failed\n"); |
| 88 | return retval; | 88 | return retval; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | retval = pci_request_regions(pci_dev, pci_name(pci_dev)); | 91 | retval = pci_request_regions(pci_dev, pci_name(pci_dev)); |
| 92 | if (retval) { | 92 | if (retval) { |
| 93 | ERROR_PROBE("PCI request regions failed.\n"); | 93 | rt2x00_probe_err("PCI request regions failed\n"); |
| 94 | goto exit_disable_device; | 94 | goto exit_disable_device; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | pci_set_master(pci_dev); | 97 | pci_set_master(pci_dev); |
| 98 | 98 | ||
| 99 | if (pci_set_mwi(pci_dev)) | 99 | if (pci_set_mwi(pci_dev)) |
| 100 | ERROR_PROBE("MWI not available.\n"); | 100 | rt2x00_probe_err("MWI not available\n"); |
| 101 | 101 | ||
| 102 | if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { | 102 | if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { |
| 103 | ERROR_PROBE("PCI DMA not supported.\n"); | 103 | rt2x00_probe_err("PCI DMA not supported\n"); |
| 104 | retval = -EIO; | 104 | retval = -EIO; |
| 105 | goto exit_release_regions; | 105 | goto exit_release_regions; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 108 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
| 109 | if (!hw) { | 109 | if (!hw) { |
| 110 | ERROR_PROBE("Failed to allocate hardware.\n"); | 110 | rt2x00_probe_err("Failed to allocate hardware\n"); |
| 111 | retval = -ENOMEM; | 111 | retval = -ENOMEM; |
| 112 | goto exit_release_regions; | 112 | goto exit_release_regions; |
| 113 | } | 113 | } |
| @@ -207,7 +207,7 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) | |||
| 207 | 207 | ||
| 208 | if (pci_set_power_state(pci_dev, PCI_D0) || | 208 | if (pci_set_power_state(pci_dev, PCI_D0) || |
| 209 | pci_enable_device(pci_dev)) { | 209 | pci_enable_device(pci_dev)) { |
| 210 | ERROR(rt2x00dev, "Failed to resume device.\n"); | 210 | rt2x00_err(rt2x00dev, "Failed to resume device\n"); |
| 211 | return -EIO; | 211 | return -EIO; |
| 212 | } | 212 | } |
| 213 | 213 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 952a0490eb17..2c12311467a9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
| @@ -35,7 +35,8 @@ | |||
| 35 | 35 | ||
| 36 | struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) | 36 | struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) |
| 37 | { | 37 | { |
| 38 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 38 | struct data_queue *queue = entry->queue; |
| 39 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
| 39 | struct sk_buff *skb; | 40 | struct sk_buff *skb; |
| 40 | struct skb_frame_desc *skbdesc; | 41 | struct skb_frame_desc *skbdesc; |
| 41 | unsigned int frame_size; | 42 | unsigned int frame_size; |
| @@ -46,7 +47,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) | |||
| 46 | * The frame size includes descriptor size, because the | 47 | * The frame size includes descriptor size, because the |
| 47 | * hardware directly receive the frame into the skbuffer. | 48 | * hardware directly receive the frame into the skbuffer. |
| 48 | */ | 49 | */ |
| 49 | frame_size = entry->queue->data_size + entry->queue->desc_size; | 50 | frame_size = queue->data_size + queue->desc_size + queue->winfo_size; |
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * The payload should be aligned to a 4-byte boundary, | 53 | * The payload should be aligned to a 4-byte boundary, |
| @@ -531,10 +532,10 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, | |||
| 531 | */ | 532 | */ |
| 532 | if (unlikely(rt2x00dev->ops->lib->get_entry_state && | 533 | if (unlikely(rt2x00dev->ops->lib->get_entry_state && |
| 533 | rt2x00dev->ops->lib->get_entry_state(entry))) { | 534 | rt2x00dev->ops->lib->get_entry_state(entry))) { |
| 534 | ERROR(rt2x00dev, | 535 | rt2x00_err(rt2x00dev, |
| 535 | "Corrupt queue %d, accessing entry which is not ours.\n" | 536 | "Corrupt queue %d, accessing entry which is not ours\n" |
| 536 | "Please file bug report to %s.\n", | 537 | "Please file bug report to %s\n", |
| 537 | entry->queue->qid, DRV_PROJECT); | 538 | entry->queue->qid, DRV_PROJECT); |
| 538 | return -EINVAL; | 539 | return -EINVAL; |
| 539 | } | 540 | } |
| 540 | 541 | ||
| @@ -698,8 +699,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
| 698 | spin_lock(&queue->tx_lock); | 699 | spin_lock(&queue->tx_lock); |
| 699 | 700 | ||
| 700 | if (unlikely(rt2x00queue_full(queue))) { | 701 | if (unlikely(rt2x00queue_full(queue))) { |
| 701 | ERROR(queue->rt2x00dev, | 702 | rt2x00_err(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n", |
| 702 | "Dropping frame due to full tx queue %d.\n", queue->qid); | 703 | queue->qid); |
| 703 | ret = -ENOBUFS; | 704 | ret = -ENOBUFS; |
| 704 | goto out; | 705 | goto out; |
| 705 | } | 706 | } |
| @@ -708,10 +709,10 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
| 708 | 709 | ||
| 709 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, | 710 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, |
| 710 | &entry->flags))) { | 711 | &entry->flags))) { |
| 711 | ERROR(queue->rt2x00dev, | 712 | rt2x00_err(queue->rt2x00dev, |
| 712 | "Arrived at non-free entry in the non-full queue %d.\n" | 713 | "Arrived at non-free entry in the non-full queue %d\n" |
| 713 | "Please file bug report to %s.\n", | 714 | "Please file bug report to %s\n", |
| 714 | queue->qid, DRV_PROJECT); | 715 | queue->qid, DRV_PROJECT); |
| 715 | ret = -EINVAL; | 716 | ret = -EINVAL; |
| 716 | goto out; | 717 | goto out; |
| 717 | } | 718 | } |
| @@ -842,9 +843,9 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue, | |||
| 842 | unsigned int i; | 843 | unsigned int i; |
| 843 | 844 | ||
| 844 | if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { | 845 | if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { |
| 845 | ERROR(queue->rt2x00dev, | 846 | rt2x00_err(queue->rt2x00dev, |
| 846 | "Entry requested from invalid index range (%d - %d)\n", | 847 | "Entry requested from invalid index range (%d - %d)\n", |
| 847 | start, end); | 848 | start, end); |
| 848 | return true; | 849 | return true; |
| 849 | } | 850 | } |
| 850 | 851 | ||
| @@ -891,8 +892,8 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | |||
| 891 | unsigned long irqflags; | 892 | unsigned long irqflags; |
| 892 | 893 | ||
| 893 | if (unlikely(index >= Q_INDEX_MAX)) { | 894 | if (unlikely(index >= Q_INDEX_MAX)) { |
| 894 | ERROR(queue->rt2x00dev, | 895 | rt2x00_err(queue->rt2x00dev, "Entry requested from invalid index type (%d)\n", |
| 895 | "Entry requested from invalid index type (%d)\n", index); | 896 | index); |
| 896 | return NULL; | 897 | return NULL; |
| 897 | } | 898 | } |
| 898 | 899 | ||
| @@ -912,8 +913,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) | |||
| 912 | unsigned long irqflags; | 913 | unsigned long irqflags; |
| 913 | 914 | ||
| 914 | if (unlikely(index >= Q_INDEX_MAX)) { | 915 | if (unlikely(index >= Q_INDEX_MAX)) { |
| 915 | ERROR(queue->rt2x00dev, | 916 | rt2x00_err(queue->rt2x00dev, |
| 916 | "Index change on invalid index type (%d)\n", index); | 917 | "Index change on invalid index type (%d)\n", index); |
| 917 | return; | 918 | return; |
| 918 | } | 919 | } |
| 919 | 920 | ||
| @@ -1073,7 +1074,8 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) | |||
| 1073 | * The queue flush has failed... | 1074 | * The queue flush has failed... |
| 1074 | */ | 1075 | */ |
| 1075 | if (unlikely(!rt2x00queue_empty(queue))) | 1076 | if (unlikely(!rt2x00queue_empty(queue))) |
| 1076 | WARNING(queue->rt2x00dev, "Queue %d failed to flush\n", queue->qid); | 1077 | rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n", |
| 1078 | queue->qid); | ||
| 1077 | 1079 | ||
| 1078 | /* | 1080 | /* |
| 1079 | * Restore the queue to the previous status | 1081 | * Restore the queue to the previous status |
| @@ -1172,6 +1174,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
| 1172 | queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); | 1174 | queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); |
| 1173 | queue->data_size = qdesc->data_size; | 1175 | queue->data_size = qdesc->data_size; |
| 1174 | queue->desc_size = qdesc->desc_size; | 1176 | queue->desc_size = qdesc->desc_size; |
| 1177 | queue->winfo_size = qdesc->winfo_size; | ||
| 1175 | 1178 | ||
| 1176 | /* | 1179 | /* |
| 1177 | * Allocate all queue entries. | 1180 | * Allocate all queue entries. |
| @@ -1262,7 +1265,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
| 1262 | return 0; | 1265 | return 0; |
| 1263 | 1266 | ||
| 1264 | exit: | 1267 | exit: |
| 1265 | ERROR(rt2x00dev, "Queue entries allocation failed.\n"); | 1268 | rt2x00_err(rt2x00dev, "Queue entries allocation failed\n"); |
| 1266 | 1269 | ||
| 1267 | rt2x00queue_uninitialize(rt2x00dev); | 1270 | rt2x00queue_uninitialize(rt2x00dev); |
| 1268 | 1271 | ||
| @@ -1314,7 +1317,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
| 1314 | 1317 | ||
| 1315 | queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); | 1318 | queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); |
| 1316 | if (!queue) { | 1319 | if (!queue) { |
| 1317 | ERROR(rt2x00dev, "Queue allocation failed.\n"); | 1320 | rt2x00_err(rt2x00dev, "Queue allocation failed\n"); |
| 1318 | return -ENOMEM; | 1321 | return -ENOMEM; |
| 1319 | } | 1322 | } |
| 1320 | 1323 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 3d0137193da0..4a7b34e9261b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
| @@ -479,7 +479,8 @@ struct data_queue { | |||
| 479 | unsigned short cw_max; | 479 | unsigned short cw_max; |
| 480 | 480 | ||
| 481 | unsigned short data_size; | 481 | unsigned short data_size; |
| 482 | unsigned short desc_size; | 482 | unsigned char desc_size; |
| 483 | unsigned char winfo_size; | ||
| 483 | 484 | ||
| 484 | unsigned short usb_endpoint; | 485 | unsigned short usb_endpoint; |
| 485 | unsigned short usb_maxpacket; | 486 | unsigned short usb_maxpacket; |
| @@ -499,7 +500,8 @@ struct data_queue { | |||
| 499 | struct data_queue_desc { | 500 | struct data_queue_desc { |
| 500 | unsigned short entry_num; | 501 | unsigned short entry_num; |
| 501 | unsigned short data_size; | 502 | unsigned short data_size; |
| 502 | unsigned short desc_size; | 503 | unsigned char desc_size; |
| 504 | unsigned char winfo_size; | ||
| 503 | unsigned short priv_size; | 505 | unsigned short priv_size; |
| 504 | }; | 506 | }; |
| 505 | 507 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index 2aa5c38022f3..9271a5fce0a8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c | |||
| @@ -68,7 +68,7 @@ static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
| 68 | return 0; | 68 | return 0; |
| 69 | 69 | ||
| 70 | exit: | 70 | exit: |
| 71 | ERROR_PROBE("Failed to allocate registers.\n"); | 71 | rt2x00_probe_err("Failed to allocate registers\n"); |
| 72 | rt2x00soc_free_reg(rt2x00dev); | 72 | rt2x00soc_free_reg(rt2x00dev); |
| 73 | 73 | ||
| 74 | return -ENOMEM; | 74 | return -ENOMEM; |
| @@ -82,7 +82,7 @@ int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops) | |||
| 82 | 82 | ||
| 83 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 83 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
| 84 | if (!hw) { | 84 | if (!hw) { |
| 85 | ERROR_PROBE("Failed to allocate hardware.\n"); | 85 | rt2x00_probe_err("Failed to allocate hardware\n"); |
| 86 | return -ENOMEM; | 86 | return -ENOMEM; |
| 87 | } | 87 | } |
| 88 | 88 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 5e50d4ff9d21..88289873c0cf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
| @@ -70,9 +70,9 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | ERROR(rt2x00dev, | 73 | rt2x00_err(rt2x00dev, |
| 74 | "Vendor Request 0x%02x failed for offset 0x%04x with error %d.\n", | 74 | "Vendor Request 0x%02x failed for offset 0x%04x with error %d\n", |
| 75 | request, offset, status); | 75 | request, offset, status); |
| 76 | 76 | ||
| 77 | return status; | 77 | return status; |
| 78 | } | 78 | } |
| @@ -91,7 +91,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
| 91 | * Check for Cache availability. | 91 | * Check for Cache availability. |
| 92 | */ | 92 | */ |
| 93 | if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { | 93 | if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { |
| 94 | ERROR(rt2x00dev, "CSR cache not available.\n"); | 94 | rt2x00_err(rt2x00dev, "CSR cache not available\n"); |
| 95 | return -ENOMEM; | 95 | return -ENOMEM; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| @@ -157,8 +157,8 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
| 157 | udelay(REGISTER_BUSY_DELAY); | 157 | udelay(REGISTER_BUSY_DELAY); |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | ERROR(rt2x00dev, "Indirect register access failed: " | 160 | rt2x00_err(rt2x00dev, "Indirect register access failed: offset=0x%.08x, value=0x%.08x\n", |
| 161 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | 161 | offset, *reg); |
| 162 | *reg = ~0; | 162 | *reg = ~0; |
| 163 | 163 | ||
| 164 | return 0; | 164 | return 0; |
| @@ -307,7 +307,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) | |||
| 307 | status = skb_padto(entry->skb, length); | 307 | status = skb_padto(entry->skb, length); |
| 308 | if (unlikely(status)) { | 308 | if (unlikely(status)) { |
| 309 | /* TODO: report something more appropriate than IO_FAILED. */ | 309 | /* TODO: report something more appropriate than IO_FAILED. */ |
| 310 | WARNING(rt2x00dev, "TX SKB padding error, out of memory\n"); | 310 | rt2x00_warn(rt2x00dev, "TX SKB padding error, out of memory\n"); |
| 311 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | 311 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
| 312 | rt2x00lib_dmadone(entry); | 312 | rt2x00lib_dmadone(entry); |
| 313 | 313 | ||
| @@ -520,8 +520,8 @@ EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); | |||
| 520 | 520 | ||
| 521 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) | 521 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) |
| 522 | { | 522 | { |
| 523 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," | 523 | rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", |
| 524 | " invoke forced forced reset\n", queue->qid); | 524 | queue->qid); |
| 525 | 525 | ||
| 526 | rt2x00queue_flush_queue(queue, true); | 526 | rt2x00queue_flush_queue(queue, true); |
| 527 | } | 527 | } |
| @@ -622,7 +622,7 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) | |||
| 622 | * At least 1 endpoint for RX and 1 endpoint for TX must be available. | 622 | * At least 1 endpoint for RX and 1 endpoint for TX must be available. |
| 623 | */ | 623 | */ |
| 624 | if (!rt2x00dev->rx->usb_endpoint || !rt2x00dev->tx->usb_endpoint) { | 624 | if (!rt2x00dev->rx->usb_endpoint || !rt2x00dev->tx->usb_endpoint) { |
| 625 | ERROR(rt2x00dev, "Bulk-in/Bulk-out endpoints not found\n"); | 625 | rt2x00_err(rt2x00dev, "Bulk-in/Bulk-out endpoints not found\n"); |
| 626 | return -EPIPE; | 626 | return -EPIPE; |
| 627 | } | 627 | } |
| 628 | 628 | ||
| @@ -775,7 +775,7 @@ static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
| 775 | return 0; | 775 | return 0; |
| 776 | 776 | ||
| 777 | exit: | 777 | exit: |
| 778 | ERROR_PROBE("Failed to allocate registers.\n"); | 778 | rt2x00_probe_err("Failed to allocate registers\n"); |
| 779 | 779 | ||
| 780 | rt2x00usb_free_reg(rt2x00dev); | 780 | rt2x00usb_free_reg(rt2x00dev); |
| 781 | 781 | ||
| @@ -795,7 +795,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
| 795 | 795 | ||
| 796 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 796 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
| 797 | if (!hw) { | 797 | if (!hw) { |
| 798 | ERROR_PROBE("Failed to allocate hardware.\n"); | 798 | rt2x00_probe_err("Failed to allocate hardware\n"); |
| 799 | retval = -ENOMEM; | 799 | retval = -ENOMEM; |
| 800 | goto exit_put_device; | 800 | goto exit_put_device; |
| 801 | } | 801 | } |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 9e3c8ff53e3f..0dc8180e251b 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
| @@ -58,12 +58,12 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | |||
| 58 | * and we will print an error. | 58 | * and we will print an error. |
| 59 | */ | 59 | */ |
| 60 | #define WAIT_FOR_BBP(__dev, __reg) \ | 60 | #define WAIT_FOR_BBP(__dev, __reg) \ |
| 61 | rt2x00pci_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) | 61 | rt2x00mmio_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) |
| 62 | #define WAIT_FOR_RF(__dev, __reg) \ | 62 | #define WAIT_FOR_RF(__dev, __reg) \ |
| 63 | rt2x00pci_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) | 63 | rt2x00mmio_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) |
| 64 | #define WAIT_FOR_MCU(__dev, __reg) \ | 64 | #define WAIT_FOR_MCU(__dev, __reg) \ |
| 65 | rt2x00pci_regbusy_read((__dev), H2M_MAILBOX_CSR, \ | 65 | rt2x00mmio_regbusy_read((__dev), H2M_MAILBOX_CSR, \ |
| 66 | H2M_MAILBOX_CSR_OWNER, (__reg)) | 66 | H2M_MAILBOX_CSR_OWNER, (__reg)) |
| 67 | 67 | ||
| 68 | static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 68 | static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
| 69 | const unsigned int word, const u8 value) | 69 | const unsigned int word, const u8 value) |
| @@ -83,7 +83,7 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
| 83 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 83 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
| 84 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | 84 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); |
| 85 | 85 | ||
| 86 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | 86 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR3, reg); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | mutex_unlock(&rt2x00dev->csr_mutex); | 89 | mutex_unlock(&rt2x00dev->csr_mutex); |
| @@ -110,7 +110,7 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
| 110 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 110 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
| 111 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | 111 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); |
| 112 | 112 | ||
| 113 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | 113 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR3, reg); |
| 114 | 114 | ||
| 115 | WAIT_FOR_BBP(rt2x00dev, ®); | 115 | WAIT_FOR_BBP(rt2x00dev, ®); |
| 116 | } | 116 | } |
| @@ -138,7 +138,7 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
| 138 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | 138 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); |
| 139 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | 139 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); |
| 140 | 140 | ||
| 141 | rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); | 141 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR4, reg); |
| 142 | rt2x00_rf_write(rt2x00dev, word, value); | 142 | rt2x00_rf_write(rt2x00dev, word, value); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| @@ -162,12 +162,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
| 162 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | 162 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); |
| 163 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | 163 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); |
| 164 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | 164 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); |
| 165 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); | 165 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); |
| 166 | 166 | ||
| 167 | rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); | 167 | rt2x00mmio_register_read(rt2x00dev, HOST_CMD_CSR, ®); |
| 168 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | 168 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); |
| 169 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 169 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); |
| 170 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | 170 | rt2x00mmio_register_write(rt2x00dev, HOST_CMD_CSR, reg); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | mutex_unlock(&rt2x00dev->csr_mutex); | 173 | mutex_unlock(&rt2x00dev->csr_mutex); |
| @@ -179,7 +179,7 @@ static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | |||
| 179 | struct rt2x00_dev *rt2x00dev = eeprom->data; | 179 | struct rt2x00_dev *rt2x00dev = eeprom->data; |
| 180 | u32 reg; | 180 | u32 reg; |
| 181 | 181 | ||
| 182 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | 182 | rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); |
| 183 | 183 | ||
| 184 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); | 184 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); |
| 185 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); | 185 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); |
| @@ -201,15 +201,15 @@ static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | |||
| 201 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, | 201 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, |
| 202 | !!eeprom->reg_chip_select); | 202 | !!eeprom->reg_chip_select); |
| 203 | 203 | ||
| 204 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); | 204 | rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 207 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
| 208 | static const struct rt2x00debug rt61pci_rt2x00debug = { | 208 | static const struct rt2x00debug rt61pci_rt2x00debug = { |
| 209 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
| 210 | .csr = { | 210 | .csr = { |
| 211 | .read = rt2x00pci_register_read, | 211 | .read = rt2x00mmio_register_read, |
| 212 | .write = rt2x00pci_register_write, | 212 | .write = rt2x00mmio_register_write, |
| 213 | .flags = RT2X00DEBUGFS_OFFSET, | 213 | .flags = RT2X00DEBUGFS_OFFSET, |
| 214 | .word_base = CSR_REG_BASE, | 214 | .word_base = CSR_REG_BASE, |
| 215 | .word_size = sizeof(u32), | 215 | .word_size = sizeof(u32), |
| @@ -243,7 +243,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
| 243 | { | 243 | { |
| 244 | u32 reg; | 244 | u32 reg; |
| 245 | 245 | ||
| 246 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 246 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); |
| 247 | return rt2x00_get_field32(reg, MAC_CSR13_VAL5); | 247 | return rt2x00_get_field32(reg, MAC_CSR13_VAL5); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| @@ -294,10 +294,10 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev, | |||
| 294 | container_of(led_cdev, struct rt2x00_led, led_dev); | 294 | container_of(led_cdev, struct rt2x00_led, led_dev); |
| 295 | u32 reg; | 295 | u32 reg; |
| 296 | 296 | ||
| 297 | rt2x00pci_register_read(led->rt2x00dev, MAC_CSR14, ®); | 297 | rt2x00mmio_register_read(led->rt2x00dev, MAC_CSR14, ®); |
| 298 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); | 298 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); |
| 299 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); | 299 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); |
| 300 | rt2x00pci_register_write(led->rt2x00dev, MAC_CSR14, reg); | 300 | rt2x00mmio_register_write(led->rt2x00dev, MAC_CSR14, reg); |
| 301 | 301 | ||
| 302 | return 0; | 302 | return 0; |
| 303 | } | 303 | } |
| @@ -339,7 +339,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
| 339 | */ | 339 | */ |
| 340 | mask = (0xf << crypto->bssidx); | 340 | mask = (0xf << crypto->bssidx); |
| 341 | 341 | ||
| 342 | rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); | 342 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR0, ®); |
| 343 | reg &= mask; | 343 | reg &= mask; |
| 344 | 344 | ||
| 345 | if (reg && reg == mask) | 345 | if (reg && reg == mask) |
| @@ -358,8 +358,8 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
| 358 | sizeof(key_entry.rx_mic)); | 358 | sizeof(key_entry.rx_mic)); |
| 359 | 359 | ||
| 360 | reg = SHARED_KEY_ENTRY(key->hw_key_idx); | 360 | reg = SHARED_KEY_ENTRY(key->hw_key_idx); |
| 361 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | 361 | rt2x00mmio_register_multiwrite(rt2x00dev, reg, |
| 362 | &key_entry, sizeof(key_entry)); | 362 | &key_entry, sizeof(key_entry)); |
| 363 | 363 | ||
| 364 | /* | 364 | /* |
| 365 | * The cipher types are stored over 2 registers. | 365 | * The cipher types are stored over 2 registers. |
| @@ -372,16 +372,16 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
| 372 | field.bit_offset = (3 * key->hw_key_idx); | 372 | field.bit_offset = (3 * key->hw_key_idx); |
| 373 | field.bit_mask = 0x7 << field.bit_offset; | 373 | field.bit_mask = 0x7 << field.bit_offset; |
| 374 | 374 | ||
| 375 | rt2x00pci_register_read(rt2x00dev, SEC_CSR1, ®); | 375 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR1, ®); |
| 376 | rt2x00_set_field32(®, field, crypto->cipher); | 376 | rt2x00_set_field32(®, field, crypto->cipher); |
| 377 | rt2x00pci_register_write(rt2x00dev, SEC_CSR1, reg); | 377 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg); |
| 378 | } else { | 378 | } else { |
| 379 | field.bit_offset = (3 * (key->hw_key_idx - 8)); | 379 | field.bit_offset = (3 * (key->hw_key_idx - 8)); |
| 380 | field.bit_mask = 0x7 << field.bit_offset; | 380 | field.bit_mask = 0x7 << field.bit_offset; |
| 381 | 381 | ||
| 382 | rt2x00pci_register_read(rt2x00dev, SEC_CSR5, ®); | 382 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR5, ®); |
| 383 | rt2x00_set_field32(®, field, crypto->cipher); | 383 | rt2x00_set_field32(®, field, crypto->cipher); |
| 384 | rt2x00pci_register_write(rt2x00dev, SEC_CSR5, reg); | 384 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg); |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | /* | 387 | /* |
| @@ -404,12 +404,12 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
| 404 | */ | 404 | */ |
| 405 | mask = 1 << key->hw_key_idx; | 405 | mask = 1 << key->hw_key_idx; |
| 406 | 406 | ||
| 407 | rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); | 407 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR0, ®); |
| 408 | if (crypto->cmd == SET_KEY) | 408 | if (crypto->cmd == SET_KEY) |
| 409 | reg |= mask; | 409 | reg |= mask; |
| 410 | else if (crypto->cmd == DISABLE_KEY) | 410 | else if (crypto->cmd == DISABLE_KEY) |
| 411 | reg &= ~mask; | 411 | reg &= ~mask; |
| 412 | rt2x00pci_register_write(rt2x00dev, SEC_CSR0, reg); | 412 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg); |
| 413 | 413 | ||
| 414 | return 0; | 414 | return 0; |
| 415 | } | 415 | } |
| @@ -433,10 +433,10 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
| 433 | * When both registers are full, we drop the key. | 433 | * When both registers are full, we drop the key. |
| 434 | * Otherwise, we use the first invalid entry. | 434 | * Otherwise, we use the first invalid entry. |
| 435 | */ | 435 | */ |
| 436 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); | 436 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR2, ®); |
| 437 | if (reg && reg == ~0) { | 437 | if (reg && reg == ~0) { |
| 438 | key->hw_key_idx = 32; | 438 | key->hw_key_idx = 32; |
| 439 | rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); | 439 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR3, ®); |
| 440 | if (reg && reg == ~0) | 440 | if (reg && reg == ~0) |
| 441 | return -ENOSPC; | 441 | return -ENOSPC; |
| 442 | } | 442 | } |
| @@ -458,21 +458,21 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
| 458 | addr_entry.cipher = crypto->cipher; | 458 | addr_entry.cipher = crypto->cipher; |
| 459 | 459 | ||
| 460 | reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); | 460 | reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); |
| 461 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | 461 | rt2x00mmio_register_multiwrite(rt2x00dev, reg, |
| 462 | &key_entry, sizeof(key_entry)); | 462 | &key_entry, sizeof(key_entry)); |
| 463 | 463 | ||
| 464 | reg = PAIRWISE_TA_ENTRY(key->hw_key_idx); | 464 | reg = PAIRWISE_TA_ENTRY(key->hw_key_idx); |
| 465 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | 465 | rt2x00mmio_register_multiwrite(rt2x00dev, reg, |
| 466 | &addr_entry, sizeof(addr_entry)); | 466 | &addr_entry, sizeof(addr_entry)); |
| 467 | 467 | ||
| 468 | /* | 468 | /* |
| 469 | * Enable pairwise lookup table for given BSS idx. | 469 | * Enable pairwise lookup table for given BSS idx. |
| 470 | * Without this, received frames will not be decrypted | 470 | * Without this, received frames will not be decrypted |
| 471 | * by the hardware. | 471 | * by the hardware. |
| 472 | */ | 472 | */ |
| 473 | rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®); | 473 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR4, ®); |
| 474 | reg |= (1 << crypto->bssidx); | 474 | reg |= (1 << crypto->bssidx); |
| 475 | rt2x00pci_register_write(rt2x00dev, SEC_CSR4, reg); | 475 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR4, reg); |
| 476 | 476 | ||
| 477 | /* | 477 | /* |
| 478 | * The driver does not support the IV/EIV generation | 478 | * The driver does not support the IV/EIV generation |
| @@ -495,21 +495,21 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
| 495 | if (key->hw_key_idx < 32) { | 495 | if (key->hw_key_idx < 32) { |
| 496 | mask = 1 << key->hw_key_idx; | 496 | mask = 1 << key->hw_key_idx; |
| 497 | 497 | ||
| 498 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); | 498 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR2, ®); |
| 499 | if (crypto->cmd == SET_KEY) | 499 | if (crypto->cmd == SET_KEY) |
| 500 | reg |= mask; | 500 | reg |= mask; |
| 501 | else if (crypto->cmd == DISABLE_KEY) | 501 | else if (crypto->cmd == DISABLE_KEY) |
| 502 | reg &= ~mask; | 502 | reg &= ~mask; |
| 503 | rt2x00pci_register_write(rt2x00dev, SEC_CSR2, reg); | 503 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR2, reg); |
| 504 | } else { | 504 | } else { |
| 505 | mask = 1 << (key->hw_key_idx - 32); | 505 | mask = 1 << (key->hw_key_idx - 32); |
| 506 | 506 | ||
| 507 | rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); | 507 | rt2x00mmio_register_read(rt2x00dev, SEC_CSR3, ®); |
| 508 | if (crypto->cmd == SET_KEY) | 508 | if (crypto->cmd == SET_KEY) |
| 509 | reg |= mask; | 509 | reg |= mask; |
| 510 | else if (crypto->cmd == DISABLE_KEY) | 510 | else if (crypto->cmd == DISABLE_KEY) |
| 511 | reg &= ~mask; | 511 | reg &= ~mask; |
| 512 | rt2x00pci_register_write(rt2x00dev, SEC_CSR3, reg); | 512 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR3, reg); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | return 0; | 515 | return 0; |
| @@ -526,7 +526,7 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 526 | * and broadcast frames will always be accepted since | 526 | * and broadcast frames will always be accepted since |
| 527 | * there is no filter for it at this time. | 527 | * there is no filter for it at this time. |
| 528 | */ | 528 | */ |
| 529 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 529 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); |
| 530 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | 530 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, |
| 531 | !(filter_flags & FIF_FCSFAIL)); | 531 | !(filter_flags & FIF_FCSFAIL)); |
| 532 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | 532 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, |
| @@ -544,7 +544,7 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, | |||
| 544 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | 544 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
| 545 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | 545 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
| 546 | !(filter_flags & FIF_CONTROL)); | 546 | !(filter_flags & FIF_CONTROL)); |
| 547 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 547 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | 550 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
| @@ -558,9 +558,9 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
| 558 | /* | 558 | /* |
| 559 | * Enable synchronisation. | 559 | * Enable synchronisation. |
| 560 | */ | 560 | */ |
| 561 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 561 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 562 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 562 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
| 563 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 563 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | if (flags & CONFIG_UPDATE_MAC) { | 566 | if (flags & CONFIG_UPDATE_MAC) { |
| @@ -568,8 +568,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
| 568 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 568 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
| 569 | conf->mac[1] = cpu_to_le32(reg); | 569 | conf->mac[1] = cpu_to_le32(reg); |
| 570 | 570 | ||
| 571 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, | 571 | rt2x00mmio_register_multiwrite(rt2x00dev, MAC_CSR2, |
| 572 | conf->mac, sizeof(conf->mac)); | 572 | conf->mac, sizeof(conf->mac)); |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | if (flags & CONFIG_UPDATE_BSSID) { | 575 | if (flags & CONFIG_UPDATE_BSSID) { |
| @@ -577,8 +577,9 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
| 577 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); | 577 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
| 578 | conf->bssid[1] = cpu_to_le32(reg); | 578 | conf->bssid[1] = cpu_to_le32(reg); |
| 579 | 579 | ||
| 580 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, | 580 | rt2x00mmio_register_multiwrite(rt2x00dev, MAC_CSR4, |
| 581 | conf->bssid, sizeof(conf->bssid)); | 581 | conf->bssid, |
| 582 | sizeof(conf->bssid)); | ||
| 582 | } | 583 | } |
| 583 | } | 584 | } |
| 584 | 585 | ||
| @@ -588,40 +589,40 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
| 588 | { | 589 | { |
| 589 | u32 reg; | 590 | u32 reg; |
| 590 | 591 | ||
| 591 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 592 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); |
| 592 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32); | 593 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32); |
| 593 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | 594 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); |
| 594 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 595 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); |
| 595 | 596 | ||
| 596 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 597 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
| 597 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | 598 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR4, ®); |
| 598 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | 599 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); |
| 599 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 600 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
| 600 | !!erp->short_preamble); | 601 | !!erp->short_preamble); |
| 601 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 602 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR4, reg); |
| 602 | } | 603 | } |
| 603 | 604 | ||
| 604 | if (changed & BSS_CHANGED_BASIC_RATES) | 605 | if (changed & BSS_CHANGED_BASIC_RATES) |
| 605 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, | 606 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR5, |
| 606 | erp->basic_rates); | 607 | erp->basic_rates); |
| 607 | 608 | ||
| 608 | if (changed & BSS_CHANGED_BEACON_INT) { | 609 | if (changed & BSS_CHANGED_BEACON_INT) { |
| 609 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 610 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 610 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, | 611 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, |
| 611 | erp->beacon_int * 16); | 612 | erp->beacon_int * 16); |
| 612 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 613 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 613 | } | 614 | } |
| 614 | 615 | ||
| 615 | if (changed & BSS_CHANGED_ERP_SLOT) { | 616 | if (changed & BSS_CHANGED_ERP_SLOT) { |
| 616 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | 617 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR9, ®); |
| 617 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); | 618 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); |
| 618 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | 619 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR9, reg); |
| 619 | 620 | ||
| 620 | rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); | 621 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR8, ®); |
| 621 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); | 622 | rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); |
| 622 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | 623 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); |
| 623 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); | 624 | rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); |
| 624 | rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); | 625 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR8, reg); |
| 625 | } | 626 | } |
| 626 | } | 627 | } |
| 627 | 628 | ||
| @@ -714,7 +715,7 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, | |||
| 714 | { | 715 | { |
| 715 | u32 reg; | 716 | u32 reg; |
| 716 | 717 | ||
| 717 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 718 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); |
| 718 | 719 | ||
| 719 | rt2x00_set_field32(®, MAC_CSR13_DIR4, 0); | 720 | rt2x00_set_field32(®, MAC_CSR13_DIR4, 0); |
| 720 | rt2x00_set_field32(®, MAC_CSR13_VAL4, p1); | 721 | rt2x00_set_field32(®, MAC_CSR13_VAL4, p1); |
| @@ -722,7 +723,7 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, | |||
| 722 | rt2x00_set_field32(®, MAC_CSR13_DIR3, 0); | 723 | rt2x00_set_field32(®, MAC_CSR13_DIR3, 0); |
| 723 | rt2x00_set_field32(®, MAC_CSR13_VAL3, !p2); | 724 | rt2x00_set_field32(®, MAC_CSR13_VAL3, !p2); |
| 724 | 725 | ||
| 725 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | 726 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, reg); |
| 726 | } | 727 | } |
| 727 | 728 | ||
| 728 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | 729 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, |
| @@ -821,14 +822,14 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, | |||
| 821 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | 822 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) |
| 822 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | 823 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); |
| 823 | 824 | ||
| 824 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | 825 | rt2x00mmio_register_read(rt2x00dev, PHY_CSR0, ®); |
| 825 | 826 | ||
| 826 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 827 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
| 827 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | 828 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
| 828 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 829 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
| 829 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | 830 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
| 830 | 831 | ||
| 831 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 832 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR0, reg); |
| 832 | 833 | ||
| 833 | if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) | 834 | if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) |
| 834 | rt61pci_config_antenna_5x(rt2x00dev, ant); | 835 | rt61pci_config_antenna_5x(rt2x00dev, ant); |
| @@ -848,7 +849,7 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, | |||
| 848 | u16 eeprom; | 849 | u16 eeprom; |
| 849 | short lna_gain = 0; | 850 | short lna_gain = 0; |
| 850 | 851 | ||
| 851 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { | 852 | if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { |
| 852 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) | 853 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) |
| 853 | lna_gain += 14; | 854 | lna_gain += 14; |
| 854 | 855 | ||
| @@ -928,7 +929,7 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, | |||
| 928 | { | 929 | { |
| 929 | u32 reg; | 930 | u32 reg; |
| 930 | 931 | ||
| 931 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | 932 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR4, ®); |
| 932 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); | 933 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); |
| 933 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); | 934 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); |
| 934 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); | 935 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); |
| @@ -936,7 +937,7 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, | |||
| 936 | libconf->conf->long_frame_max_tx_count); | 937 | libconf->conf->long_frame_max_tx_count); |
| 937 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, | 938 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, |
| 938 | libconf->conf->short_frame_max_tx_count); | 939 | libconf->conf->short_frame_max_tx_count); |
| 939 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 940 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR4, reg); |
| 940 | } | 941 | } |
| 941 | 942 | ||
| 942 | static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, | 943 | static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, |
| @@ -948,7 +949,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 948 | u32 reg; | 949 | u32 reg; |
| 949 | 950 | ||
| 950 | if (state == STATE_SLEEP) { | 951 | if (state == STATE_SLEEP) { |
| 951 | rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); | 952 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR11, ®); |
| 952 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, | 953 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, |
| 953 | rt2x00dev->beacon_int - 10); | 954 | rt2x00dev->beacon_int - 10); |
| 954 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, | 955 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, |
| @@ -957,27 +958,29 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, | |||
| 957 | 958 | ||
| 958 | /* We must first disable autowake before it can be enabled */ | 959 | /* We must first disable autowake before it can be enabled */ |
| 959 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | 960 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); |
| 960 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | 961 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); |
| 961 | 962 | ||
| 962 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1); | 963 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1); |
| 963 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | 964 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); |
| 964 | 965 | ||
| 965 | rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005); | 966 | rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, |
| 966 | rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c); | 967 | 0x00000005); |
| 967 | rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060); | 968 | rt2x00mmio_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c); |
| 969 | rt2x00mmio_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060); | ||
| 968 | 970 | ||
| 969 | rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0); | 971 | rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0); |
| 970 | } else { | 972 | } else { |
| 971 | rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); | 973 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR11, ®); |
| 972 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0); | 974 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0); |
| 973 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); | 975 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); |
| 974 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | 976 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); |
| 975 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0); | 977 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0); |
| 976 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | 978 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); |
| 977 | 979 | ||
| 978 | rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); | 980 | rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, |
| 979 | rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018); | 981 | 0x00000007); |
| 980 | rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020); | 982 | rt2x00mmio_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018); |
| 983 | rt2x00mmio_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020); | ||
| 981 | 984 | ||
| 982 | rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); | 985 | rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); |
| 983 | } | 986 | } |
| @@ -1013,13 +1016,13 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
| 1013 | /* | 1016 | /* |
| 1014 | * Update FCS error count from register. | 1017 | * Update FCS error count from register. |
| 1015 | */ | 1018 | */ |
| 1016 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | 1019 | rt2x00mmio_register_read(rt2x00dev, STA_CSR0, ®); |
| 1017 | qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); | 1020 | qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); |
| 1018 | 1021 | ||
| 1019 | /* | 1022 | /* |
| 1020 | * Update False CCA count from register. | 1023 | * Update False CCA count from register. |
| 1021 | */ | 1024 | */ |
| 1022 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | 1025 | rt2x00mmio_register_read(rt2x00dev, STA_CSR1, ®); |
| 1023 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | 1026 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); |
| 1024 | } | 1027 | } |
| 1025 | 1028 | ||
| @@ -1138,16 +1141,16 @@ static void rt61pci_start_queue(struct data_queue *queue) | |||
| 1138 | 1141 | ||
| 1139 | switch (queue->qid) { | 1142 | switch (queue->qid) { |
| 1140 | case QID_RX: | 1143 | case QID_RX: |
| 1141 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 1144 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); |
| 1142 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); | 1145 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); |
| 1143 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 1146 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); |
| 1144 | break; | 1147 | break; |
| 1145 | case QID_BEACON: | 1148 | case QID_BEACON: |
| 1146 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1149 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 1147 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 1150 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); |
| 1148 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | 1151 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); |
| 1149 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1152 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
| 1150 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1153 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 1151 | break; | 1154 | break; |
| 1152 | default: | 1155 | default: |
| 1153 | break; | 1156 | break; |
| @@ -1161,24 +1164,24 @@ static void rt61pci_kick_queue(struct data_queue *queue) | |||
| 1161 | 1164 | ||
| 1162 | switch (queue->qid) { | 1165 | switch (queue->qid) { |
| 1163 | case QID_AC_VO: | 1166 | case QID_AC_VO: |
| 1164 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1167 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1165 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); | 1168 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); |
| 1166 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1169 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1167 | break; | 1170 | break; |
| 1168 | case QID_AC_VI: | 1171 | case QID_AC_VI: |
| 1169 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1172 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1170 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); | 1173 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); |
| 1171 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1174 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1172 | break; | 1175 | break; |
| 1173 | case QID_AC_BE: | 1176 | case QID_AC_BE: |
| 1174 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1177 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1175 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); | 1178 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); |
| 1176 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1179 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1177 | break; | 1180 | break; |
| 1178 | case QID_AC_BK: | 1181 | case QID_AC_BK: |
| 1179 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1182 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1180 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); | 1183 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); |
| 1181 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1184 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1182 | break; | 1185 | break; |
| 1183 | default: | 1186 | default: |
| 1184 | break; | 1187 | break; |
| @@ -1192,36 +1195,36 @@ static void rt61pci_stop_queue(struct data_queue *queue) | |||
| 1192 | 1195 | ||
| 1193 | switch (queue->qid) { | 1196 | switch (queue->qid) { |
| 1194 | case QID_AC_VO: | 1197 | case QID_AC_VO: |
| 1195 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1198 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1196 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); | 1199 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); |
| 1197 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1200 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1198 | break; | 1201 | break; |
| 1199 | case QID_AC_VI: | 1202 | case QID_AC_VI: |
| 1200 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1203 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1201 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | 1204 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); |
| 1202 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1205 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1203 | break; | 1206 | break; |
| 1204 | case QID_AC_BE: | 1207 | case QID_AC_BE: |
| 1205 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1208 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1206 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1209 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
| 1207 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1210 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1208 | break; | 1211 | break; |
| 1209 | case QID_AC_BK: | 1212 | case QID_AC_BK: |
| 1210 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1213 | rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
| 1211 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1214 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
| 1212 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1215 | rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
| 1213 | break; | 1216 | break; |
| 1214 | case QID_RX: | 1217 | case QID_RX: |
| 1215 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 1218 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); |
| 1216 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); | 1219 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); |
| 1217 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 1220 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); |
| 1218 | break; | 1221 | break; |
| 1219 | case QID_BEACON: | 1222 | case QID_BEACON: |
| 1220 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1223 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 1221 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | 1224 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); |
| 1222 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | 1225 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); |
| 1223 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1226 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
| 1224 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1227 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 1225 | 1228 | ||
| 1226 | /* | 1229 | /* |
| 1227 | * Wait for possibly running tbtt tasklets. | 1230 | * Wait for possibly running tbtt tasklets. |
| @@ -1299,14 +1302,14 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1299 | * Wait for stable hardware. | 1302 | * Wait for stable hardware. |
| 1300 | */ | 1303 | */ |
| 1301 | for (i = 0; i < 100; i++) { | 1304 | for (i = 0; i < 100; i++) { |
| 1302 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | 1305 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR0, ®); |
| 1303 | if (reg) | 1306 | if (reg) |
| 1304 | break; | 1307 | break; |
| 1305 | msleep(1); | 1308 | msleep(1); |
| 1306 | } | 1309 | } |
| 1307 | 1310 | ||
| 1308 | if (!reg) { | 1311 | if (!reg) { |
| 1309 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 1312 | rt2x00_err(rt2x00dev, "Unstable hardware\n"); |
| 1310 | return -EBUSY; | 1313 | return -EBUSY; |
| 1311 | } | 1314 | } |
| 1312 | 1315 | ||
| @@ -1315,10 +1318,10 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1315 | */ | 1318 | */ |
| 1316 | reg = 0; | 1319 | reg = 0; |
| 1317 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | 1320 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); |
| 1318 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | 1321 | rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); |
| 1319 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | 1322 | rt2x00mmio_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); |
| 1320 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 1323 | rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
| 1321 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, 0); | 1324 | rt2x00mmio_register_write(rt2x00dev, HOST_CMD_CSR, 0); |
| 1322 | 1325 | ||
| 1323 | /* | 1326 | /* |
| 1324 | * Write firmware to device. | 1327 | * Write firmware to device. |
| @@ -1326,26 +1329,26 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1326 | reg = 0; | 1329 | reg = 0; |
| 1327 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | 1330 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); |
| 1328 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 1); | 1331 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 1); |
| 1329 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | 1332 | rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); |
| 1330 | 1333 | ||
| 1331 | rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 1334 | rt2x00mmio_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
| 1332 | data, len); | 1335 | data, len); |
| 1333 | 1336 | ||
| 1334 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 0); | 1337 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 0); |
| 1335 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | 1338 | rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); |
| 1336 | 1339 | ||
| 1337 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 0); | 1340 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 0); |
| 1338 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | 1341 | rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); |
| 1339 | 1342 | ||
| 1340 | for (i = 0; i < 100; i++) { | 1343 | for (i = 0; i < 100; i++) { |
| 1341 | rt2x00pci_register_read(rt2x00dev, MCU_CNTL_CSR, ®); | 1344 | rt2x00mmio_register_read(rt2x00dev, MCU_CNTL_CSR, ®); |
| 1342 | if (rt2x00_get_field32(reg, MCU_CNTL_CSR_READY)) | 1345 | if (rt2x00_get_field32(reg, MCU_CNTL_CSR_READY)) |
| 1343 | break; | 1346 | break; |
| 1344 | msleep(1); | 1347 | msleep(1); |
| 1345 | } | 1348 | } |
| 1346 | 1349 | ||
| 1347 | if (i == 100) { | 1350 | if (i == 100) { |
| 1348 | ERROR(rt2x00dev, "MCU Control register not ready.\n"); | 1351 | rt2x00_err(rt2x00dev, "MCU Control register not ready\n"); |
| 1349 | return -EBUSY; | 1352 | return -EBUSY; |
| 1350 | } | 1353 | } |
| 1351 | 1354 | ||
| @@ -1360,16 +1363,16 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1360 | reg = 0; | 1363 | reg = 0; |
| 1361 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | 1364 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); |
| 1362 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | 1365 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); |
| 1363 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1366 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1364 | 1367 | ||
| 1365 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | 1368 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); |
| 1366 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | 1369 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); |
| 1367 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | 1370 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); |
| 1368 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1371 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1369 | 1372 | ||
| 1370 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | 1373 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); |
| 1371 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | 1374 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); |
| 1372 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1375 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1373 | 1376 | ||
| 1374 | return 0; | 1377 | return 0; |
| 1375 | } | 1378 | } |
| @@ -1379,7 +1382,7 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1379 | */ | 1382 | */ |
| 1380 | static bool rt61pci_get_entry_state(struct queue_entry *entry) | 1383 | static bool rt61pci_get_entry_state(struct queue_entry *entry) |
| 1381 | { | 1384 | { |
| 1382 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1385 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1383 | u32 word; | 1386 | u32 word; |
| 1384 | 1387 | ||
| 1385 | if (entry->queue->qid == QID_RX) { | 1388 | if (entry->queue->qid == QID_RX) { |
| @@ -1396,7 +1399,7 @@ static bool rt61pci_get_entry_state(struct queue_entry *entry) | |||
| 1396 | 1399 | ||
| 1397 | static void rt61pci_clear_entry(struct queue_entry *entry) | 1400 | static void rt61pci_clear_entry(struct queue_entry *entry) |
| 1398 | { | 1401 | { |
| 1399 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1402 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1400 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1403 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 1401 | u32 word; | 1404 | u32 word; |
| 1402 | 1405 | ||
| @@ -1419,13 +1422,13 @@ static void rt61pci_clear_entry(struct queue_entry *entry) | |||
| 1419 | 1422 | ||
| 1420 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | 1423 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
| 1421 | { | 1424 | { |
| 1422 | struct queue_entry_priv_pci *entry_priv; | 1425 | struct queue_entry_priv_mmio *entry_priv; |
| 1423 | u32 reg; | 1426 | u32 reg; |
| 1424 | 1427 | ||
| 1425 | /* | 1428 | /* |
| 1426 | * Initialize registers. | 1429 | * Initialize registers. |
| 1427 | */ | 1430 | */ |
| 1428 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | 1431 | rt2x00mmio_register_read(rt2x00dev, TX_RING_CSR0, ®); |
| 1429 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | 1432 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, |
| 1430 | rt2x00dev->tx[0].limit); | 1433 | rt2x00dev->tx[0].limit); |
| 1431 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | 1434 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, |
| @@ -1434,67 +1437,67 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
| 1434 | rt2x00dev->tx[2].limit); | 1437 | rt2x00dev->tx[2].limit); |
| 1435 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | 1438 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, |
| 1436 | rt2x00dev->tx[3].limit); | 1439 | rt2x00dev->tx[3].limit); |
| 1437 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | 1440 | rt2x00mmio_register_write(rt2x00dev, TX_RING_CSR0, reg); |
| 1438 | 1441 | ||
| 1439 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | 1442 | rt2x00mmio_register_read(rt2x00dev, TX_RING_CSR1, ®); |
| 1440 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | 1443 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, |
| 1441 | rt2x00dev->tx[0].desc_size / 4); | 1444 | rt2x00dev->tx[0].desc_size / 4); |
| 1442 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1445 | rt2x00mmio_register_write(rt2x00dev, TX_RING_CSR1, reg); |
| 1443 | 1446 | ||
| 1444 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; | 1447 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
| 1445 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1448 | rt2x00mmio_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
| 1446 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1449 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
| 1447 | entry_priv->desc_dma); | 1450 | entry_priv->desc_dma); |
| 1448 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1451 | rt2x00mmio_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
| 1449 | 1452 | ||
| 1450 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; | 1453 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
| 1451 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1454 | rt2x00mmio_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
| 1452 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1455 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
| 1453 | entry_priv->desc_dma); | 1456 | entry_priv->desc_dma); |
| 1454 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1457 | rt2x00mmio_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
| 1455 | 1458 | ||
| 1456 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; | 1459 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; |
| 1457 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1460 | rt2x00mmio_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
| 1458 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1461 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
| 1459 | entry_priv->desc_dma); | 1462 | entry_priv->desc_dma); |
| 1460 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1463 | rt2x00mmio_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
| 1461 | 1464 | ||
| 1462 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; | 1465 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; |
| 1463 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1466 | rt2x00mmio_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
| 1464 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1467 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
| 1465 | entry_priv->desc_dma); | 1468 | entry_priv->desc_dma); |
| 1466 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1469 | rt2x00mmio_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
| 1467 | 1470 | ||
| 1468 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | 1471 | rt2x00mmio_register_read(rt2x00dev, RX_RING_CSR, ®); |
| 1469 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); | 1472 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); |
| 1470 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | 1473 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, |
| 1471 | rt2x00dev->rx->desc_size / 4); | 1474 | rt2x00dev->rx->desc_size / 4); |
| 1472 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1475 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
| 1473 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1476 | rt2x00mmio_register_write(rt2x00dev, RX_RING_CSR, reg); |
| 1474 | 1477 | ||
| 1475 | entry_priv = rt2x00dev->rx->entries[0].priv_data; | 1478 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
| 1476 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1479 | rt2x00mmio_register_read(rt2x00dev, RX_BASE_CSR, ®); |
| 1477 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1480 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
| 1478 | entry_priv->desc_dma); | 1481 | entry_priv->desc_dma); |
| 1479 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1482 | rt2x00mmio_register_write(rt2x00dev, RX_BASE_CSR, reg); |
| 1480 | 1483 | ||
| 1481 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1484 | rt2x00mmio_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
| 1482 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC0, 2); | 1485 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC0, 2); |
| 1483 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | 1486 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); |
| 1484 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | 1487 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); |
| 1485 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | 1488 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); |
| 1486 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | 1489 | rt2x00mmio_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); |
| 1487 | 1490 | ||
| 1488 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | 1491 | rt2x00mmio_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); |
| 1489 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1); | 1492 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1); |
| 1490 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | 1493 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); |
| 1491 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | 1494 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); |
| 1492 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | 1495 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); |
| 1493 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | 1496 | rt2x00mmio_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); |
| 1494 | 1497 | ||
| 1495 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1498 | rt2x00mmio_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
| 1496 | rt2x00_set_field32(®, RX_CNTL_CSR_LOAD_RXD, 1); | 1499 | rt2x00_set_field32(®, RX_CNTL_CSR_LOAD_RXD, 1); |
| 1497 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1500 | rt2x00mmio_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
| 1498 | 1501 | ||
| 1499 | return 0; | 1502 | return 0; |
| 1500 | } | 1503 | } |
| @@ -1503,13 +1506,13 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 1503 | { | 1506 | { |
| 1504 | u32 reg; | 1507 | u32 reg; |
| 1505 | 1508 | ||
| 1506 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 1509 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); |
| 1507 | rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); | 1510 | rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); |
| 1508 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); | 1511 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); |
| 1509 | rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); | 1512 | rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); |
| 1510 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 1513 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); |
| 1511 | 1514 | ||
| 1512 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR1, ®); | 1515 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR1, ®); |
| 1513 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ | 1516 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ |
| 1514 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); | 1517 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); |
| 1515 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ | 1518 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ |
| @@ -1518,12 +1521,12 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 1518 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); | 1521 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); |
| 1519 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ | 1522 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ |
| 1520 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); | 1523 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); |
| 1521 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, reg); | 1524 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR1, reg); |
| 1522 | 1525 | ||
| 1523 | /* | 1526 | /* |
| 1524 | * CCK TXD BBP registers | 1527 | * CCK TXD BBP registers |
| 1525 | */ | 1528 | */ |
| 1526 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR2, ®); | 1529 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR2, ®); |
| 1527 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); | 1530 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); |
| 1528 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); | 1531 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); |
| 1529 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); | 1532 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); |
| @@ -1532,76 +1535,76 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 1532 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); | 1535 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); |
| 1533 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); | 1536 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); |
| 1534 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); | 1537 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); |
| 1535 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, reg); | 1538 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR2, reg); |
| 1536 | 1539 | ||
| 1537 | /* | 1540 | /* |
| 1538 | * OFDM TXD BBP registers | 1541 | * OFDM TXD BBP registers |
| 1539 | */ | 1542 | */ |
| 1540 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR3, ®); | 1543 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR3, ®); |
| 1541 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); | 1544 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); |
| 1542 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); | 1545 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); |
| 1543 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); | 1546 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); |
| 1544 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); | 1547 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); |
| 1545 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); | 1548 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); |
| 1546 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); | 1549 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); |
| 1547 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, reg); | 1550 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR3, reg); |
| 1548 | 1551 | ||
| 1549 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR7, ®); | 1552 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR7, ®); |
| 1550 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); | 1553 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); |
| 1551 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); | 1554 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); |
| 1552 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); | 1555 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); |
| 1553 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); | 1556 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); |
| 1554 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, reg); | 1557 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR7, reg); |
| 1555 | 1558 | ||
| 1556 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR8, ®); | 1559 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR8, ®); |
| 1557 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); | 1560 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); |
| 1558 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); | 1561 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); |
| 1559 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); | 1562 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); |
| 1560 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | 1563 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); |
| 1561 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); | 1564 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR8, reg); |
| 1562 | 1565 | ||
| 1563 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1566 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 1564 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, 0); | 1567 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, 0); |
| 1565 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | 1568 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); |
| 1566 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | 1569 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); |
| 1567 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | 1570 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); |
| 1568 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1571 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
| 1569 | rt2x00_set_field32(®, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0); | 1572 | rt2x00_set_field32(®, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0); |
| 1570 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1573 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 1571 | 1574 | ||
| 1572 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | 1575 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); |
| 1573 | 1576 | ||
| 1574 | rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); | 1577 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); |
| 1575 | 1578 | ||
| 1576 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | 1579 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR9, ®); |
| 1577 | rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); | 1580 | rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); |
| 1578 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | 1581 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR9, reg); |
| 1579 | 1582 | ||
| 1580 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); | 1583 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); |
| 1581 | 1584 | ||
| 1582 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | 1585 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) |
| 1583 | return -EBUSY; | 1586 | return -EBUSY; |
| 1584 | 1587 | ||
| 1585 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | 1588 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); |
| 1586 | 1589 | ||
| 1587 | /* | 1590 | /* |
| 1588 | * Invalidate all Shared Keys (SEC_CSR0), | 1591 | * Invalidate all Shared Keys (SEC_CSR0), |
| 1589 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 1592 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
| 1590 | */ | 1593 | */ |
| 1591 | rt2x00pci_register_write(rt2x00dev, SEC_CSR0, 0x00000000); | 1594 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, 0x00000000); |
| 1592 | rt2x00pci_register_write(rt2x00dev, SEC_CSR1, 0x00000000); | 1595 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, 0x00000000); |
| 1593 | rt2x00pci_register_write(rt2x00dev, SEC_CSR5, 0x00000000); | 1596 | rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, 0x00000000); |
| 1594 | 1597 | ||
| 1595 | rt2x00pci_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); | 1598 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); |
| 1596 | rt2x00pci_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); | 1599 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); |
| 1597 | rt2x00pci_register_write(rt2x00dev, PHY_CSR6, 0x00080606); | 1600 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR6, 0x00080606); |
| 1598 | rt2x00pci_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); | 1601 | rt2x00mmio_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); |
| 1599 | 1602 | ||
| 1600 | rt2x00pci_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); | 1603 | rt2x00mmio_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); |
| 1601 | 1604 | ||
| 1602 | rt2x00pci_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); | 1605 | rt2x00mmio_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); |
| 1603 | 1606 | ||
| 1604 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | 1607 | rt2x00mmio_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); |
| 1605 | 1608 | ||
| 1606 | /* | 1609 | /* |
| 1607 | * Clear all beacons | 1610 | * Clear all beacons |
| @@ -1609,36 +1612,36 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 1609 | * the first byte since that byte contains the VALID and OWNER | 1612 | * the first byte since that byte contains the VALID and OWNER |
| 1610 | * bits which (when set to 0) will invalidate the entire beacon. | 1613 | * bits which (when set to 0) will invalidate the entire beacon. |
| 1611 | */ | 1614 | */ |
| 1612 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | 1615 | rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE0, 0); |
| 1613 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | 1616 | rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE1, 0); |
| 1614 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | 1617 | rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE2, 0); |
| 1615 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | 1618 | rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE3, 0); |
| 1616 | 1619 | ||
| 1617 | /* | 1620 | /* |
| 1618 | * We must clear the error counters. | 1621 | * We must clear the error counters. |
| 1619 | * These registers are cleared on read, | 1622 | * These registers are cleared on read, |
| 1620 | * so we may pass a useless variable to store the value. | 1623 | * so we may pass a useless variable to store the value. |
| 1621 | */ | 1624 | */ |
| 1622 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | 1625 | rt2x00mmio_register_read(rt2x00dev, STA_CSR0, ®); |
| 1623 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | 1626 | rt2x00mmio_register_read(rt2x00dev, STA_CSR1, ®); |
| 1624 | rt2x00pci_register_read(rt2x00dev, STA_CSR2, ®); | 1627 | rt2x00mmio_register_read(rt2x00dev, STA_CSR2, ®); |
| 1625 | 1628 | ||
| 1626 | /* | 1629 | /* |
| 1627 | * Reset MAC and BBP registers. | 1630 | * Reset MAC and BBP registers. |
| 1628 | */ | 1631 | */ |
| 1629 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | 1632 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); |
| 1630 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | 1633 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); |
| 1631 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | 1634 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); |
| 1632 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1635 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1633 | 1636 | ||
| 1634 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | 1637 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); |
| 1635 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | 1638 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); |
| 1636 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | 1639 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); |
| 1637 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1640 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1638 | 1641 | ||
| 1639 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | 1642 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); |
| 1640 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | 1643 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); |
| 1641 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | 1644 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); |
| 1642 | 1645 | ||
| 1643 | return 0; | 1646 | return 0; |
| 1644 | } | 1647 | } |
| @@ -1655,7 +1658,7 @@ static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 1655 | udelay(REGISTER_BUSY_DELAY); | 1658 | udelay(REGISTER_BUSY_DELAY); |
| 1656 | } | 1659 | } |
| 1657 | 1660 | ||
| 1658 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1661 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 1659 | return -EACCES; | 1662 | return -EACCES; |
| 1660 | } | 1663 | } |
| 1661 | 1664 | ||
| @@ -1722,11 +1725,11 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 1722 | * should clear the register to assure a clean state. | 1725 | * should clear the register to assure a clean state. |
| 1723 | */ | 1726 | */ |
| 1724 | if (state == STATE_RADIO_IRQ_ON) { | 1727 | if (state == STATE_RADIO_IRQ_ON) { |
| 1725 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 1728 | rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
| 1726 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 1729 | rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
| 1727 | 1730 | ||
| 1728 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); | 1731 | rt2x00mmio_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); |
| 1729 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); | 1732 | rt2x00mmio_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); |
| 1730 | } | 1733 | } |
| 1731 | 1734 | ||
| 1732 | /* | 1735 | /* |
| @@ -1735,15 +1738,15 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 1735 | */ | 1738 | */ |
| 1736 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); | 1739 | spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); |
| 1737 | 1740 | ||
| 1738 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 1741 | rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); |
| 1739 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); | 1742 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); |
| 1740 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); | 1743 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); |
| 1741 | rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); | 1744 | rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); |
| 1742 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); | 1745 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); |
| 1743 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); | 1746 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); |
| 1744 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 1747 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 1745 | 1748 | ||
| 1746 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | 1749 | rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); |
| 1747 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_0, mask); | 1750 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_0, mask); |
| 1748 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_1, mask); | 1751 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_1, mask); |
| 1749 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_2, mask); | 1752 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_2, mask); |
| @@ -1753,7 +1756,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
| 1753 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); | 1756 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); |
| 1754 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); | 1757 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); |
| 1755 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); | 1758 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); |
| 1756 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 1759 | rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
| 1757 | 1760 | ||
| 1758 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); | 1761 | spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); |
| 1759 | 1762 | ||
| @@ -1783,9 +1786,9 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 1783 | /* | 1786 | /* |
| 1784 | * Enable RX. | 1787 | * Enable RX. |
| 1785 | */ | 1788 | */ |
| 1786 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1789 | rt2x00mmio_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
| 1787 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | 1790 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); |
| 1788 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1791 | rt2x00mmio_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
| 1789 | 1792 | ||
| 1790 | return 0; | 1793 | return 0; |
| 1791 | } | 1794 | } |
| @@ -1795,7 +1798,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
| 1795 | /* | 1798 | /* |
| 1796 | * Disable power | 1799 | * Disable power |
| 1797 | */ | 1800 | */ |
| 1798 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1801 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
| 1799 | } | 1802 | } |
| 1800 | 1803 | ||
| 1801 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | 1804 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) |
| @@ -1806,10 +1809,10 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
| 1806 | 1809 | ||
| 1807 | put_to_sleep = (state != STATE_AWAKE); | 1810 | put_to_sleep = (state != STATE_AWAKE); |
| 1808 | 1811 | ||
| 1809 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | 1812 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR12, ®); |
| 1810 | rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); | 1813 | rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); |
| 1811 | rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); | 1814 | rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); |
| 1812 | rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); | 1815 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR12, reg); |
| 1813 | 1816 | ||
| 1814 | /* | 1817 | /* |
| 1815 | * Device is not guaranteed to be in the requested state yet. | 1818 | * Device is not guaranteed to be in the requested state yet. |
| @@ -1817,11 +1820,11 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
| 1817 | * device has entered the correct state. | 1820 | * device has entered the correct state. |
| 1818 | */ | 1821 | */ |
| 1819 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1822 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
| 1820 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®2); | 1823 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR12, ®2); |
| 1821 | state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE); | 1824 | state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE); |
| 1822 | if (state == !put_to_sleep) | 1825 | if (state == !put_to_sleep) |
| 1823 | return 0; | 1826 | return 0; |
| 1824 | rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); | 1827 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR12, reg); |
| 1825 | msleep(10); | 1828 | msleep(10); |
| 1826 | } | 1829 | } |
| 1827 | 1830 | ||
| @@ -1856,8 +1859,8 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 1856 | } | 1859 | } |
| 1857 | 1860 | ||
| 1858 | if (unlikely(retval)) | 1861 | if (unlikely(retval)) |
| 1859 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 1862 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 1860 | state, retval); | 1863 | state, retval); |
| 1861 | 1864 | ||
| 1862 | return retval; | 1865 | return retval; |
| 1863 | } | 1866 | } |
| @@ -1869,7 +1872,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, | |||
| 1869 | struct txentry_desc *txdesc) | 1872 | struct txentry_desc *txdesc) |
| 1870 | { | 1873 | { |
| 1871 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1874 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
| 1872 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1875 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1873 | __le32 *txd = entry_priv->desc; | 1876 | __le32 *txd = entry_priv->desc; |
| 1874 | u32 word; | 1877 | u32 word; |
| 1875 | 1878 | ||
| @@ -1967,7 +1970,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
| 1967 | struct txentry_desc *txdesc) | 1970 | struct txentry_desc *txdesc) |
| 1968 | { | 1971 | { |
| 1969 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1972 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| 1970 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1973 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 1971 | unsigned int beacon_base; | 1974 | unsigned int beacon_base; |
| 1972 | unsigned int padding_len; | 1975 | unsigned int padding_len; |
| 1973 | u32 orig_reg, reg; | 1976 | u32 orig_reg, reg; |
| @@ -1976,10 +1979,10 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
| 1976 | * Disable beaconing while we are reloading the beacon data, | 1979 | * Disable beaconing while we are reloading the beacon data, |
| 1977 | * otherwise we might be sending out invalid data. | 1980 | * otherwise we might be sending out invalid data. |
| 1978 | */ | 1981 | */ |
| 1979 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1982 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 1980 | orig_reg = reg; | 1983 | orig_reg = reg; |
| 1981 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1984 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
| 1982 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1985 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 1983 | 1986 | ||
| 1984 | /* | 1987 | /* |
| 1985 | * Write the TX descriptor for the beacon. | 1988 | * Write the TX descriptor for the beacon. |
| @@ -1996,19 +1999,19 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
| 1996 | */ | 1999 | */ |
| 1997 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 2000 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
| 1998 | if (padding_len && skb_pad(entry->skb, padding_len)) { | 2001 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
| 1999 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | 2002 | rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); |
| 2000 | /* skb freed by skb_pad() on failure */ | 2003 | /* skb freed by skb_pad() on failure */ |
| 2001 | entry->skb = NULL; | 2004 | entry->skb = NULL; |
| 2002 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg); | 2005 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, orig_reg); |
| 2003 | return; | 2006 | return; |
| 2004 | } | 2007 | } |
| 2005 | 2008 | ||
| 2006 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 2009 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
| 2007 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | 2010 | rt2x00mmio_register_multiwrite(rt2x00dev, beacon_base, |
| 2008 | entry_priv->desc, TXINFO_SIZE); | 2011 | entry_priv->desc, TXINFO_SIZE); |
| 2009 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, | 2012 | rt2x00mmio_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, |
| 2010 | entry->skb->data, | 2013 | entry->skb->data, |
| 2011 | entry->skb->len + padding_len); | 2014 | entry->skb->len + padding_len); |
| 2012 | 2015 | ||
| 2013 | /* | 2016 | /* |
| 2014 | * Enable beaconing again. | 2017 | * Enable beaconing again. |
| @@ -2016,10 +2019,10 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
| 2016 | * For Wi-Fi faily generated beacons between participating | 2019 | * For Wi-Fi faily generated beacons between participating |
| 2017 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 2020 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
| 2018 | */ | 2021 | */ |
| 2019 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); | 2022 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); |
| 2020 | 2023 | ||
| 2021 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 2024 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
| 2022 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 2025 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 2023 | 2026 | ||
| 2024 | /* | 2027 | /* |
| 2025 | * Clean up beacon skb. | 2028 | * Clean up beacon skb. |
| @@ -2037,21 +2040,21 @@ static void rt61pci_clear_beacon(struct queue_entry *entry) | |||
| 2037 | * Disable beaconing while we are reloading the beacon data, | 2040 | * Disable beaconing while we are reloading the beacon data, |
| 2038 | * otherwise we might be sending out invalid data. | 2041 | * otherwise we might be sending out invalid data. |
| 2039 | */ | 2042 | */ |
| 2040 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 2043 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); |
| 2041 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 2044 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
| 2042 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 2045 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 2043 | 2046 | ||
| 2044 | /* | 2047 | /* |
| 2045 | * Clear beacon. | 2048 | * Clear beacon. |
| 2046 | */ | 2049 | */ |
| 2047 | rt2x00pci_register_write(rt2x00dev, | 2050 | rt2x00mmio_register_write(rt2x00dev, |
| 2048 | HW_BEACON_OFFSET(entry->entry_idx), 0); | 2051 | HW_BEACON_OFFSET(entry->entry_idx), 0); |
| 2049 | 2052 | ||
| 2050 | /* | 2053 | /* |
| 2051 | * Enable beaconing again. | 2054 | * Enable beaconing again. |
| 2052 | */ | 2055 | */ |
| 2053 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 2056 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
| 2054 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 2057 | rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); |
| 2055 | } | 2058 | } |
| 2056 | 2059 | ||
| 2057 | /* | 2060 | /* |
| @@ -2089,7 +2092,7 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
| 2089 | struct rxdone_entry_desc *rxdesc) | 2092 | struct rxdone_entry_desc *rxdesc) |
| 2090 | { | 2093 | { |
| 2091 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 2094 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| 2092 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 2095 | struct queue_entry_priv_mmio *entry_priv = entry->priv_data; |
| 2093 | u32 word0; | 2096 | u32 word0; |
| 2094 | u32 word1; | 2097 | u32 word1; |
| 2095 | 2098 | ||
| @@ -2155,7 +2158,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 2155 | struct data_queue *queue; | 2158 | struct data_queue *queue; |
| 2156 | struct queue_entry *entry; | 2159 | struct queue_entry *entry; |
| 2157 | struct queue_entry *entry_done; | 2160 | struct queue_entry *entry_done; |
| 2158 | struct queue_entry_priv_pci *entry_priv; | 2161 | struct queue_entry_priv_mmio *entry_priv; |
| 2159 | struct txdone_entry_desc txdesc; | 2162 | struct txdone_entry_desc txdesc; |
| 2160 | u32 word; | 2163 | u32 word; |
| 2161 | u32 reg; | 2164 | u32 reg; |
| @@ -2173,7 +2176,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 2173 | * tx ring size for now. | 2176 | * tx ring size for now. |
| 2174 | */ | 2177 | */ |
| 2175 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { | 2178 | for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { |
| 2176 | rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); | 2179 | rt2x00mmio_register_read(rt2x00dev, STA_CSR4, ®); |
| 2177 | if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) | 2180 | if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) |
| 2178 | break; | 2181 | break; |
| 2179 | 2182 | ||
| @@ -2207,9 +2210,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
| 2207 | /* Catch up. | 2210 | /* Catch up. |
| 2208 | * Just report any entries we missed as failed. | 2211 | * Just report any entries we missed as failed. |
| 2209 | */ | 2212 | */ |
| 2210 | WARNING(rt2x00dev, | 2213 | rt2x00_warn(rt2x00dev, "TX status report missed for entry %d\n", |
| 2211 | "TX status report missed for entry %d\n", | 2214 | entry_done->entry_idx); |
| 2212 | entry_done->entry_idx); | ||
| 2213 | 2215 | ||
| 2214 | rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); | 2216 | rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); |
| 2215 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 2217 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
| @@ -2260,9 +2262,9 @@ static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, | |||
| 2260 | */ | 2262 | */ |
| 2261 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 2263 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 2262 | 2264 | ||
| 2263 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 2265 | rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); |
| 2264 | rt2x00_set_field32(®, irq_field, 0); | 2266 | rt2x00_set_field32(®, irq_field, 0); |
| 2265 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 2267 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 2266 | 2268 | ||
| 2267 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 2269 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 2268 | } | 2270 | } |
| @@ -2278,9 +2280,9 @@ static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, | |||
| 2278 | */ | 2280 | */ |
| 2279 | spin_lock_irq(&rt2x00dev->irqmask_lock); | 2281 | spin_lock_irq(&rt2x00dev->irqmask_lock); |
| 2280 | 2282 | ||
| 2281 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | 2283 | rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); |
| 2282 | rt2x00_set_field32(®, irq_field, 0); | 2284 | rt2x00_set_field32(®, irq_field, 0); |
| 2283 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 2285 | rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
| 2284 | 2286 | ||
| 2285 | spin_unlock_irq(&rt2x00dev->irqmask_lock); | 2287 | spin_unlock_irq(&rt2x00dev->irqmask_lock); |
| 2286 | } | 2288 | } |
| @@ -2304,7 +2306,7 @@ static void rt61pci_tbtt_tasklet(unsigned long data) | |||
| 2304 | static void rt61pci_rxdone_tasklet(unsigned long data) | 2306 | static void rt61pci_rxdone_tasklet(unsigned long data) |
| 2305 | { | 2307 | { |
| 2306 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 2308 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
| 2307 | if (rt2x00pci_rxdone(rt2x00dev)) | 2309 | if (rt2x00mmio_rxdone(rt2x00dev)) |
| 2308 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); | 2310 | tasklet_schedule(&rt2x00dev->rxdone_tasklet); |
| 2309 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 2311 | else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 2310 | rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); | 2312 | rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); |
| @@ -2314,8 +2316,8 @@ static void rt61pci_autowake_tasklet(unsigned long data) | |||
| 2314 | { | 2316 | { |
| 2315 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 2317 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
| 2316 | rt61pci_wakeup(rt2x00dev); | 2318 | rt61pci_wakeup(rt2x00dev); |
| 2317 | rt2x00pci_register_write(rt2x00dev, | 2319 | rt2x00mmio_register_write(rt2x00dev, |
| 2318 | M2H_CMD_DONE_CSR, 0xffffffff); | 2320 | M2H_CMD_DONE_CSR, 0xffffffff); |
| 2319 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 2321 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 2320 | rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP); | 2322 | rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP); |
| 2321 | } | 2323 | } |
| @@ -2330,11 +2332,11 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
| 2330 | * Get the interrupt sources & saved to local variable. | 2332 | * Get the interrupt sources & saved to local variable. |
| 2331 | * Write register value back to clear pending interrupts. | 2333 | * Write register value back to clear pending interrupts. |
| 2332 | */ | 2334 | */ |
| 2333 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); | 2335 | rt2x00mmio_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); |
| 2334 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); | 2336 | rt2x00mmio_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); |
| 2335 | 2337 | ||
| 2336 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 2338 | rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
| 2337 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | 2339 | rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); |
| 2338 | 2340 | ||
| 2339 | if (!reg && !reg_mcu) | 2341 | if (!reg && !reg_mcu) |
| 2340 | return IRQ_NONE; | 2342 | return IRQ_NONE; |
| @@ -2371,13 +2373,13 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
| 2371 | */ | 2373 | */ |
| 2372 | spin_lock(&rt2x00dev->irqmask_lock); | 2374 | spin_lock(&rt2x00dev->irqmask_lock); |
| 2373 | 2375 | ||
| 2374 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | 2376 | rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); |
| 2375 | reg |= mask; | 2377 | reg |= mask; |
| 2376 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | 2378 | rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); |
| 2377 | 2379 | ||
| 2378 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | 2380 | rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); |
| 2379 | reg |= mask_mcu; | 2381 | reg |= mask_mcu; |
| 2380 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | 2382 | rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); |
| 2381 | 2383 | ||
| 2382 | spin_unlock(&rt2x00dev->irqmask_lock); | 2384 | spin_unlock(&rt2x00dev->irqmask_lock); |
| 2383 | 2385 | ||
| @@ -2395,7 +2397,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2395 | u8 *mac; | 2397 | u8 *mac; |
| 2396 | s8 value; | 2398 | s8 value; |
| 2397 | 2399 | ||
| 2398 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | 2400 | rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); |
| 2399 | 2401 | ||
| 2400 | eeprom.data = rt2x00dev; | 2402 | eeprom.data = rt2x00dev; |
| 2401 | eeprom.register_read = rt61pci_eepromregister_read; | 2403 | eeprom.register_read = rt61pci_eepromregister_read; |
| @@ -2416,7 +2418,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2416 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 2418 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 2417 | if (!is_valid_ether_addr(mac)) { | 2419 | if (!is_valid_ether_addr(mac)) { |
| 2418 | eth_random_addr(mac); | 2420 | eth_random_addr(mac); |
| 2419 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 2421 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 2420 | } | 2422 | } |
| 2421 | 2423 | ||
| 2422 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 2424 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); |
| @@ -2431,7 +2433,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2431 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | 2433 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); |
| 2432 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); | 2434 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); |
| 2433 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 2435 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); |
| 2434 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 2436 | rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); |
| 2435 | } | 2437 | } |
| 2436 | 2438 | ||
| 2437 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | 2439 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); |
| @@ -2444,7 +2446,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2444 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | 2446 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); |
| 2445 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | 2447 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); |
| 2446 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | 2448 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); |
| 2447 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 2449 | rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); |
| 2448 | } | 2450 | } |
| 2449 | 2451 | ||
| 2450 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); | 2452 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); |
| @@ -2452,7 +2454,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2452 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, | 2454 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, |
| 2453 | LED_MODE_DEFAULT); | 2455 | LED_MODE_DEFAULT); |
| 2454 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); | 2456 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); |
| 2455 | EEPROM(rt2x00dev, "Led: 0x%04x\n", word); | 2457 | rt2x00_eeprom_dbg(rt2x00dev, "Led: 0x%04x\n", word); |
| 2456 | } | 2458 | } |
| 2457 | 2459 | ||
| 2458 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | 2460 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); |
| @@ -2460,7 +2462,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2460 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | 2462 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); |
| 2461 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); | 2463 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); |
| 2462 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | 2464 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); |
| 2463 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | 2465 | rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); |
| 2464 | } | 2466 | } |
| 2465 | 2467 | ||
| 2466 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); | 2468 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); |
| @@ -2468,7 +2470,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2468 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | 2470 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); |
| 2469 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | 2471 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); |
| 2470 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | 2472 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); |
| 2471 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 2473 | rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); |
| 2472 | } else { | 2474 | } else { |
| 2473 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); | 2475 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); |
| 2474 | if (value < -10 || value > 10) | 2476 | if (value < -10 || value > 10) |
| @@ -2484,7 +2486,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2484 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 2486 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
| 2485 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 2487 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
| 2486 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 2488 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
| 2487 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); | 2489 | rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
| 2488 | } else { | 2490 | } else { |
| 2489 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 2491 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
| 2490 | if (value < -10 || value > 10) | 2492 | if (value < -10 || value > 10) |
| @@ -2513,7 +2515,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2513 | * Identify RF chipset. | 2515 | * Identify RF chipset. |
| 2514 | */ | 2516 | */ |
| 2515 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 2517 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
| 2516 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | 2518 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR0, ®); |
| 2517 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), | 2519 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), |
| 2518 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 2520 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
| 2519 | 2521 | ||
| @@ -2521,7 +2523,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 2521 | !rt2x00_rf(rt2x00dev, RF5325) && | 2523 | !rt2x00_rf(rt2x00dev, RF5325) && |
| 2522 | !rt2x00_rf(rt2x00dev, RF2527) && | 2524 | !rt2x00_rf(rt2x00dev, RF2527) && |
| 2523 | !rt2x00_rf(rt2x00dev, RF2529)) { | 2525 | !rt2x00_rf(rt2x00dev, RF2529)) { |
| 2524 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 2526 | rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); |
| 2525 | return -ENODEV; | 2527 | return -ENODEV; |
| 2526 | } | 2528 | } |
| 2527 | 2529 | ||
| @@ -2838,7 +2840,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 2838 | /* | 2840 | /* |
| 2839 | * Disable power saving. | 2841 | * Disable power saving. |
| 2840 | */ | 2842 | */ |
| 2841 | rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); | 2843 | rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); |
| 2842 | 2844 | ||
| 2843 | /* | 2845 | /* |
| 2844 | * Allocate eeprom data. | 2846 | * Allocate eeprom data. |
| @@ -2855,9 +2857,9 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
| 2855 | * Enable rfkill polling by setting GPIO direction of the | 2857 | * Enable rfkill polling by setting GPIO direction of the |
| 2856 | * rfkill switch GPIO pin correctly. | 2858 | * rfkill switch GPIO pin correctly. |
| 2857 | */ | 2859 | */ |
| 2858 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 2860 | rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); |
| 2859 | rt2x00_set_field32(®, MAC_CSR13_DIR5, 1); | 2861 | rt2x00_set_field32(®, MAC_CSR13_DIR5, 1); |
| 2860 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | 2862 | rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, reg); |
| 2861 | 2863 | ||
| 2862 | /* | 2864 | /* |
| 2863 | * Initialize hw specifications. | 2865 | * Initialize hw specifications. |
| @@ -2927,25 +2929,25 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, | |||
| 2927 | field.bit_offset = (queue_idx & 1) * 16; | 2929 | field.bit_offset = (queue_idx & 1) * 16; |
| 2928 | field.bit_mask = 0xffff << field.bit_offset; | 2930 | field.bit_mask = 0xffff << field.bit_offset; |
| 2929 | 2931 | ||
| 2930 | rt2x00pci_register_read(rt2x00dev, offset, ®); | 2932 | rt2x00mmio_register_read(rt2x00dev, offset, ®); |
| 2931 | rt2x00_set_field32(®, field, queue->txop); | 2933 | rt2x00_set_field32(®, field, queue->txop); |
| 2932 | rt2x00pci_register_write(rt2x00dev, offset, reg); | 2934 | rt2x00mmio_register_write(rt2x00dev, offset, reg); |
| 2933 | 2935 | ||
| 2934 | /* Update WMM registers */ | 2936 | /* Update WMM registers */ |
| 2935 | field.bit_offset = queue_idx * 4; | 2937 | field.bit_offset = queue_idx * 4; |
| 2936 | field.bit_mask = 0xf << field.bit_offset; | 2938 | field.bit_mask = 0xf << field.bit_offset; |
| 2937 | 2939 | ||
| 2938 | rt2x00pci_register_read(rt2x00dev, AIFSN_CSR, ®); | 2940 | rt2x00mmio_register_read(rt2x00dev, AIFSN_CSR, ®); |
| 2939 | rt2x00_set_field32(®, field, queue->aifs); | 2941 | rt2x00_set_field32(®, field, queue->aifs); |
| 2940 | rt2x00pci_register_write(rt2x00dev, AIFSN_CSR, reg); | 2942 | rt2x00mmio_register_write(rt2x00dev, AIFSN_CSR, reg); |
| 2941 | 2943 | ||
| 2942 | rt2x00pci_register_read(rt2x00dev, CWMIN_CSR, ®); | 2944 | rt2x00mmio_register_read(rt2x00dev, CWMIN_CSR, ®); |
| 2943 | rt2x00_set_field32(®, field, queue->cw_min); | 2945 | rt2x00_set_field32(®, field, queue->cw_min); |
| 2944 | rt2x00pci_register_write(rt2x00dev, CWMIN_CSR, reg); | 2946 | rt2x00mmio_register_write(rt2x00dev, CWMIN_CSR, reg); |
| 2945 | 2947 | ||
| 2946 | rt2x00pci_register_read(rt2x00dev, CWMAX_CSR, ®); | 2948 | rt2x00mmio_register_read(rt2x00dev, CWMAX_CSR, ®); |
| 2947 | rt2x00_set_field32(®, field, queue->cw_max); | 2949 | rt2x00_set_field32(®, field, queue->cw_max); |
| 2948 | rt2x00pci_register_write(rt2x00dev, CWMAX_CSR, reg); | 2950 | rt2x00mmio_register_write(rt2x00dev, CWMAX_CSR, reg); |
| 2949 | 2951 | ||
| 2950 | return 0; | 2952 | return 0; |
| 2951 | } | 2953 | } |
| @@ -2956,9 +2958,9 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
| 2956 | u64 tsf; | 2958 | u64 tsf; |
| 2957 | u32 reg; | 2959 | u32 reg; |
| 2958 | 2960 | ||
| 2959 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR13, ®); | 2961 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR13, ®); |
| 2960 | tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; | 2962 | tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; |
| 2961 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR12, ®); | 2963 | rt2x00mmio_register_read(rt2x00dev, TXRX_CSR12, ®); |
| 2962 | tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); | 2964 | tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); |
| 2963 | 2965 | ||
| 2964 | return tsf; | 2966 | return tsf; |
| @@ -2997,8 +2999,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
| 2997 | .get_firmware_name = rt61pci_get_firmware_name, | 2999 | .get_firmware_name = rt61pci_get_firmware_name, |
| 2998 | .check_firmware = rt61pci_check_firmware, | 3000 | .check_firmware = rt61pci_check_firmware, |
| 2999 | .load_firmware = rt61pci_load_firmware, | 3001 | .load_firmware = rt61pci_load_firmware, |
| 3000 | .initialize = rt2x00pci_initialize, | 3002 | .initialize = rt2x00mmio_initialize, |
| 3001 | .uninitialize = rt2x00pci_uninitialize, | 3003 | .uninitialize = rt2x00mmio_uninitialize, |
| 3002 | .get_entry_state = rt61pci_get_entry_state, | 3004 | .get_entry_state = rt61pci_get_entry_state, |
| 3003 | .clear_entry = rt61pci_clear_entry, | 3005 | .clear_entry = rt61pci_clear_entry, |
| 3004 | .set_device_state = rt61pci_set_device_state, | 3006 | .set_device_state = rt61pci_set_device_state, |
| @@ -3009,7 +3011,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
| 3009 | .start_queue = rt61pci_start_queue, | 3011 | .start_queue = rt61pci_start_queue, |
| 3010 | .kick_queue = rt61pci_kick_queue, | 3012 | .kick_queue = rt61pci_kick_queue, |
| 3011 | .stop_queue = rt61pci_stop_queue, | 3013 | .stop_queue = rt61pci_stop_queue, |
| 3012 | .flush_queue = rt2x00pci_flush_queue, | 3014 | .flush_queue = rt2x00mmio_flush_queue, |
| 3013 | .write_tx_desc = rt61pci_write_tx_desc, | 3015 | .write_tx_desc = rt61pci_write_tx_desc, |
| 3014 | .write_beacon = rt61pci_write_beacon, | 3016 | .write_beacon = rt61pci_write_beacon, |
| 3015 | .clear_beacon = rt61pci_clear_beacon, | 3017 | .clear_beacon = rt61pci_clear_beacon, |
| @@ -3027,21 +3029,21 @@ static const struct data_queue_desc rt61pci_queue_rx = { | |||
| 3027 | .entry_num = 32, | 3029 | .entry_num = 32, |
| 3028 | .data_size = DATA_FRAME_SIZE, | 3030 | .data_size = DATA_FRAME_SIZE, |
| 3029 | .desc_size = RXD_DESC_SIZE, | 3031 | .desc_size = RXD_DESC_SIZE, |
| 3030 | .priv_size = sizeof(struct queue_entry_priv_pci), | 3032 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 3031 | }; | 3033 | }; |
| 3032 | 3034 | ||
| 3033 | static const struct data_queue_desc rt61pci_queue_tx = { | 3035 | static const struct data_queue_desc rt61pci_queue_tx = { |
| 3034 | .entry_num = 32, | 3036 | .entry_num = 32, |
| 3035 | .data_size = DATA_FRAME_SIZE, | 3037 | .data_size = DATA_FRAME_SIZE, |
| 3036 | .desc_size = TXD_DESC_SIZE, | 3038 | .desc_size = TXD_DESC_SIZE, |
| 3037 | .priv_size = sizeof(struct queue_entry_priv_pci), | 3039 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 3038 | }; | 3040 | }; |
| 3039 | 3041 | ||
| 3040 | static const struct data_queue_desc rt61pci_queue_bcn = { | 3042 | static const struct data_queue_desc rt61pci_queue_bcn = { |
| 3041 | .entry_num = 4, | 3043 | .entry_num = 4, |
| 3042 | .data_size = 0, /* No DMA required for beacons */ | 3044 | .data_size = 0, /* No DMA required for beacons */ |
| 3043 | .desc_size = TXINFO_SIZE, | 3045 | .desc_size = TXINFO_SIZE, |
| 3044 | .priv_size = sizeof(struct queue_entry_priv_pci), | 3046 | .priv_size = sizeof(struct queue_entry_priv_mmio), |
| 3045 | }; | 3047 | }; |
| 3046 | 3048 | ||
| 3047 | static const struct rt2x00_ops rt61pci_ops = { | 3049 | static const struct rt2x00_ops rt61pci_ops = { |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 24eec66e9fd2..377e09bb0b81 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -739,7 +739,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev, | |||
| 739 | u16 eeprom; | 739 | u16 eeprom; |
| 740 | short lna_gain = 0; | 740 | short lna_gain = 0; |
| 741 | 741 | ||
| 742 | if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { | 742 | if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { |
| 743 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) | 743 | if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) |
| 744 | lna_gain += 14; | 744 | lna_gain += 14; |
| 745 | 745 | ||
| @@ -1122,7 +1122,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1122 | } | 1122 | } |
| 1123 | 1123 | ||
| 1124 | if (!reg) { | 1124 | if (!reg) { |
| 1125 | ERROR(rt2x00dev, "Unstable hardware.\n"); | 1125 | rt2x00_err(rt2x00dev, "Unstable hardware\n"); |
| 1126 | return -EBUSY; | 1126 | return -EBUSY; |
| 1127 | } | 1127 | } |
| 1128 | 1128 | ||
| @@ -1139,7 +1139,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 1139 | 0, USB_MODE_FIRMWARE, | 1139 | 0, USB_MODE_FIRMWARE, |
| 1140 | REGISTER_TIMEOUT_FIRMWARE); | 1140 | REGISTER_TIMEOUT_FIRMWARE); |
| 1141 | if (status < 0) { | 1141 | if (status < 0) { |
| 1142 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 1142 | rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n"); |
| 1143 | return status; | 1143 | return status; |
| 1144 | } | 1144 | } |
| 1145 | 1145 | ||
| @@ -1305,7 +1305,7 @@ static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |||
| 1305 | udelay(REGISTER_BUSY_DELAY); | 1305 | udelay(REGISTER_BUSY_DELAY); |
| 1306 | } | 1306 | } |
| 1307 | 1307 | ||
| 1308 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1308 | rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); |
| 1309 | return -EACCES; | 1309 | return -EACCES; |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| @@ -1443,8 +1443,8 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
| 1443 | } | 1443 | } |
| 1444 | 1444 | ||
| 1445 | if (unlikely(retval)) | 1445 | if (unlikely(retval)) |
| 1446 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | 1446 | rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", |
| 1447 | state, retval); | 1447 | state, retval); |
| 1448 | 1448 | ||
| 1449 | return retval; | 1449 | return retval; |
| 1450 | } | 1450 | } |
| @@ -1567,7 +1567,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
| 1567 | */ | 1567 | */ |
| 1568 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 1568 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
| 1569 | if (padding_len && skb_pad(entry->skb, padding_len)) { | 1569 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
| 1570 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | 1570 | rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); |
| 1571 | /* skb freed by skb_pad() on failure */ | 1571 | /* skb freed by skb_pad() on failure */ |
| 1572 | entry->skb = NULL; | 1572 | entry->skb = NULL; |
| 1573 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); | 1573 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); |
| @@ -1771,7 +1771,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1771 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | 1771 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); |
| 1772 | if (!is_valid_ether_addr(mac)) { | 1772 | if (!is_valid_ether_addr(mac)) { |
| 1773 | eth_random_addr(mac); | 1773 | eth_random_addr(mac); |
| 1774 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | 1774 | rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); |
| 1775 | } | 1775 | } |
| 1776 | 1776 | ||
| 1777 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | 1777 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); |
| @@ -1786,14 +1786,14 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1786 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | 1786 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); |
| 1787 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5226); | 1787 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5226); |
| 1788 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 1788 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); |
| 1789 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 1789 | rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); |
| 1790 | } | 1790 | } |
| 1791 | 1791 | ||
| 1792 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | 1792 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); |
| 1793 | if (word == 0xffff) { | 1793 | if (word == 0xffff) { |
| 1794 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA, 0); | 1794 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA, 0); |
| 1795 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | 1795 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); |
| 1796 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | 1796 | rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); |
| 1797 | } | 1797 | } |
| 1798 | 1798 | ||
| 1799 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); | 1799 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); |
| @@ -1809,7 +1809,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1809 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, | 1809 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, |
| 1810 | LED_MODE_DEFAULT); | 1810 | LED_MODE_DEFAULT); |
| 1811 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); | 1811 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); |
| 1812 | EEPROM(rt2x00dev, "Led: 0x%04x\n", word); | 1812 | rt2x00_eeprom_dbg(rt2x00dev, "Led: 0x%04x\n", word); |
| 1813 | } | 1813 | } |
| 1814 | 1814 | ||
| 1815 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | 1815 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); |
| @@ -1817,7 +1817,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1817 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | 1817 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); |
| 1818 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); | 1818 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); |
| 1819 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | 1819 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); |
| 1820 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | 1820 | rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); |
| 1821 | } | 1821 | } |
| 1822 | 1822 | ||
| 1823 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); | 1823 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); |
| @@ -1825,7 +1825,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1825 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | 1825 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); |
| 1826 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | 1826 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); |
| 1827 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | 1827 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); |
| 1828 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1828 | rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); |
| 1829 | } else { | 1829 | } else { |
| 1830 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); | 1830 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); |
| 1831 | if (value < -10 || value > 10) | 1831 | if (value < -10 || value > 10) |
| @@ -1841,7 +1841,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1841 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1841 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
| 1842 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1842 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
| 1843 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1843 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
| 1844 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); | 1844 | rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
| 1845 | } else { | 1845 | } else { |
| 1846 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1846 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
| 1847 | if (value < -10 || value > 10) | 1847 | if (value < -10 || value > 10) |
| @@ -1875,7 +1875,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1875 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 1875 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
| 1876 | 1876 | ||
| 1877 | if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) { | 1877 | if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) { |
| 1878 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 1878 | rt2x00_err(rt2x00dev, "Invalid RT chipset detected\n"); |
| 1879 | return -ENODEV; | 1879 | return -ENODEV; |
| 1880 | } | 1880 | } |
| 1881 | 1881 | ||
| @@ -1883,7 +1883,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
| 1883 | !rt2x00_rf(rt2x00dev, RF2528) && | 1883 | !rt2x00_rf(rt2x00dev, RF2528) && |
| 1884 | !rt2x00_rf(rt2x00dev, RF5225) && | 1884 | !rt2x00_rf(rt2x00dev, RF5225) && |
| 1885 | !rt2x00_rf(rt2x00dev, RF2527)) { | 1885 | !rt2x00_rf(rt2x00dev, RF2527)) { |
| 1886 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 1886 | rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); |
| 1887 | return -ENODEV; | 1887 | return -ENODEV; |
| 1888 | } | 1888 | } |
| 1889 | 1889 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 1b3c2843221d..91a04e2b8ece 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
| @@ -147,8 +147,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 147 | signal = priv->rf->calc_rssi(agc, sq); | 147 | signal = priv->rf->calc_rssi(agc, sq); |
| 148 | } | 148 | } |
| 149 | rx_status.signal = signal; | 149 | rx_status.signal = signal; |
| 150 | rx_status.freq = dev->conf.channel->center_freq; | 150 | rx_status.freq = dev->conf.chandef.chan->center_freq; |
| 151 | rx_status.band = dev->conf.channel->band; | 151 | rx_status.band = dev->conf.chandef.chan->band; |
| 152 | rx_status.mactime = le64_to_cpu(entry->tsft); | 152 | rx_status.mactime = le64_to_cpu(entry->tsft); |
| 153 | rx_status.flag |= RX_FLAG_MACTIME_START; | 153 | rx_status.flag |= RX_FLAG_MACTIME_START; |
| 154 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) | 154 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c index 5ee7589dd546..077ff92cc139 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c +++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c | |||
| @@ -82,7 +82,8 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
| 82 | struct ieee80211_conf *conf) | 82 | struct ieee80211_conf *conf) |
| 83 | { | 83 | { |
| 84 | struct rtl8180_priv *priv = dev->priv; | 84 | struct rtl8180_priv *priv = dev->priv; |
| 85 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 85 | int channel = |
| 86 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
| 86 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; | 87 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
| 87 | u32 chan = channel - 1; | 88 | u32 chan = channel - 1; |
| 88 | 89 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c index 667b3363d437..4715000c94dd 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/max2820.c +++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c | |||
| @@ -95,7 +95,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
| 95 | { | 95 | { |
| 96 | struct rtl8180_priv *priv = dev->priv; | 96 | struct rtl8180_priv *priv = dev->priv; |
| 97 | int channel = conf ? | 97 | int channel = conf ? |
| 98 | ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; | 98 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1; |
| 99 | unsigned int chan_idx = channel - 1; | 99 | unsigned int chan_idx = channel - 1; |
| 100 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | 100 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; |
| 101 | u32 chan = max2820_chan[chan_idx]; | 101 | u32 chan = max2820_chan[chan_idx]; |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c index 7c4574ba9d75..cc2a5412c1f0 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c | |||
| @@ -719,7 +719,8 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
| 719 | struct ieee80211_conf *conf) | 719 | struct ieee80211_conf *conf) |
| 720 | { | 720 | { |
| 721 | struct rtl8180_priv *priv = dev->priv; | 721 | struct rtl8180_priv *priv = dev->priv; |
| 722 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | 722 | int chan = |
| 723 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
| 723 | 724 | ||
| 724 | if (priv->rf->init == rtl8225_rf_init) | 725 | if (priv->rf->init == rtl8225_rf_init) |
| 725 | rtl8225_rf_set_tx_power(dev, chan); | 726 | rtl8225_rf_set_tx_power(dev, chan); |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c index 44771a6286af..b3ec40f6bd23 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c +++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c | |||
| @@ -105,7 +105,8 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
| 105 | struct ieee80211_conf *conf) | 105 | struct ieee80211_conf *conf) |
| 106 | { | 106 | { |
| 107 | struct rtl8180_priv *priv = dev->priv; | 107 | struct rtl8180_priv *priv = dev->priv; |
| 108 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 108 | int channel = |
| 109 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
| 109 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; | 110 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
| 110 | u32 chan = sa2400_chan[channel - 1]; | 111 | u32 chan = sa2400_chan[channel - 1]; |
| 111 | 112 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 4574bd213705..f49220e234b0 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
| @@ -379,8 +379,8 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
| 379 | rate = (flags >> 20) & 0xF; | 379 | rate = (flags >> 20) & 0xF; |
| 380 | skb_trim(skb, flags & 0x0FFF); | 380 | skb_trim(skb, flags & 0x0FFF); |
| 381 | rx_status.rate_idx = rate; | 381 | rx_status.rate_idx = rate; |
| 382 | rx_status.freq = dev->conf.channel->center_freq; | 382 | rx_status.freq = dev->conf.chandef.chan->center_freq; |
| 383 | rx_status.band = dev->conf.channel->band; | 383 | rx_status.band = dev->conf.chandef.chan->band; |
| 384 | rx_status.flag |= RX_FLAG_MACTIME_START; | 384 | rx_status.flag |= RX_FLAG_MACTIME_START; |
| 385 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) | 385 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) |
| 386 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; | 386 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c index 908903f721f5..f0bf35fedbaf 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c | |||
| @@ -905,7 +905,8 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
| 905 | struct ieee80211_conf *conf) | 905 | struct ieee80211_conf *conf) |
| 906 | { | 906 | { |
| 907 | struct rtl8187_priv *priv = dev->priv; | 907 | struct rtl8187_priv *priv = dev->priv; |
| 908 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | 908 | int chan = |
| 909 | ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); | ||
| 909 | 910 | ||
| 910 | if (priv->rf->init == rtl8225_rf_init) | 911 | if (priv->rf->init == rtl8225_rf_init) |
| 911 | rtl8225_rf_set_tx_power(dev, chan); | 912 | rtl8225_rf_set_tx_power(dev, chan); |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index cac1fa912e8c..af59dd5718e1 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
| @@ -722,7 +722,7 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, | |||
| 722 | int rate_idx; | 722 | int rate_idx; |
| 723 | 723 | ||
| 724 | if (false == isht) { | 724 | if (false == isht) { |
| 725 | if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) { | 725 | if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) { |
| 726 | switch (desc_rate) { | 726 | switch (desc_rate) { |
| 727 | case DESC92_RATE1M: | 727 | case DESC92_RATE1M: |
| 728 | rate_idx = 0; | 728 | rate_idx = 0; |
| @@ -987,8 +987,8 @@ static bool addbareq_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 987 | if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) { | 987 | if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) { |
| 988 | skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid); | 988 | skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid); |
| 989 | if (skb_delba) { | 989 | if (skb_delba) { |
| 990 | rx_status.freq = hw->conf.channel->center_freq; | 990 | rx_status.freq = hw->conf.chandef.chan->center_freq; |
| 991 | rx_status.band = hw->conf.channel->band; | 991 | rx_status.band = hw->conf.chandef.chan->band; |
| 992 | rx_status.flag |= RX_FLAG_DECRYPTED; | 992 | rx_status.flag |= RX_FLAG_DECRYPTED; |
| 993 | rx_status.flag |= RX_FLAG_MACTIME_END; | 993 | rx_status.flag |= RX_FLAG_MACTIME_END; |
| 994 | rx_status.rate_idx = 0; | 994 | rx_status.rate_idx = 0; |
| @@ -1593,7 +1593,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, | |||
| 1593 | sta_entry->mimo_ps = smps; | 1593 | sta_entry->mimo_ps = smps; |
| 1594 | 1594 | ||
| 1595 | info->control.rates[0].idx = 0; | 1595 | info->control.rates[0].idx = 0; |
| 1596 | info->band = hw->conf.channel->band; | 1596 | info->band = hw->conf.chandef.chan->band; |
| 1597 | rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); | 1597 | rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); |
| 1598 | } | 1598 | } |
| 1599 | return 1; | 1599 | return 1; |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 2201b5cee08f..ee84844be008 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
| @@ -370,7 +370,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 372 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 373 | struct ieee80211_channel *channel = hw->conf.channel; | 373 | struct ieee80211_channel *channel = hw->conf.chandef.chan; |
| 374 | u8 wide_chan = (u8) channel->hw_value; | 374 | u8 wide_chan = (u8) channel->hw_value; |
| 375 | 375 | ||
| 376 | if (mac->act_scanning) | 376 | if (mac->act_scanning) |
| @@ -392,7 +392,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 392 | *info for cisco1253 bw20, so we modify | 392 | *info for cisco1253 bw20, so we modify |
| 393 | *it here based on UPPER & LOWER | 393 | *it here based on UPPER & LOWER |
| 394 | */ | 394 | */ |
| 395 | switch (hw->conf.channel_type) { | 395 | switch (cfg80211_get_chandef_type(&hw->conf.chandef)) { |
| 396 | case NL80211_CHAN_HT20: | 396 | case NL80211_CHAN_HT20: |
| 397 | case NL80211_CHAN_NO_HT: | 397 | case NL80211_CHAN_NO_HT: |
| 398 | /* SC */ | 398 | /* SC */ |
| @@ -450,7 +450,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 450 | rtlpriv->cfg->ops->switch_channel(hw); | 450 | rtlpriv->cfg->ops->switch_channel(hw); |
| 451 | rtlpriv->cfg->ops->set_channel_access(hw); | 451 | rtlpriv->cfg->ops->set_channel_access(hw); |
| 452 | rtlpriv->cfg->ops->set_bw_mode(hw, | 452 | rtlpriv->cfg->ops->set_bw_mode(hw, |
| 453 | hw->conf.channel_type); | 453 | cfg80211_get_chandef_type(&hw->conf.chandef)); |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | mutex_unlock(&rtlpriv->locks.conf_mutex); | 456 | mutex_unlock(&rtlpriv->locks.conf_mutex); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c index bcff49730a4e..b68cae3024fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c | |||
| @@ -1635,7 +1635,7 @@ static void _rtl8188e_read_power_value_fromprom(struct ieee80211_hw *hw, | |||
| 1635 | if (pwr2g->index_cck_base[path][i] == 0xFF) | 1635 | if (pwr2g->index_cck_base[path][i] == 0xFF) |
| 1636 | pwr2g->index_cck_base[path][i] = 0x2D; | 1636 | pwr2g->index_cck_base[path][i] = 0x2D; |
| 1637 | } | 1637 | } |
| 1638 | for (i = 0; i < MAX_CHNL_GROUP_24G-1; i++) { | 1638 | for (i = 0; i < MAX_CHNL_GROUP_24G; i++) { |
| 1639 | pwr2g->index_bw40_base[path][i] = hwinfo[eadr++]; | 1639 | pwr2g->index_bw40_base[path][i] = hwinfo[eadr++]; |
| 1640 | if (pwr2g->index_bw40_base[path][i] == 0xFF) | 1640 | if (pwr2g->index_bw40_base[path][i] == 0xFF) |
| 1641 | pwr2g->index_bw40_base[path][i] = 0x2D; | 1641 | pwr2g->index_bw40_base[path][i] = 0x2D; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index d075237add51..a8871d66d56a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | |||
| @@ -421,8 +421,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw, | |||
| 421 | RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, | 421 | RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, |
| 422 | "Get Wakeup Packet!! WakeMatch =%d\n", | 422 | "Get Wakeup Packet!! WakeMatch =%d\n", |
| 423 | status->wake_match); | 423 | status->wake_match); |
| 424 | rx_status->freq = hw->conf.channel->center_freq; | 424 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 425 | rx_status->band = hw->conf.channel->band; | 425 | rx_status->band = hw->conf.chandef.chan->band; |
| 426 | 426 | ||
| 427 | if (status->crc) | 427 | if (status->crc) |
| 428 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 428 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 926e2a34c766..d2d57a27a7c1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
| @@ -669,7 +669,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
| 669 | u8 thermalvalue, delta, delta_lck, delta_iqk; | 669 | u8 thermalvalue, delta, delta_lck, delta_iqk; |
| 670 | long ele_a, ele_d, temp_cck, val_x, value32; | 670 | long ele_a, ele_d, temp_cck, val_x, value32; |
| 671 | long val_y, ele_c = 0; | 671 | long val_y, ele_c = 0; |
| 672 | u8 ofdm_index[2], ofdm_index_old[2], cck_index_old = 0; | 672 | u8 ofdm_index[2], ofdm_index_old[2] = {0, 0}, cck_index_old = 0; |
| 673 | s8 cck_index = 0; | 673 | s8 cck_index = 0; |
| 674 | int i; | 674 | int i; |
| 675 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 675 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
| @@ -717,7 +717,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
| 717 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | 717 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { |
| 718 | if (ele_d == (ofdmswing_table[i] & | 718 | if (ele_d == (ofdmswing_table[i] & |
| 719 | MASKOFDM_D)) { | 719 | MASKOFDM_D)) { |
| 720 | 720 | ofdm_index_old[1] = (u8) i; | |
| 721 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | 721 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, |
| 722 | DBG_LOUD, | 722 | DBG_LOUD, |
| 723 | "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", | 723 | "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 65bf5fb97002..6ad23b413eb3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
| @@ -363,8 +363,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | |||
| 363 | 363 | ||
| 364 | stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc); | 364 | stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc); |
| 365 | 365 | ||
| 366 | rx_status->freq = hw->conf.channel->center_freq; | 366 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 367 | rx_status->band = hw->conf.channel->band; | 367 | rx_status->band = hw->conf.chandef.chan->band; |
| 368 | 368 | ||
| 369 | hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size | 369 | hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size |
| 370 | + stats->rx_bufshift); | 370 | + stats->rx_bufshift); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 710f7904ecdf..763cf1defab5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
| @@ -324,8 +324,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | |||
| 324 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | 324 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); |
| 325 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); | 325 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); |
| 326 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | 326 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); |
| 327 | rx_status->freq = hw->conf.channel->center_freq; | 327 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 328 | rx_status->band = hw->conf.channel->band; | 328 | rx_status->band = hw->conf.chandef.chan->band; |
| 329 | if (GET_RX_DESC_CRC32(pdesc)) | 329 | if (GET_RX_DESC_CRC32(pdesc)) |
| 330 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 330 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
| 331 | if (!GET_RX_DESC_SWDEC(pdesc)) | 331 | if (!GET_RX_DESC_SWDEC(pdesc)) |
| @@ -395,8 +395,8 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 395 | stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); | 395 | stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); |
| 396 | /* TODO: is center_freq changed when doing scan? */ | 396 | /* TODO: is center_freq changed when doing scan? */ |
| 397 | /* TODO: Shall we add protection or just skip those two step? */ | 397 | /* TODO: Shall we add protection or just skip those two step? */ |
| 398 | rx_status->freq = hw->conf.channel->center_freq; | 398 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 399 | rx_status->band = hw->conf.channel->band; | 399 | rx_status->band = hw->conf.chandef.chan->band; |
| 400 | if (GET_RX_DESC_CRC32(rxdesc)) | 400 | if (GET_RX_DESC_CRC32(rxdesc)) |
| 401 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 401 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
| 402 | if (!GET_RX_DESC_SWDEC(rxdesc)) | 402 | if (!GET_RX_DESC_SWDEC(rxdesc)) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 941080e03c06..b8ec718a0fab 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
| @@ -499,8 +499,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | |||
| 499 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | 499 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); |
| 500 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); | 500 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); |
| 501 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | 501 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); |
| 502 | rx_status->freq = hw->conf.channel->center_freq; | 502 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 503 | rx_status->band = hw->conf.channel->band; | 503 | rx_status->band = hw->conf.chandef.chan->band; |
| 504 | if (GET_RX_DESC_CRC32(pdesc)) | 504 | if (GET_RX_DESC_CRC32(pdesc)) |
| 505 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 505 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
| 506 | if (!GET_RX_DESC_SWDEC(pdesc)) | 506 | if (!GET_RX_DESC_SWDEC(pdesc)) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 960bc28cc51e..c7095118de6e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
| @@ -281,8 +281,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | |||
| 281 | if (stats->hwerror) | 281 | if (stats->hwerror) |
| 282 | return false; | 282 | return false; |
| 283 | 283 | ||
| 284 | rx_status->freq = hw->conf.channel->center_freq; | 284 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 285 | rx_status->band = hw->conf.channel->band; | 285 | rx_status->band = hw->conf.chandef.chan->band; |
| 286 | 286 | ||
| 287 | if (stats->crc) | 287 | if (stats->crc) |
| 288 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 288 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c index 6c64365308d3..c72758d8f4ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | |||
| @@ -304,8 +304,8 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, | |||
| 304 | 304 | ||
| 305 | status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); | 305 | status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); |
| 306 | 306 | ||
| 307 | rx_status->freq = hw->conf.channel->center_freq; | 307 | rx_status->freq = hw->conf.chandef.chan->center_freq; |
| 308 | rx_status->band = hw->conf.channel->band; | 308 | rx_status->band = hw->conf.chandef.chan->band; |
| 309 | 309 | ||
| 310 | if (status->crc) | 310 | if (status->crc) |
| 311 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 311 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index bbbf68cf50a7..3291ffa95273 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
| @@ -572,7 +572,8 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 572 | struct ieee80211_conf *conf = &hw->conf; | 572 | struct ieee80211_conf *conf = &hw->conf; |
| 573 | int channel, ret = 0; | 573 | int channel, ret = 0; |
| 574 | 574 | ||
| 575 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 575 | channel = ieee80211_frequency_to_channel( |
| 576 | conf->chandef.chan->center_freq); | ||
| 576 | 577 | ||
| 577 | wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", | 578 | wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", |
| 578 | channel, | 579 | channel, |
| @@ -1223,7 +1224,7 @@ static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 1223 | if (idx != 0) | 1224 | if (idx != 0) |
| 1224 | return -ENOENT; | 1225 | return -ENOENT; |
| 1225 | 1226 | ||
| 1226 | survey->channel = conf->channel; | 1227 | survey->channel = conf->chandef.chan; |
| 1227 | survey->filled = SURVEY_INFO_NOISE_DBM; | 1228 | survey->filled = SURVEY_INFO_NOISE_DBM; |
| 1228 | survey->noise = wl->noise; | 1229 | survey->noise = wl->noise; |
| 1229 | 1230 | ||
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 7dc9f965037d..7485dbae8c4b 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c | |||
| @@ -301,7 +301,7 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl, | |||
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | cmd->role_id = wlvif->role_id; | 303 | cmd->role_id = wlvif->role_id; |
| 304 | cmd->channel = ch_switch->channel->hw_value; | 304 | cmd->channel = ch_switch->chandef.chan->hw_value; |
| 305 | cmd->switch_time = ch_switch->count; | 305 | cmd->switch_time = ch_switch->count; |
| 306 | cmd->stop_tx = ch_switch->block_tx; | 306 | cmd->stop_tx = ch_switch->block_tx; |
| 307 | 307 | ||
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c index 1d1f6cc7a50a..7649c75cd68d 100644 --- a/drivers/net/wireless/ti/wl18xx/cmd.c +++ b/drivers/net/wireless/ti/wl18xx/cmd.c | |||
| @@ -42,11 +42,11 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl, | |||
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | cmd->role_id = wlvif->role_id; | 44 | cmd->role_id = wlvif->role_id; |
| 45 | cmd->channel = ch_switch->channel->hw_value; | 45 | cmd->channel = ch_switch->chandef.chan->hw_value; |
| 46 | cmd->switch_time = ch_switch->count; | 46 | cmd->switch_time = ch_switch->count; |
| 47 | cmd->stop_tx = ch_switch->block_tx; | 47 | cmd->stop_tx = ch_switch->block_tx; |
| 48 | 48 | ||
| 49 | switch (ch_switch->channel->band) { | 49 | switch (ch_switch->chandef.chan->band) { |
| 50 | case IEEE80211_BAND_2GHZ: | 50 | case IEEE80211_BAND_2GHZ: |
| 51 | cmd->band = WLCORE_BAND_2_4GHZ; | 51 | cmd->band = WLCORE_BAND_2_4GHZ; |
| 52 | break; | 52 | break; |
| @@ -55,7 +55,7 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl, | |||
| 55 | break; | 55 | break; |
| 56 | default: | 56 | default: |
| 57 | wl1271_error("invalid channel switch band: %d", | 57 | wl1271_error("invalid channel switch band: %d", |
| 58 | ch_switch->channel->band); | 58 | ch_switch->chandef.chan->band); |
| 59 | ret = -EINVAL; | 59 | ret = -EINVAL; |
| 60 | goto out_free; | 60 | goto out_free; |
| 61 | } | 61 | } |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index d10954c0c181..953111a502ee 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
| @@ -4502,7 +4502,7 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
| 4502 | if (idx != 0) | 4502 | if (idx != 0) |
| 4503 | return -ENOENT; | 4503 | return -ENOENT; |
| 4504 | 4504 | ||
| 4505 | survey->channel = conf->channel; | 4505 | survey->channel = conf->chandef.chan; |
| 4506 | survey->filled = 0; | 4506 | survey->filled = 0; |
| 4507 | return 0; | 4507 | return 0; |
| 4508 | } | 4508 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 114364b5d466..c6208a7988e4 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
| @@ -1156,10 +1156,10 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1156 | struct ieee80211_conf *conf = &hw->conf; | 1156 | struct ieee80211_conf *conf = &hw->conf; |
| 1157 | 1157 | ||
| 1158 | spin_lock_irq(&mac->lock); | 1158 | spin_lock_irq(&mac->lock); |
| 1159 | mac->channel = conf->channel->hw_value; | 1159 | mac->channel = conf->chandef.chan->hw_value; |
| 1160 | spin_unlock_irq(&mac->lock); | 1160 | spin_unlock_irq(&mac->lock); |
| 1161 | 1161 | ||
| 1162 | return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); | 1162 | return zd_chip_set_channel(&mac->chip, conf->chandef.chan->hw_value); |
| 1163 | } | 1163 | } |
| 1164 | 1164 | ||
| 1165 | static void zd_beacon_done(struct zd_mac *mac) | 1165 | static void zd_beacon_done(struct zd_mac *mac) |
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index e57034971ccc..4775d4e61b88 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig | |||
| @@ -26,6 +26,16 @@ config NFC_WILINK | |||
| 26 | Say Y here to compile support for Texas Instrument's NFC WiLink driver | 26 | Say Y here to compile support for Texas Instrument's NFC WiLink driver |
| 27 | into the kernel or say M to compile it as module. | 27 | into the kernel or say M to compile it as module. |
| 28 | 28 | ||
| 29 | config NFC_MEI_PHY | ||
| 30 | tristate "MEI bus NFC device support" | ||
| 31 | depends on INTEL_MEI_BUS_NFC && NFC_HCI | ||
| 32 | help | ||
| 33 | This adds support to use an mei bus nfc device. Select this if you | ||
| 34 | will use an HCI NFC driver for an NFC chip connected behind an | ||
| 35 | Intel's Management Engine chip. | ||
| 36 | |||
| 37 | If unsure, say N. | ||
| 38 | |||
| 29 | source "drivers/nfc/pn544/Kconfig" | 39 | source "drivers/nfc/pn544/Kconfig" |
| 30 | source "drivers/nfc/microread/Kconfig" | 40 | source "drivers/nfc/microread/Kconfig" |
| 31 | 41 | ||
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index a189ada0926a..aa6bd657ef40 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile | |||
| @@ -6,5 +6,6 @@ obj-$(CONFIG_NFC_PN544) += pn544/ | |||
| 6 | obj-$(CONFIG_NFC_MICROREAD) += microread/ | 6 | obj-$(CONFIG_NFC_MICROREAD) += microread/ |
| 7 | obj-$(CONFIG_NFC_PN533) += pn533.o | 7 | obj-$(CONFIG_NFC_PN533) += pn533.o |
| 8 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o | 8 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o |
| 9 | obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o | ||
| 9 | 10 | ||
| 10 | ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG | 11 | ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG |
diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c new file mode 100644 index 000000000000..b8f8abc422f0 --- /dev/null +++ b/drivers/nfc/mei_phy.c | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | /* | ||
| 2 | * MEI Library for mei bus nfc device access | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Intel Corporation. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the | ||
| 17 | * Free Software Foundation, Inc., | ||
| 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/nfc.h> | ||
| 24 | |||
| 25 | #include "mei_phy.h" | ||
| 26 | |||
| 27 | struct mei_nfc_hdr { | ||
| 28 | u8 cmd; | ||
| 29 | u8 status; | ||
| 30 | u16 req_id; | ||
| 31 | u32 reserved; | ||
| 32 | u16 data_size; | ||
| 33 | } __attribute__((packed)); | ||
| 34 | |||
| 35 | #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) | ||
| 36 | |||
| 37 | #define MEI_DUMP_SKB_IN(info, skb) \ | ||
| 38 | do { \ | ||
| 39 | pr_debug("%s:\n", info); \ | ||
| 40 | print_hex_dump_debug("mei in : ", DUMP_PREFIX_OFFSET, \ | ||
| 41 | 16, 1, (skb)->data, (skb)->len, false); \ | ||
| 42 | } while (0) | ||
| 43 | |||
| 44 | #define MEI_DUMP_SKB_OUT(info, skb) \ | ||
| 45 | do { \ | ||
| 46 | pr_debug("%s:\n", info); \ | ||
| 47 | print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET, \ | ||
| 48 | 16, 1, (skb)->data, (skb)->len, false); \ | ||
| 49 | } while (0) | ||
| 50 | |||
| 51 | int nfc_mei_phy_enable(void *phy_id) | ||
| 52 | { | ||
| 53 | int r; | ||
| 54 | struct nfc_mei_phy *phy = phy_id; | ||
| 55 | |||
| 56 | pr_info("%s\n", __func__); | ||
| 57 | |||
| 58 | if (phy->powered == 1) | ||
| 59 | return 0; | ||
| 60 | |||
| 61 | r = mei_cl_enable_device(phy->device); | ||
| 62 | if (r < 0) { | ||
| 63 | pr_err("MEI_PHY: Could not enable device\n"); | ||
| 64 | return r; | ||
| 65 | } | ||
| 66 | |||
| 67 | phy->powered = 1; | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | EXPORT_SYMBOL_GPL(nfc_mei_phy_enable); | ||
| 72 | |||
| 73 | void nfc_mei_phy_disable(void *phy_id) | ||
| 74 | { | ||
| 75 | struct nfc_mei_phy *phy = phy_id; | ||
| 76 | |||
| 77 | pr_info("%s\n", __func__); | ||
| 78 | |||
| 79 | mei_cl_disable_device(phy->device); | ||
| 80 | |||
| 81 | phy->powered = 0; | ||
| 82 | } | ||
| 83 | EXPORT_SYMBOL_GPL(nfc_mei_phy_disable); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Writing a frame must not return the number of written bytes. | ||
| 87 | * It must return either zero for success, or <0 for error. | ||
| 88 | * In addition, it must not alter the skb | ||
| 89 | */ | ||
| 90 | static int nfc_mei_phy_write(void *phy_id, struct sk_buff *skb) | ||
| 91 | { | ||
| 92 | struct nfc_mei_phy *phy = phy_id; | ||
| 93 | int r; | ||
| 94 | |||
| 95 | MEI_DUMP_SKB_OUT("mei frame sent", skb); | ||
| 96 | |||
| 97 | r = mei_cl_send(phy->device, skb->data, skb->len); | ||
| 98 | if (r > 0) | ||
| 99 | r = 0; | ||
| 100 | |||
| 101 | return r; | ||
| 102 | } | ||
| 103 | |||
| 104 | void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) | ||
| 105 | { | ||
| 106 | struct nfc_mei_phy *phy = context; | ||
| 107 | |||
| 108 | if (phy->hard_fault != 0) | ||
| 109 | return; | ||
| 110 | |||
| 111 | if (events & BIT(MEI_CL_EVENT_RX)) { | ||
| 112 | struct sk_buff *skb; | ||
| 113 | int reply_size; | ||
| 114 | |||
| 115 | skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL); | ||
| 116 | if (!skb) | ||
| 117 | return; | ||
| 118 | |||
| 119 | reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); | ||
| 120 | if (reply_size < MEI_NFC_HEADER_SIZE) { | ||
| 121 | kfree(skb); | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | skb_put(skb, reply_size); | ||
| 126 | skb_pull(skb, MEI_NFC_HEADER_SIZE); | ||
| 127 | |||
| 128 | MEI_DUMP_SKB_IN("mei frame read", skb); | ||
| 129 | |||
| 130 | nfc_hci_recv_frame(phy->hdev, skb); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | EXPORT_SYMBOL_GPL(nfc_mei_event_cb); | ||
| 134 | |||
| 135 | struct nfc_phy_ops mei_phy_ops = { | ||
| 136 | .write = nfc_mei_phy_write, | ||
| 137 | .enable = nfc_mei_phy_enable, | ||
| 138 | .disable = nfc_mei_phy_disable, | ||
| 139 | }; | ||
| 140 | EXPORT_SYMBOL_GPL(mei_phy_ops); | ||
| 141 | |||
| 142 | struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device) | ||
| 143 | { | ||
| 144 | struct nfc_mei_phy *phy; | ||
| 145 | |||
| 146 | phy = kzalloc(sizeof(struct nfc_mei_phy), GFP_KERNEL); | ||
| 147 | if (!phy) | ||
| 148 | return NULL; | ||
| 149 | |||
| 150 | phy->device = device; | ||
| 151 | mei_cl_set_drvdata(device, phy); | ||
| 152 | |||
| 153 | return phy; | ||
| 154 | } | ||
| 155 | EXPORT_SYMBOL_GPL(nfc_mei_phy_alloc); | ||
| 156 | |||
| 157 | void nfc_mei_phy_free(struct nfc_mei_phy *phy) | ||
| 158 | { | ||
| 159 | kfree(phy); | ||
| 160 | } | ||
| 161 | EXPORT_SYMBOL_GPL(nfc_mei_phy_free); | ||
| 162 | |||
| 163 | MODULE_LICENSE("GPL"); | ||
| 164 | MODULE_DESCRIPTION("mei bus NFC device interface"); | ||
diff --git a/drivers/nfc/mei_phy.h b/drivers/nfc/mei_phy.h new file mode 100644 index 000000000000..d669900f8278 --- /dev/null +++ b/drivers/nfc/mei_phy.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #ifndef __LOCAL_MEI_PHY_H_ | ||
| 2 | #define __LOCAL_MEI_PHY_H_ | ||
| 3 | |||
| 4 | #include <linux/mei_cl_bus.h> | ||
| 5 | #include <net/nfc/hci.h> | ||
| 6 | |||
| 7 | #define MEI_NFC_HEADER_SIZE 10 | ||
| 8 | #define MEI_NFC_MAX_HCI_PAYLOAD 300 | ||
| 9 | |||
| 10 | struct nfc_mei_phy { | ||
| 11 | struct mei_cl_device *device; | ||
| 12 | struct nfc_hci_dev *hdev; | ||
| 13 | |||
| 14 | int powered; | ||
| 15 | |||
| 16 | int hard_fault; /* | ||
| 17 | * < 0 if hardware error occured | ||
| 18 | * and prevents normal operation. | ||
| 19 | */ | ||
| 20 | }; | ||
| 21 | |||
| 22 | extern struct nfc_phy_ops mei_phy_ops; | ||
| 23 | |||
| 24 | int nfc_mei_phy_enable(void *phy_id); | ||
| 25 | void nfc_mei_phy_disable(void *phy_id); | ||
| 26 | void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context); | ||
| 27 | struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device); | ||
| 28 | void nfc_mei_phy_free(struct nfc_mei_phy *phy); | ||
| 29 | |||
| 30 | #endif /* __LOCAL_MEI_PHY_H_ */ | ||
diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig index 572305be6e37..951d5542f6bc 100644 --- a/drivers/nfc/microread/Kconfig +++ b/drivers/nfc/microread/Kconfig | |||
| @@ -25,7 +25,7 @@ config NFC_MICROREAD_I2C | |||
| 25 | 25 | ||
| 26 | config NFC_MICROREAD_MEI | 26 | config NFC_MICROREAD_MEI |
| 27 | tristate "NFC Microread MEI support" | 27 | tristate "NFC Microread MEI support" |
| 28 | depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC | 28 | depends on NFC_MICROREAD && NFC_MEI_PHY |
| 29 | ---help--- | 29 | ---help--- |
| 30 | This module adds support for the mei interface of adapters using | 30 | This module adds support for the mei interface of adapters using |
| 31 | Inside microread chipsets. Select this if your microread chipset | 31 | Inside microread chipsets. Select this if your microread chipset |
diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c index ca33ae193935..1ad044dce7b6 100644 --- a/drivers/nfc/microread/mei.c +++ b/drivers/nfc/microread/mei.c | |||
| @@ -19,151 +19,31 @@ | |||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/mod_devicetable.h> |
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/gpio.h> | ||
| 25 | #include <linux/mei_cl_bus.h> | ||
| 26 | |||
| 27 | #include <linux/nfc.h> | 23 | #include <linux/nfc.h> |
| 28 | #include <net/nfc/hci.h> | 24 | #include <net/nfc/hci.h> |
| 29 | #include <net/nfc/llc.h> | 25 | #include <net/nfc/llc.h> |
| 30 | 26 | ||
| 27 | #include "../mei_phy.h" | ||
| 31 | #include "microread.h" | 28 | #include "microread.h" |
| 32 | 29 | ||
| 33 | #define MICROREAD_DRIVER_NAME "microread" | 30 | #define MICROREAD_DRIVER_NAME "microread" |
| 34 | 31 | ||
| 35 | struct mei_nfc_hdr { | ||
| 36 | u8 cmd; | ||
| 37 | u8 status; | ||
| 38 | u16 req_id; | ||
| 39 | u32 reserved; | ||
| 40 | u16 data_size; | ||
| 41 | } __attribute__((packed)); | ||
| 42 | |||
| 43 | #define MEI_NFC_HEADER_SIZE 10 | ||
| 44 | #define MEI_NFC_MAX_HCI_PAYLOAD 300 | ||
| 45 | #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) | ||
| 46 | |||
| 47 | struct microread_mei_phy { | ||
| 48 | struct mei_cl_device *device; | ||
| 49 | struct nfc_hci_dev *hdev; | ||
| 50 | |||
| 51 | int powered; | ||
| 52 | |||
| 53 | int hard_fault; /* | ||
| 54 | * < 0 if hardware error occured (e.g. i2c err) | ||
| 55 | * and prevents normal operation. | ||
| 56 | */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | #define MEI_DUMP_SKB_IN(info, skb) \ | ||
| 60 | do { \ | ||
| 61 | pr_debug("%s:\n", info); \ | ||
| 62 | print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET, \ | ||
| 63 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
| 64 | } while (0) | ||
| 65 | |||
| 66 | #define MEI_DUMP_SKB_OUT(info, skb) \ | ||
| 67 | do { \ | ||
| 68 | pr_debug("%s:\n", info); \ | ||
| 69 | print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET, \ | ||
| 70 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
| 71 | } while (0) | ||
| 72 | |||
| 73 | static int microread_mei_enable(void *phy_id) | ||
| 74 | { | ||
| 75 | struct microread_mei_phy *phy = phy_id; | ||
| 76 | |||
| 77 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 78 | |||
| 79 | phy->powered = 1; | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static void microread_mei_disable(void *phy_id) | ||
| 85 | { | ||
| 86 | struct microread_mei_phy *phy = phy_id; | ||
| 87 | |||
| 88 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 89 | |||
| 90 | phy->powered = 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Writing a frame must not return the number of written bytes. | ||
| 95 | * It must return either zero for success, or <0 for error. | ||
| 96 | * In addition, it must not alter the skb | ||
| 97 | */ | ||
| 98 | static int microread_mei_write(void *phy_id, struct sk_buff *skb) | ||
| 99 | { | ||
| 100 | struct microread_mei_phy *phy = phy_id; | ||
| 101 | int r; | ||
| 102 | |||
| 103 | MEI_DUMP_SKB_OUT("mei frame sent", skb); | ||
| 104 | |||
| 105 | r = mei_cl_send(phy->device, skb->data, skb->len); | ||
| 106 | if (r > 0) | ||
| 107 | r = 0; | ||
| 108 | |||
| 109 | return r; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void microread_event_cb(struct mei_cl_device *device, u32 events, | ||
| 113 | void *context) | ||
| 114 | { | ||
| 115 | struct microread_mei_phy *phy = context; | ||
| 116 | |||
| 117 | if (phy->hard_fault != 0) | ||
| 118 | return; | ||
| 119 | |||
| 120 | if (events & BIT(MEI_CL_EVENT_RX)) { | ||
| 121 | struct sk_buff *skb; | ||
| 122 | int reply_size; | ||
| 123 | |||
| 124 | skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL); | ||
| 125 | if (!skb) | ||
| 126 | return; | ||
| 127 | |||
| 128 | reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); | ||
| 129 | if (reply_size < MEI_NFC_HEADER_SIZE) { | ||
| 130 | kfree(skb); | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | |||
| 134 | skb_put(skb, reply_size); | ||
| 135 | skb_pull(skb, MEI_NFC_HEADER_SIZE); | ||
| 136 | |||
| 137 | MEI_DUMP_SKB_IN("mei frame read", skb); | ||
| 138 | |||
| 139 | nfc_hci_recv_frame(phy->hdev, skb); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct nfc_phy_ops mei_phy_ops = { | ||
| 144 | .write = microread_mei_write, | ||
| 145 | .enable = microread_mei_enable, | ||
| 146 | .disable = microread_mei_disable, | ||
| 147 | }; | ||
| 148 | |||
| 149 | static int microread_mei_probe(struct mei_cl_device *device, | 32 | static int microread_mei_probe(struct mei_cl_device *device, |
| 150 | const struct mei_cl_device_id *id) | 33 | const struct mei_cl_device_id *id) |
| 151 | { | 34 | { |
| 152 | struct microread_mei_phy *phy; | 35 | struct nfc_mei_phy *phy; |
| 153 | int r; | 36 | int r; |
| 154 | 37 | ||
| 155 | pr_info("Probing NFC microread\n"); | 38 | pr_info("Probing NFC microread\n"); |
| 156 | 39 | ||
| 157 | phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL); | 40 | phy = nfc_mei_phy_alloc(device); |
| 158 | if (!phy) { | 41 | if (!phy) { |
| 159 | pr_err("Cannot allocate memory for microread mei phy.\n"); | 42 | pr_err("Cannot allocate memory for microread mei phy.\n"); |
| 160 | return -ENOMEM; | 43 | return -ENOMEM; |
| 161 | } | 44 | } |
| 162 | 45 | ||
| 163 | phy->device = device; | 46 | r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); |
| 164 | mei_cl_set_drvdata(device, phy); | ||
| 165 | |||
| 166 | r = mei_cl_register_event_cb(device, microread_event_cb, phy); | ||
| 167 | if (r) { | 47 | if (r) { |
| 168 | pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); | 48 | pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); |
| 169 | goto err_out; | 49 | goto err_out; |
| @@ -178,23 +58,22 @@ static int microread_mei_probe(struct mei_cl_device *device, | |||
| 178 | return 0; | 58 | return 0; |
| 179 | 59 | ||
| 180 | err_out: | 60 | err_out: |
| 181 | kfree(phy); | 61 | nfc_mei_phy_free(phy); |
| 182 | 62 | ||
| 183 | return r; | 63 | return r; |
| 184 | } | 64 | } |
| 185 | 65 | ||
| 186 | static int microread_mei_remove(struct mei_cl_device *device) | 66 | static int microread_mei_remove(struct mei_cl_device *device) |
| 187 | { | 67 | { |
| 188 | struct microread_mei_phy *phy = mei_cl_get_drvdata(device); | 68 | struct nfc_mei_phy *phy = mei_cl_get_drvdata(device); |
| 189 | 69 | ||
| 190 | pr_info("Removing microread\n"); | 70 | pr_info("Removing microread\n"); |
| 191 | 71 | ||
| 192 | microread_remove(phy->hdev); | 72 | microread_remove(phy->hdev); |
| 193 | 73 | ||
| 194 | if (phy->powered) | 74 | nfc_mei_phy_disable(phy); |
| 195 | microread_mei_disable(phy); | ||
| 196 | 75 | ||
| 197 | kfree(phy); | 76 | nfc_mei_phy_free(phy); |
| 198 | 77 | ||
| 199 | return 0; | 78 | return 0; |
| 200 | } | 79 | } |
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index f0f6763d67ae..8f6f2baa930d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
| @@ -1,9 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2011 Instituto Nokia de Tecnologia | 2 | * Copyright (C) 2011 Instituto Nokia de Tecnologia |
| 3 | * | 3 | * Copyright (C) 2012-2013 Tieto Poland |
| 4 | * Authors: | ||
| 5 | * Lauro Ramos Venancio <lauro.venancio@openbossa.org> | ||
| 6 | * Aloisio Almeida Jr <aloisio.almeida@openbossa.org> | ||
| 7 | * | 4 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
| @@ -30,7 +27,7 @@ | |||
| 30 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
| 31 | #include <net/nfc/nfc.h> | 28 | #include <net/nfc/nfc.h> |
| 32 | 29 | ||
| 33 | #define VERSION "0.1" | 30 | #define VERSION "0.2" |
| 34 | 31 | ||
| 35 | #define PN533_VENDOR_ID 0x4CC | 32 | #define PN533_VENDOR_ID 0x4CC |
| 36 | #define PN533_PRODUCT_ID 0x2533 | 33 | #define PN533_PRODUCT_ID 0x2533 |
| @@ -41,8 +38,12 @@ | |||
| 41 | #define SONY_VENDOR_ID 0x054c | 38 | #define SONY_VENDOR_ID 0x054c |
| 42 | #define PASORI_PRODUCT_ID 0x02e1 | 39 | #define PASORI_PRODUCT_ID 0x02e1 |
| 43 | 40 | ||
| 44 | #define PN533_DEVICE_STD 0x1 | 41 | #define ACS_VENDOR_ID 0x072f |
| 45 | #define PN533_DEVICE_PASORI 0x2 | 42 | #define ACR122U_PRODUCT_ID 0x2200 |
| 43 | |||
| 44 | #define PN533_DEVICE_STD 0x1 | ||
| 45 | #define PN533_DEVICE_PASORI 0x2 | ||
| 46 | #define PN533_DEVICE_ACR122U 0x3 | ||
| 46 | 47 | ||
| 47 | #define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\ | 48 | #define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\ |
| 48 | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\ | 49 | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\ |
| @@ -71,6 +72,11 @@ static const struct usb_device_id pn533_table[] = { | |||
| 71 | .idProduct = PASORI_PRODUCT_ID, | 72 | .idProduct = PASORI_PRODUCT_ID, |
| 72 | .driver_info = PN533_DEVICE_PASORI, | 73 | .driver_info = PN533_DEVICE_PASORI, |
| 73 | }, | 74 | }, |
| 75 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
| 76 | .idVendor = ACS_VENDOR_ID, | ||
| 77 | .idProduct = ACR122U_PRODUCT_ID, | ||
| 78 | .driver_info = PN533_DEVICE_ACR122U, | ||
| 79 | }, | ||
| 74 | { } | 80 | { } |
| 75 | }; | 81 | }; |
| 76 | MODULE_DEVICE_TABLE(usb, pn533_table); | 82 | MODULE_DEVICE_TABLE(usb, pn533_table); |
| @@ -78,32 +84,47 @@ MODULE_DEVICE_TABLE(usb, pn533_table); | |||
| 78 | /* How much time we spend listening for initiators */ | 84 | /* How much time we spend listening for initiators */ |
| 79 | #define PN533_LISTEN_TIME 2 | 85 | #define PN533_LISTEN_TIME 2 |
| 80 | 86 | ||
| 81 | /* frame definitions */ | 87 | /* Standard pn533 frame definitions */ |
| 82 | #define PN533_FRAME_HEADER_LEN (sizeof(struct pn533_frame) \ | 88 | #define PN533_STD_FRAME_HEADER_LEN (sizeof(struct pn533_std_frame) \ |
| 83 | + 2) /* data[0] TFI, data[1] CC */ | 89 | + 2) /* data[0] TFI, data[1] CC */ |
| 84 | #define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ | 90 | #define PN533_STD_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ |
| 85 | 91 | ||
| 86 | /* | 92 | /* |
| 87 | * Max extended frame payload len, excluding TFI and CC | 93 | * Max extended frame payload len, excluding TFI and CC |
| 88 | * which are already in PN533_FRAME_HEADER_LEN. | 94 | * which are already in PN533_FRAME_HEADER_LEN. |
| 89 | */ | 95 | */ |
| 90 | #define PN533_FRAME_MAX_PAYLOAD_LEN 263 | 96 | #define PN533_STD_FRAME_MAX_PAYLOAD_LEN 263 |
| 91 | 97 | ||
| 92 | #define PN533_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2), | 98 | #define PN533_STD_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2), |
| 93 | Postamble (1) */ | 99 | Postamble (1) */ |
| 94 | #define PN533_FRAME_CHECKSUM(f) (f->data[f->datalen]) | 100 | #define PN533_STD_FRAME_CHECKSUM(f) (f->data[f->datalen]) |
| 95 | #define PN533_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1]) | 101 | #define PN533_STD_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1]) |
| 96 | 102 | ||
| 97 | /* start of frame */ | 103 | /* start of frame */ |
| 98 | #define PN533_SOF 0x00FF | 104 | #define PN533_STD_FRAME_SOF 0x00FF |
| 105 | |||
| 106 | /* standard frame identifier: in/out/error */ | ||
| 107 | #define PN533_STD_FRAME_IDENTIFIER(f) (f->data[0]) /* TFI */ | ||
| 108 | #define PN533_STD_FRAME_DIR_OUT 0xD4 | ||
| 109 | #define PN533_STD_FRAME_DIR_IN 0xD5 | ||
| 110 | |||
| 111 | /* ACS ACR122 pn533 frame definitions */ | ||
| 112 | #define PN533_ACR122_TX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_tx_frame) \ | ||
| 113 | + 2) | ||
| 114 | #define PN533_ACR122_TX_FRAME_TAIL_LEN 0 | ||
| 115 | #define PN533_ACR122_RX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_rx_frame) \ | ||
| 116 | + 2) | ||
| 117 | #define PN533_ACR122_RX_FRAME_TAIL_LEN 2 | ||
| 118 | #define PN533_ACR122_FRAME_MAX_PAYLOAD_LEN PN533_STD_FRAME_MAX_PAYLOAD_LEN | ||
| 119 | |||
| 120 | /* CCID messages types */ | ||
| 121 | #define PN533_ACR122_PC_TO_RDR_ICCPOWERON 0x62 | ||
| 122 | #define PN533_ACR122_PC_TO_RDR_ESCAPE 0x6B | ||
| 99 | 123 | ||
| 100 | /* frame identifier: in/out/error */ | 124 | #define PN533_ACR122_RDR_TO_PC_ESCAPE 0x83 |
| 101 | #define PN533_FRAME_IDENTIFIER(f) (f->data[0]) | ||
| 102 | #define PN533_DIR_OUT 0xD4 | ||
| 103 | #define PN533_DIR_IN 0xD5 | ||
| 104 | 125 | ||
| 105 | /* PN533 Commands */ | 126 | /* PN533 Commands */ |
| 106 | #define PN533_FRAME_CMD(f) (f->data[1]) | 127 | #define PN533_STD_FRAME_CMD(f) (f->data[1]) |
| 107 | 128 | ||
| 108 | #define PN533_CMD_GET_FIRMWARE_VERSION 0x02 | 129 | #define PN533_CMD_GET_FIRMWARE_VERSION 0x02 |
| 109 | #define PN533_CMD_RF_CONFIGURATION 0x32 | 130 | #define PN533_CMD_RF_CONFIGURATION 0x32 |
| @@ -128,8 +149,6 @@ MODULE_DEVICE_TABLE(usb, pn533_table); | |||
| 128 | 149 | ||
| 129 | struct pn533; | 150 | struct pn533; |
| 130 | 151 | ||
| 131 | typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, int status); | ||
| 132 | |||
| 133 | typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg, | 152 | typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg, |
| 134 | struct sk_buff *resp); | 153 | struct sk_buff *resp); |
| 135 | 154 | ||
| @@ -144,9 +163,13 @@ struct pn533_fw_version { | |||
| 144 | }; | 163 | }; |
| 145 | 164 | ||
| 146 | /* PN533_CMD_RF_CONFIGURATION */ | 165 | /* PN533_CMD_RF_CONFIGURATION */ |
| 147 | #define PN533_CFGITEM_TIMING 0x02 | 166 | #define PN533_CFGITEM_RF_FIELD 0x01 |
| 167 | #define PN533_CFGITEM_TIMING 0x02 | ||
| 148 | #define PN533_CFGITEM_MAX_RETRIES 0x05 | 168 | #define PN533_CFGITEM_MAX_RETRIES 0x05 |
| 149 | #define PN533_CFGITEM_PASORI 0x82 | 169 | #define PN533_CFGITEM_PASORI 0x82 |
| 170 | |||
| 171 | #define PN533_CFGITEM_RF_FIELD_ON 0x1 | ||
| 172 | #define PN533_CFGITEM_RF_FIELD_OFF 0x0 | ||
| 150 | 173 | ||
| 151 | #define PN533_CONFIG_TIMING_102 0xb | 174 | #define PN533_CONFIG_TIMING_102 0xb |
| 152 | #define PN533_CONFIG_TIMING_204 0xc | 175 | #define PN533_CONFIG_TIMING_204 0xc |
| @@ -313,10 +336,17 @@ struct pn533_cmd_jump_dep_response { | |||
| 313 | #define PN533_INIT_TARGET_RESP_ACTIVE 0x1 | 336 | #define PN533_INIT_TARGET_RESP_ACTIVE 0x1 |
| 314 | #define PN533_INIT_TARGET_RESP_DEP 0x4 | 337 | #define PN533_INIT_TARGET_RESP_DEP 0x4 |
| 315 | 338 | ||
| 339 | enum pn533_protocol_type { | ||
| 340 | PN533_PROTO_REQ_ACK_RESP = 0, | ||
| 341 | PN533_PROTO_REQ_RESP | ||
| 342 | }; | ||
| 343 | |||
| 316 | struct pn533 { | 344 | struct pn533 { |
| 317 | struct usb_device *udev; | 345 | struct usb_device *udev; |
| 318 | struct usb_interface *interface; | 346 | struct usb_interface *interface; |
| 319 | struct nfc_dev *nfc_dev; | 347 | struct nfc_dev *nfc_dev; |
| 348 | u32 device_type; | ||
| 349 | enum pn533_protocol_type protocol_type; | ||
| 320 | 350 | ||
| 321 | struct urb *out_urb; | 351 | struct urb *out_urb; |
| 322 | struct urb *in_urb; | 352 | struct urb *in_urb; |
| @@ -329,21 +359,21 @@ struct pn533 { | |||
| 329 | struct work_struct poll_work; | 359 | struct work_struct poll_work; |
| 330 | struct work_struct mi_work; | 360 | struct work_struct mi_work; |
| 331 | struct work_struct tg_work; | 361 | struct work_struct tg_work; |
| 332 | struct timer_list listen_timer; | ||
| 333 | int wq_in_error; | ||
| 334 | int cancel_listen; | ||
| 335 | 362 | ||
| 336 | pn533_cmd_complete_t cmd_complete; | 363 | struct list_head cmd_queue; |
| 337 | void *cmd_complete_arg; | 364 | struct pn533_cmd *cmd; |
| 365 | u8 cmd_pending; | ||
| 366 | struct mutex cmd_lock; /* protects cmd queue */ | ||
| 367 | |||
| 338 | void *cmd_complete_mi_arg; | 368 | void *cmd_complete_mi_arg; |
| 339 | struct mutex cmd_lock; | ||
| 340 | u8 cmd; | ||
| 341 | 369 | ||
| 342 | struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1]; | 370 | struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1]; |
| 343 | u8 poll_mod_count; | 371 | u8 poll_mod_count; |
| 344 | u8 poll_mod_curr; | 372 | u8 poll_mod_curr; |
| 345 | u32 poll_protocols; | 373 | u32 poll_protocols; |
| 346 | u32 listen_protocols; | 374 | u32 listen_protocols; |
| 375 | struct timer_list listen_timer; | ||
| 376 | int cancel_listen; | ||
| 347 | 377 | ||
| 348 | u8 *gb; | 378 | u8 *gb; |
| 349 | size_t gb_len; | 379 | size_t gb_len; |
| @@ -352,24 +382,21 @@ struct pn533 { | |||
| 352 | u8 tgt_active_prot; | 382 | u8 tgt_active_prot; |
| 353 | u8 tgt_mode; | 383 | u8 tgt_mode; |
| 354 | 384 | ||
| 355 | u32 device_type; | ||
| 356 | |||
| 357 | struct list_head cmd_queue; | ||
| 358 | u8 cmd_pending; | ||
| 359 | |||
| 360 | struct pn533_frame_ops *ops; | 385 | struct pn533_frame_ops *ops; |
| 361 | }; | 386 | }; |
| 362 | 387 | ||
| 363 | struct pn533_cmd { | 388 | struct pn533_cmd { |
| 364 | struct list_head queue; | 389 | struct list_head queue; |
| 365 | u8 cmd_code; | 390 | u8 code; |
| 391 | int status; | ||
| 366 | struct sk_buff *req; | 392 | struct sk_buff *req; |
| 367 | struct sk_buff *resp; | 393 | struct sk_buff *resp; |
| 368 | int resp_len; | 394 | int resp_len; |
| 369 | void *arg; | 395 | pn533_send_async_complete_t complete_cb; |
| 396 | void *complete_cb_context; | ||
| 370 | }; | 397 | }; |
| 371 | 398 | ||
| 372 | struct pn533_frame { | 399 | struct pn533_std_frame { |
| 373 | u8 preamble; | 400 | u8 preamble; |
| 374 | __be16 start_frame; | 401 | __be16 start_frame; |
| 375 | u8 datalen; | 402 | u8 datalen; |
| @@ -393,14 +420,124 @@ struct pn533_frame_ops { | |||
| 393 | u8 (*get_cmd_code)(void *frame); | 420 | u8 (*get_cmd_code)(void *frame); |
| 394 | }; | 421 | }; |
| 395 | 422 | ||
| 423 | struct pn533_acr122_ccid_hdr { | ||
| 424 | u8 type; | ||
| 425 | u32 datalen; | ||
| 426 | u8 slot; | ||
| 427 | u8 seq; | ||
| 428 | u8 params[3]; /* 3 msg specific bytes or status, error and 1 specific | ||
| 429 | byte for reposnse msg */ | ||
| 430 | u8 data[]; /* payload */ | ||
| 431 | } __packed; | ||
| 432 | |||
| 433 | struct pn533_acr122_apdu_hdr { | ||
| 434 | u8 class; | ||
| 435 | u8 ins; | ||
| 436 | u8 p1; | ||
| 437 | u8 p2; | ||
| 438 | } __packed; | ||
| 439 | |||
| 440 | struct pn533_acr122_tx_frame { | ||
| 441 | struct pn533_acr122_ccid_hdr ccid; | ||
| 442 | struct pn533_acr122_apdu_hdr apdu; | ||
| 443 | u8 datalen; | ||
| 444 | u8 data[]; /* pn533 frame: TFI ... */ | ||
| 445 | } __packed; | ||
| 446 | |||
| 447 | struct pn533_acr122_rx_frame { | ||
| 448 | struct pn533_acr122_ccid_hdr ccid; | ||
| 449 | u8 data[]; /* pn533 frame : TFI ... */ | ||
| 450 | } __packed; | ||
| 451 | |||
| 452 | static void pn533_acr122_tx_frame_init(void *_frame, u8 cmd_code) | ||
| 453 | { | ||
| 454 | struct pn533_acr122_tx_frame *frame = _frame; | ||
| 455 | |||
| 456 | frame->ccid.type = PN533_ACR122_PC_TO_RDR_ESCAPE; | ||
| 457 | frame->ccid.datalen = sizeof(frame->apdu) + 1; /* sizeof(apdu_hdr) + | ||
| 458 | sizeof(datalen) */ | ||
| 459 | frame->ccid.slot = 0; | ||
| 460 | frame->ccid.seq = 0; | ||
| 461 | frame->ccid.params[0] = 0; | ||
| 462 | frame->ccid.params[1] = 0; | ||
| 463 | frame->ccid.params[2] = 0; | ||
| 464 | |||
| 465 | frame->data[0] = PN533_STD_FRAME_DIR_OUT; | ||
| 466 | frame->data[1] = cmd_code; | ||
| 467 | frame->datalen = 2; /* data[0] + data[1] */ | ||
| 468 | |||
| 469 | frame->apdu.class = 0xFF; | ||
| 470 | frame->apdu.ins = 0; | ||
| 471 | frame->apdu.p1 = 0; | ||
| 472 | frame->apdu.p2 = 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | static void pn533_acr122_tx_frame_finish(void *_frame) | ||
| 476 | { | ||
| 477 | struct pn533_acr122_tx_frame *frame = _frame; | ||
| 478 | |||
| 479 | frame->ccid.datalen += frame->datalen; | ||
| 480 | } | ||
| 481 | |||
| 482 | static void pn533_acr122_tx_update_payload_len(void *_frame, int len) | ||
| 483 | { | ||
| 484 | struct pn533_acr122_tx_frame *frame = _frame; | ||
| 485 | |||
| 486 | frame->datalen += len; | ||
| 487 | } | ||
| 488 | |||
| 489 | static bool pn533_acr122_is_rx_frame_valid(void *_frame) | ||
| 490 | { | ||
| 491 | struct pn533_acr122_rx_frame *frame = _frame; | ||
| 492 | |||
| 493 | if (frame->ccid.type != 0x83) | ||
| 494 | return false; | ||
| 495 | |||
| 496 | if (frame->data[frame->ccid.datalen - 2] == 0x63) | ||
| 497 | return false; | ||
| 498 | |||
| 499 | return true; | ||
| 500 | } | ||
| 501 | |||
| 502 | static int pn533_acr122_rx_frame_size(void *frame) | ||
| 503 | { | ||
| 504 | struct pn533_acr122_rx_frame *f = frame; | ||
| 505 | |||
| 506 | /* f->ccid.datalen already includes tail length */ | ||
| 507 | return sizeof(struct pn533_acr122_rx_frame) + f->ccid.datalen; | ||
| 508 | } | ||
| 509 | |||
| 510 | static u8 pn533_acr122_get_cmd_code(void *frame) | ||
| 511 | { | ||
| 512 | struct pn533_acr122_rx_frame *f = frame; | ||
| 513 | |||
| 514 | return PN533_STD_FRAME_CMD(f); | ||
| 515 | } | ||
| 516 | |||
| 517 | static struct pn533_frame_ops pn533_acr122_frame_ops = { | ||
| 518 | .tx_frame_init = pn533_acr122_tx_frame_init, | ||
| 519 | .tx_frame_finish = pn533_acr122_tx_frame_finish, | ||
| 520 | .tx_update_payload_len = pn533_acr122_tx_update_payload_len, | ||
| 521 | .tx_header_len = PN533_ACR122_TX_FRAME_HEADER_LEN, | ||
| 522 | .tx_tail_len = PN533_ACR122_TX_FRAME_TAIL_LEN, | ||
| 523 | |||
| 524 | .rx_is_frame_valid = pn533_acr122_is_rx_frame_valid, | ||
| 525 | .rx_header_len = PN533_ACR122_RX_FRAME_HEADER_LEN, | ||
| 526 | .rx_tail_len = PN533_ACR122_RX_FRAME_TAIL_LEN, | ||
| 527 | .rx_frame_size = pn533_acr122_rx_frame_size, | ||
| 528 | |||
| 529 | .max_payload_len = PN533_ACR122_FRAME_MAX_PAYLOAD_LEN, | ||
| 530 | .get_cmd_code = pn533_acr122_get_cmd_code, | ||
| 531 | }; | ||
| 532 | |||
| 396 | /* The rule: value + checksum = 0 */ | 533 | /* The rule: value + checksum = 0 */ |
| 397 | static inline u8 pn533_checksum(u8 value) | 534 | static inline u8 pn533_std_checksum(u8 value) |
| 398 | { | 535 | { |
| 399 | return ~value + 1; | 536 | return ~value + 1; |
| 400 | } | 537 | } |
| 401 | 538 | ||
| 402 | /* The rule: sum(data elements) + checksum = 0 */ | 539 | /* The rule: sum(data elements) + checksum = 0 */ |
| 403 | static u8 pn533_data_checksum(u8 *data, int datalen) | 540 | static u8 pn533_std_data_checksum(u8 *data, int datalen) |
| 404 | { | 541 | { |
| 405 | u8 sum = 0; | 542 | u8 sum = 0; |
| 406 | int i; | 543 | int i; |
| @@ -408,61 +545,61 @@ static u8 pn533_data_checksum(u8 *data, int datalen) | |||
| 408 | for (i = 0; i < datalen; i++) | 545 | for (i = 0; i < datalen; i++) |
| 409 | sum += data[i]; | 546 | sum += data[i]; |
| 410 | 547 | ||
| 411 | return pn533_checksum(sum); | 548 | return pn533_std_checksum(sum); |
| 412 | } | 549 | } |
| 413 | 550 | ||
| 414 | static void pn533_tx_frame_init(void *_frame, u8 cmd_code) | 551 | static void pn533_std_tx_frame_init(void *_frame, u8 cmd_code) |
| 415 | { | 552 | { |
| 416 | struct pn533_frame *frame = _frame; | 553 | struct pn533_std_frame *frame = _frame; |
| 417 | 554 | ||
| 418 | frame->preamble = 0; | 555 | frame->preamble = 0; |
| 419 | frame->start_frame = cpu_to_be16(PN533_SOF); | 556 | frame->start_frame = cpu_to_be16(PN533_STD_FRAME_SOF); |
| 420 | PN533_FRAME_IDENTIFIER(frame) = PN533_DIR_OUT; | 557 | PN533_STD_FRAME_IDENTIFIER(frame) = PN533_STD_FRAME_DIR_OUT; |
| 421 | PN533_FRAME_CMD(frame) = cmd_code; | 558 | PN533_STD_FRAME_CMD(frame) = cmd_code; |
| 422 | frame->datalen = 2; | 559 | frame->datalen = 2; |
| 423 | } | 560 | } |
| 424 | 561 | ||
| 425 | static void pn533_tx_frame_finish(void *_frame) | 562 | static void pn533_std_tx_frame_finish(void *_frame) |
| 426 | { | 563 | { |
| 427 | struct pn533_frame *frame = _frame; | 564 | struct pn533_std_frame *frame = _frame; |
| 428 | 565 | ||
| 429 | frame->datalen_checksum = pn533_checksum(frame->datalen); | 566 | frame->datalen_checksum = pn533_std_checksum(frame->datalen); |
| 430 | 567 | ||
| 431 | PN533_FRAME_CHECKSUM(frame) = | 568 | PN533_STD_FRAME_CHECKSUM(frame) = |
| 432 | pn533_data_checksum(frame->data, frame->datalen); | 569 | pn533_std_data_checksum(frame->data, frame->datalen); |
| 433 | 570 | ||
| 434 | PN533_FRAME_POSTAMBLE(frame) = 0; | 571 | PN533_STD_FRAME_POSTAMBLE(frame) = 0; |
| 435 | } | 572 | } |
| 436 | 573 | ||
| 437 | static void pn533_tx_update_payload_len(void *_frame, int len) | 574 | static void pn533_std_tx_update_payload_len(void *_frame, int len) |
| 438 | { | 575 | { |
| 439 | struct pn533_frame *frame = _frame; | 576 | struct pn533_std_frame *frame = _frame; |
| 440 | 577 | ||
| 441 | frame->datalen += len; | 578 | frame->datalen += len; |
| 442 | } | 579 | } |
| 443 | 580 | ||
| 444 | static bool pn533_rx_frame_is_valid(void *_frame) | 581 | static bool pn533_std_rx_frame_is_valid(void *_frame) |
| 445 | { | 582 | { |
| 446 | u8 checksum; | 583 | u8 checksum; |
| 447 | struct pn533_frame *frame = _frame; | 584 | struct pn533_std_frame *frame = _frame; |
| 448 | 585 | ||
| 449 | if (frame->start_frame != cpu_to_be16(PN533_SOF)) | 586 | if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) |
| 450 | return false; | 587 | return false; |
| 451 | 588 | ||
| 452 | checksum = pn533_checksum(frame->datalen); | 589 | checksum = pn533_std_checksum(frame->datalen); |
| 453 | if (checksum != frame->datalen_checksum) | 590 | if (checksum != frame->datalen_checksum) |
| 454 | return false; | 591 | return false; |
| 455 | 592 | ||
| 456 | checksum = pn533_data_checksum(frame->data, frame->datalen); | 593 | checksum = pn533_std_data_checksum(frame->data, frame->datalen); |
| 457 | if (checksum != PN533_FRAME_CHECKSUM(frame)) | 594 | if (checksum != PN533_STD_FRAME_CHECKSUM(frame)) |
| 458 | return false; | 595 | return false; |
| 459 | 596 | ||
| 460 | return true; | 597 | return true; |
| 461 | } | 598 | } |
| 462 | 599 | ||
| 463 | static bool pn533_rx_frame_is_ack(struct pn533_frame *frame) | 600 | static bool pn533_std_rx_frame_is_ack(struct pn533_std_frame *frame) |
| 464 | { | 601 | { |
| 465 | if (frame->start_frame != cpu_to_be16(PN533_SOF)) | 602 | if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) |
| 466 | return false; | 603 | return false; |
| 467 | 604 | ||
| 468 | if (frame->datalen != 0 || frame->datalen_checksum != 0xFF) | 605 | if (frame->datalen != 0 || frame->datalen_checksum != 0xFF) |
| @@ -471,57 +608,51 @@ static bool pn533_rx_frame_is_ack(struct pn533_frame *frame) | |||
| 471 | return true; | 608 | return true; |
| 472 | } | 609 | } |
| 473 | 610 | ||
| 474 | static inline int pn533_rx_frame_size(void *frame) | 611 | static inline int pn533_std_rx_frame_size(void *frame) |
| 475 | { | 612 | { |
| 476 | struct pn533_frame *f = frame; | 613 | struct pn533_std_frame *f = frame; |
| 477 | 614 | ||
| 478 | return sizeof(struct pn533_frame) + f->datalen + PN533_FRAME_TAIL_LEN; | 615 | return sizeof(struct pn533_std_frame) + f->datalen + |
| 616 | PN533_STD_FRAME_TAIL_LEN; | ||
| 479 | } | 617 | } |
| 480 | 618 | ||
| 481 | static u8 pn533_get_cmd_code(void *frame) | 619 | static u8 pn533_std_get_cmd_code(void *frame) |
| 482 | { | 620 | { |
| 483 | struct pn533_frame *f = frame; | 621 | struct pn533_std_frame *f = frame; |
| 484 | 622 | ||
| 485 | return PN533_FRAME_CMD(f); | 623 | return PN533_STD_FRAME_CMD(f); |
| 486 | } | 624 | } |
| 487 | 625 | ||
| 488 | static struct pn533_frame_ops pn533_std_frame_ops = { | 626 | static struct pn533_frame_ops pn533_std_frame_ops = { |
| 489 | .tx_frame_init = pn533_tx_frame_init, | 627 | .tx_frame_init = pn533_std_tx_frame_init, |
| 490 | .tx_frame_finish = pn533_tx_frame_finish, | 628 | .tx_frame_finish = pn533_std_tx_frame_finish, |
| 491 | .tx_update_payload_len = pn533_tx_update_payload_len, | 629 | .tx_update_payload_len = pn533_std_tx_update_payload_len, |
| 492 | .tx_header_len = PN533_FRAME_HEADER_LEN, | 630 | .tx_header_len = PN533_STD_FRAME_HEADER_LEN, |
| 493 | .tx_tail_len = PN533_FRAME_TAIL_LEN, | 631 | .tx_tail_len = PN533_STD_FRAME_TAIL_LEN, |
| 494 | 632 | ||
| 495 | .rx_is_frame_valid = pn533_rx_frame_is_valid, | 633 | .rx_is_frame_valid = pn533_std_rx_frame_is_valid, |
| 496 | .rx_frame_size = pn533_rx_frame_size, | 634 | .rx_frame_size = pn533_std_rx_frame_size, |
| 497 | .rx_header_len = PN533_FRAME_HEADER_LEN, | 635 | .rx_header_len = PN533_STD_FRAME_HEADER_LEN, |
| 498 | .rx_tail_len = PN533_FRAME_TAIL_LEN, | 636 | .rx_tail_len = PN533_STD_FRAME_TAIL_LEN, |
| 499 | 637 | ||
| 500 | .max_payload_len = PN533_FRAME_MAX_PAYLOAD_LEN, | 638 | .max_payload_len = PN533_STD_FRAME_MAX_PAYLOAD_LEN, |
| 501 | .get_cmd_code = pn533_get_cmd_code, | 639 | .get_cmd_code = pn533_std_get_cmd_code, |
| 502 | }; | 640 | }; |
| 503 | 641 | ||
| 504 | static bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame) | 642 | static bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame) |
| 505 | { | 643 | { |
| 506 | return (dev->ops->get_cmd_code(frame) == PN533_CMD_RESPONSE(dev->cmd)); | 644 | return (dev->ops->get_cmd_code(frame) == |
| 507 | } | 645 | PN533_CMD_RESPONSE(dev->cmd->code)); |
| 508 | |||
| 509 | |||
| 510 | static void pn533_wq_cmd_complete(struct work_struct *work) | ||
| 511 | { | ||
| 512 | struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work); | ||
| 513 | int rc; | ||
| 514 | |||
| 515 | rc = dev->cmd_complete(dev, dev->cmd_complete_arg, dev->wq_in_error); | ||
| 516 | if (rc != -EINPROGRESS) | ||
| 517 | queue_work(dev->wq, &dev->cmd_work); | ||
| 518 | } | 646 | } |
| 519 | 647 | ||
| 520 | static void pn533_recv_response(struct urb *urb) | 648 | static void pn533_recv_response(struct urb *urb) |
| 521 | { | 649 | { |
| 522 | struct pn533 *dev = urb->context; | 650 | struct pn533 *dev = urb->context; |
| 651 | struct pn533_cmd *cmd = dev->cmd; | ||
| 523 | u8 *in_frame; | 652 | u8 *in_frame; |
| 524 | 653 | ||
| 654 | cmd->status = urb->status; | ||
| 655 | |||
| 525 | switch (urb->status) { | 656 | switch (urb->status) { |
| 526 | case 0: | 657 | case 0: |
| 527 | break; /* success */ | 658 | break; /* success */ |
| @@ -530,37 +661,33 @@ static void pn533_recv_response(struct urb *urb) | |||
| 530 | nfc_dev_dbg(&dev->interface->dev, | 661 | nfc_dev_dbg(&dev->interface->dev, |
| 531 | "The urb has been canceled (status %d)", | 662 | "The urb has been canceled (status %d)", |
| 532 | urb->status); | 663 | urb->status); |
| 533 | dev->wq_in_error = urb->status; | ||
| 534 | goto sched_wq; | 664 | goto sched_wq; |
| 535 | case -ESHUTDOWN: | 665 | case -ESHUTDOWN: |
| 536 | default: | 666 | default: |
| 537 | nfc_dev_err(&dev->interface->dev, | 667 | nfc_dev_err(&dev->interface->dev, |
| 538 | "Urb failure (status %d)", urb->status); | 668 | "Urb failure (status %d)", urb->status); |
| 539 | dev->wq_in_error = urb->status; | ||
| 540 | goto sched_wq; | 669 | goto sched_wq; |
| 541 | } | 670 | } |
| 542 | 671 | ||
| 543 | in_frame = dev->in_urb->transfer_buffer; | 672 | in_frame = dev->in_urb->transfer_buffer; |
| 544 | 673 | ||
| 545 | nfc_dev_dbg(&dev->interface->dev, "Received a frame."); | 674 | nfc_dev_dbg(&dev->interface->dev, "Received a frame."); |
| 546 | print_hex_dump(KERN_DEBUG, "PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, | 675 | print_hex_dump_debug("PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, in_frame, |
| 547 | in_frame, dev->ops->rx_frame_size(in_frame), false); | 676 | dev->ops->rx_frame_size(in_frame), false); |
| 548 | 677 | ||
| 549 | if (!dev->ops->rx_is_frame_valid(in_frame)) { | 678 | if (!dev->ops->rx_is_frame_valid(in_frame)) { |
| 550 | nfc_dev_err(&dev->interface->dev, "Received an invalid frame"); | 679 | nfc_dev_err(&dev->interface->dev, "Received an invalid frame"); |
| 551 | dev->wq_in_error = -EIO; | 680 | cmd->status = -EIO; |
| 552 | goto sched_wq; | 681 | goto sched_wq; |
| 553 | } | 682 | } |
| 554 | 683 | ||
| 555 | if (!pn533_rx_frame_is_cmd_response(dev, in_frame)) { | 684 | if (!pn533_rx_frame_is_cmd_response(dev, in_frame)) { |
| 556 | nfc_dev_err(&dev->interface->dev, | 685 | nfc_dev_err(&dev->interface->dev, |
| 557 | "It it not the response to the last command"); | 686 | "It it not the response to the last command"); |
| 558 | dev->wq_in_error = -EIO; | 687 | cmd->status = -EIO; |
| 559 | goto sched_wq; | 688 | goto sched_wq; |
| 560 | } | 689 | } |
| 561 | 690 | ||
| 562 | dev->wq_in_error = 0; | ||
| 563 | |||
| 564 | sched_wq: | 691 | sched_wq: |
| 565 | queue_work(dev->wq, &dev->cmd_complete_work); | 692 | queue_work(dev->wq, &dev->cmd_complete_work); |
| 566 | } | 693 | } |
| @@ -575,9 +702,12 @@ static int pn533_submit_urb_for_response(struct pn533 *dev, gfp_t flags) | |||
| 575 | static void pn533_recv_ack(struct urb *urb) | 702 | static void pn533_recv_ack(struct urb *urb) |
| 576 | { | 703 | { |
| 577 | struct pn533 *dev = urb->context; | 704 | struct pn533 *dev = urb->context; |
| 578 | struct pn533_frame *in_frame; | 705 | struct pn533_cmd *cmd = dev->cmd; |
| 706 | struct pn533_std_frame *in_frame; | ||
| 579 | int rc; | 707 | int rc; |
| 580 | 708 | ||
| 709 | cmd->status = urb->status; | ||
| 710 | |||
| 581 | switch (urb->status) { | 711 | switch (urb->status) { |
| 582 | case 0: | 712 | case 0: |
| 583 | break; /* success */ | 713 | break; /* success */ |
| @@ -586,21 +716,19 @@ static void pn533_recv_ack(struct urb *urb) | |||
| 586 | nfc_dev_dbg(&dev->interface->dev, | 716 | nfc_dev_dbg(&dev->interface->dev, |
| 587 | "The urb has been stopped (status %d)", | 717 | "The urb has been stopped (status %d)", |
| 588 | urb->status); | 718 | urb->status); |
| 589 | dev->wq_in_error = urb->status; | ||
| 590 | goto sched_wq; | 719 | goto sched_wq; |
| 591 | case -ESHUTDOWN: | 720 | case -ESHUTDOWN: |
| 592 | default: | 721 | default: |
| 593 | nfc_dev_err(&dev->interface->dev, | 722 | nfc_dev_err(&dev->interface->dev, |
| 594 | "Urb failure (status %d)", urb->status); | 723 | "Urb failure (status %d)", urb->status); |
| 595 | dev->wq_in_error = urb->status; | ||
| 596 | goto sched_wq; | 724 | goto sched_wq; |
| 597 | } | 725 | } |
| 598 | 726 | ||
| 599 | in_frame = dev->in_urb->transfer_buffer; | 727 | in_frame = dev->in_urb->transfer_buffer; |
| 600 | 728 | ||
| 601 | if (!pn533_rx_frame_is_ack(in_frame)) { | 729 | if (!pn533_std_rx_frame_is_ack(in_frame)) { |
| 602 | nfc_dev_err(&dev->interface->dev, "Received an invalid ack"); | 730 | nfc_dev_err(&dev->interface->dev, "Received an invalid ack"); |
| 603 | dev->wq_in_error = -EIO; | 731 | cmd->status = -EIO; |
| 604 | goto sched_wq; | 732 | goto sched_wq; |
| 605 | } | 733 | } |
| 606 | 734 | ||
| @@ -608,7 +736,7 @@ static void pn533_recv_ack(struct urb *urb) | |||
| 608 | if (rc) { | 736 | if (rc) { |
| 609 | nfc_dev_err(&dev->interface->dev, | 737 | nfc_dev_err(&dev->interface->dev, |
| 610 | "usb_submit_urb failed with result %d", rc); | 738 | "usb_submit_urb failed with result %d", rc); |
| 611 | dev->wq_in_error = rc; | 739 | cmd->status = rc; |
| 612 | goto sched_wq; | 740 | goto sched_wq; |
| 613 | } | 741 | } |
| 614 | 742 | ||
| @@ -627,7 +755,7 @@ static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags) | |||
| 627 | 755 | ||
| 628 | static int pn533_send_ack(struct pn533 *dev, gfp_t flags) | 756 | static int pn533_send_ack(struct pn533 *dev, gfp_t flags) |
| 629 | { | 757 | { |
| 630 | u8 ack[PN533_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; | 758 | u8 ack[PN533_STD_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; |
| 631 | /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ | 759 | /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ |
| 632 | int rc; | 760 | int rc; |
| 633 | 761 | ||
| @@ -643,32 +771,34 @@ static int pn533_send_ack(struct pn533 *dev, gfp_t flags) | |||
| 643 | static int __pn533_send_frame_async(struct pn533 *dev, | 771 | static int __pn533_send_frame_async(struct pn533 *dev, |
| 644 | struct sk_buff *out, | 772 | struct sk_buff *out, |
| 645 | struct sk_buff *in, | 773 | struct sk_buff *in, |
| 646 | int in_len, | 774 | int in_len) |
| 647 | pn533_cmd_complete_t cmd_complete, | ||
| 648 | void *arg) | ||
| 649 | { | 775 | { |
| 650 | int rc; | 776 | int rc; |
| 651 | 777 | ||
| 652 | dev->cmd = dev->ops->get_cmd_code(out->data); | ||
| 653 | dev->cmd_complete = cmd_complete; | ||
| 654 | dev->cmd_complete_arg = arg; | ||
| 655 | |||
| 656 | dev->out_urb->transfer_buffer = out->data; | 778 | dev->out_urb->transfer_buffer = out->data; |
| 657 | dev->out_urb->transfer_buffer_length = out->len; | 779 | dev->out_urb->transfer_buffer_length = out->len; |
| 658 | 780 | ||
| 659 | dev->in_urb->transfer_buffer = in->data; | 781 | dev->in_urb->transfer_buffer = in->data; |
| 660 | dev->in_urb->transfer_buffer_length = in_len; | 782 | dev->in_urb->transfer_buffer_length = in_len; |
| 661 | 783 | ||
| 662 | print_hex_dump(KERN_DEBUG, "PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, | 784 | print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, |
| 663 | out->data, out->len, false); | 785 | out->data, out->len, false); |
| 664 | 786 | ||
| 665 | rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); | 787 | rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); |
| 666 | if (rc) | 788 | if (rc) |
| 667 | return rc; | 789 | return rc; |
| 668 | 790 | ||
| 669 | rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL); | 791 | if (dev->protocol_type == PN533_PROTO_REQ_RESP) { |
| 670 | if (rc) | 792 | /* request for response for sent packet directly */ |
| 671 | goto error; | 793 | rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC); |
| 794 | if (rc) | ||
| 795 | goto error; | ||
| 796 | } else if (dev->protocol_type == PN533_PROTO_REQ_ACK_RESP) { | ||
| 797 | /* request for ACK if that's the case */ | ||
| 798 | rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL); | ||
| 799 | if (rc) | ||
| 800 | goto error; | ||
| 801 | } | ||
| 672 | 802 | ||
| 673 | return 0; | 803 | return 0; |
| 674 | 804 | ||
| @@ -693,39 +823,34 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, | |||
| 693 | ops->tx_frame_finish(skb->data); | 823 | ops->tx_frame_finish(skb->data); |
| 694 | } | 824 | } |
| 695 | 825 | ||
| 696 | struct pn533_send_async_complete_arg { | 826 | static int pn533_send_async_complete(struct pn533 *dev) |
| 697 | pn533_send_async_complete_t complete_cb; | ||
| 698 | void *complete_cb_context; | ||
| 699 | struct sk_buff *resp; | ||
| 700 | struct sk_buff *req; | ||
| 701 | }; | ||
| 702 | |||
| 703 | static int pn533_send_async_complete(struct pn533 *dev, void *_arg, int status) | ||
| 704 | { | 827 | { |
| 705 | struct pn533_send_async_complete_arg *arg = _arg; | 828 | struct pn533_cmd *cmd = dev->cmd; |
| 829 | int status = cmd->status; | ||
| 706 | 830 | ||
| 707 | struct sk_buff *req = arg->req; | 831 | struct sk_buff *req = cmd->req; |
| 708 | struct sk_buff *resp = arg->resp; | 832 | struct sk_buff *resp = cmd->resp; |
| 709 | 833 | ||
| 710 | int rc; | 834 | int rc; |
| 711 | 835 | ||
| 712 | dev_kfree_skb(req); | 836 | dev_kfree_skb(req); |
| 713 | 837 | ||
| 714 | if (status < 0) { | 838 | if (status < 0) { |
| 715 | arg->complete_cb(dev, arg->complete_cb_context, | 839 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, |
| 716 | ERR_PTR(status)); | 840 | ERR_PTR(status)); |
| 717 | dev_kfree_skb(resp); | 841 | dev_kfree_skb(resp); |
| 718 | kfree(arg); | 842 | goto done; |
| 719 | return status; | ||
| 720 | } | 843 | } |
| 721 | 844 | ||
| 722 | skb_put(resp, dev->ops->rx_frame_size(resp->data)); | 845 | skb_put(resp, dev->ops->rx_frame_size(resp->data)); |
| 723 | skb_pull(resp, dev->ops->rx_header_len); | 846 | skb_pull(resp, dev->ops->rx_header_len); |
| 724 | skb_trim(resp, resp->len - dev->ops->rx_tail_len); | 847 | skb_trim(resp, resp->len - dev->ops->rx_tail_len); |
| 725 | 848 | ||
| 726 | rc = arg->complete_cb(dev, arg->complete_cb_context, resp); | 849 | rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); |
| 727 | 850 | ||
| 728 | kfree(arg); | 851 | done: |
| 852 | kfree(cmd); | ||
| 853 | dev->cmd = NULL; | ||
| 729 | return rc; | 854 | return rc; |
| 730 | } | 855 | } |
| 731 | 856 | ||
| @@ -736,56 +861,45 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, | |||
| 736 | void *complete_cb_context) | 861 | void *complete_cb_context) |
| 737 | { | 862 | { |
| 738 | struct pn533_cmd *cmd; | 863 | struct pn533_cmd *cmd; |
| 739 | struct pn533_send_async_complete_arg *arg; | ||
| 740 | int rc = 0; | 864 | int rc = 0; |
| 741 | 865 | ||
| 742 | nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x", cmd_code); | 866 | nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x", cmd_code); |
| 743 | 867 | ||
| 744 | arg = kzalloc(sizeof(*arg), GFP_KERNEL); | 868 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 745 | if (!arg) | 869 | if (!cmd) |
| 746 | return -ENOMEM; | 870 | return -ENOMEM; |
| 747 | 871 | ||
| 748 | arg->complete_cb = complete_cb; | 872 | cmd->code = cmd_code; |
| 749 | arg->complete_cb_context = complete_cb_context; | 873 | cmd->req = req; |
| 750 | arg->resp = resp; | 874 | cmd->resp = resp; |
| 751 | arg->req = req; | 875 | cmd->resp_len = resp_len; |
| 876 | cmd->complete_cb = complete_cb; | ||
| 877 | cmd->complete_cb_context = complete_cb_context; | ||
| 752 | 878 | ||
| 753 | pn533_build_cmd_frame(dev, cmd_code, req); | 879 | pn533_build_cmd_frame(dev, cmd_code, req); |
| 754 | 880 | ||
| 755 | mutex_lock(&dev->cmd_lock); | 881 | mutex_lock(&dev->cmd_lock); |
| 756 | 882 | ||
| 757 | if (!dev->cmd_pending) { | 883 | if (!dev->cmd_pending) { |
| 758 | rc = __pn533_send_frame_async(dev, req, resp, resp_len, | 884 | rc = __pn533_send_frame_async(dev, req, resp, resp_len); |
| 759 | pn533_send_async_complete, arg); | ||
| 760 | if (rc) | 885 | if (rc) |
| 761 | goto error; | 886 | goto error; |
| 762 | 887 | ||
| 763 | dev->cmd_pending = 1; | 888 | dev->cmd_pending = 1; |
| 889 | dev->cmd = cmd; | ||
| 764 | goto unlock; | 890 | goto unlock; |
| 765 | } | 891 | } |
| 766 | 892 | ||
| 767 | nfc_dev_dbg(&dev->interface->dev, "%s Queueing command 0x%x", __func__, | 893 | nfc_dev_dbg(&dev->interface->dev, "%s Queueing command 0x%x", __func__, |
| 768 | cmd_code); | 894 | cmd_code); |
| 769 | 895 | ||
| 770 | cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL); | ||
| 771 | if (!cmd) { | ||
| 772 | rc = -ENOMEM; | ||
| 773 | goto error; | ||
| 774 | } | ||
| 775 | |||
| 776 | INIT_LIST_HEAD(&cmd->queue); | 896 | INIT_LIST_HEAD(&cmd->queue); |
| 777 | cmd->cmd_code = cmd_code; | ||
| 778 | cmd->req = req; | ||
| 779 | cmd->resp = resp; | ||
| 780 | cmd->resp_len = resp_len; | ||
| 781 | cmd->arg = arg; | ||
| 782 | |||
| 783 | list_add_tail(&cmd->queue, &dev->cmd_queue); | 897 | list_add_tail(&cmd->queue, &dev->cmd_queue); |
| 784 | 898 | ||
| 785 | goto unlock; | 899 | goto unlock; |
| 786 | 900 | ||
| 787 | error: | 901 | error: |
| 788 | kfree(arg); | 902 | kfree(cmd); |
| 789 | unlock: | 903 | unlock: |
| 790 | mutex_unlock(&dev->cmd_lock); | 904 | mutex_unlock(&dev->cmd_lock); |
| 791 | return rc; | 905 | return rc; |
| @@ -850,8 +964,8 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, | |||
| 850 | pn533_send_async_complete_t complete_cb, | 964 | pn533_send_async_complete_t complete_cb, |
| 851 | void *complete_cb_context) | 965 | void *complete_cb_context) |
| 852 | { | 966 | { |
| 853 | struct pn533_send_async_complete_arg *arg; | ||
| 854 | struct sk_buff *resp; | 967 | struct sk_buff *resp; |
| 968 | struct pn533_cmd *cmd; | ||
| 855 | int rc; | 969 | int rc; |
| 856 | int resp_len = dev->ops->rx_header_len + | 970 | int resp_len = dev->ops->rx_header_len + |
| 857 | dev->ops->max_payload_len + | 971 | dev->ops->max_payload_len + |
| @@ -861,33 +975,47 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, | |||
| 861 | if (!resp) | 975 | if (!resp) |
| 862 | return -ENOMEM; | 976 | return -ENOMEM; |
| 863 | 977 | ||
| 864 | arg = kzalloc(sizeof(*arg), GFP_KERNEL); | 978 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 865 | if (!arg) { | 979 | if (!cmd) { |
| 866 | dev_kfree_skb(resp); | 980 | dev_kfree_skb(resp); |
| 867 | return -ENOMEM; | 981 | return -ENOMEM; |
| 868 | } | 982 | } |
| 869 | 983 | ||
| 870 | arg->complete_cb = complete_cb; | 984 | cmd->code = cmd_code; |
| 871 | arg->complete_cb_context = complete_cb_context; | 985 | cmd->req = req; |
| 872 | arg->resp = resp; | 986 | cmd->resp = resp; |
| 873 | arg->req = req; | 987 | cmd->resp_len = resp_len; |
| 988 | cmd->complete_cb = complete_cb; | ||
| 989 | cmd->complete_cb_context = complete_cb_context; | ||
| 874 | 990 | ||
| 875 | pn533_build_cmd_frame(dev, cmd_code, req); | 991 | pn533_build_cmd_frame(dev, cmd_code, req); |
| 876 | 992 | ||
| 877 | rc = __pn533_send_frame_async(dev, req, resp, resp_len, | 993 | rc = __pn533_send_frame_async(dev, req, resp, resp_len); |
| 878 | pn533_send_async_complete, arg); | ||
| 879 | if (rc < 0) { | 994 | if (rc < 0) { |
| 880 | dev_kfree_skb(resp); | 995 | dev_kfree_skb(resp); |
| 881 | kfree(arg); | 996 | kfree(cmd); |
| 997 | } else { | ||
| 998 | dev->cmd = cmd; | ||
| 882 | } | 999 | } |
| 883 | 1000 | ||
| 884 | return rc; | 1001 | return rc; |
| 885 | } | 1002 | } |
| 886 | 1003 | ||
| 1004 | static void pn533_wq_cmd_complete(struct work_struct *work) | ||
| 1005 | { | ||
| 1006 | struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work); | ||
| 1007 | int rc; | ||
| 1008 | |||
| 1009 | rc = pn533_send_async_complete(dev); | ||
| 1010 | if (rc != -EINPROGRESS) | ||
| 1011 | queue_work(dev->wq, &dev->cmd_work); | ||
| 1012 | } | ||
| 1013 | |||
| 887 | static void pn533_wq_cmd(struct work_struct *work) | 1014 | static void pn533_wq_cmd(struct work_struct *work) |
| 888 | { | 1015 | { |
| 889 | struct pn533 *dev = container_of(work, struct pn533, cmd_work); | 1016 | struct pn533 *dev = container_of(work, struct pn533, cmd_work); |
| 890 | struct pn533_cmd *cmd; | 1017 | struct pn533_cmd *cmd; |
| 1018 | int rc; | ||
| 891 | 1019 | ||
| 892 | mutex_lock(&dev->cmd_lock); | 1020 | mutex_lock(&dev->cmd_lock); |
| 893 | 1021 | ||
| @@ -903,10 +1031,15 @@ static void pn533_wq_cmd(struct work_struct *work) | |||
| 903 | 1031 | ||
| 904 | mutex_unlock(&dev->cmd_lock); | 1032 | mutex_unlock(&dev->cmd_lock); |
| 905 | 1033 | ||
| 906 | __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len, | 1034 | rc = __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len); |
| 907 | pn533_send_async_complete, cmd->arg); | 1035 | if (rc < 0) { |
| 1036 | dev_kfree_skb(cmd->req); | ||
| 1037 | dev_kfree_skb(cmd->resp); | ||
| 1038 | kfree(cmd); | ||
| 1039 | return; | ||
| 1040 | } | ||
| 908 | 1041 | ||
| 909 | kfree(cmd); | 1042 | dev->cmd = cmd; |
| 910 | } | 1043 | } |
| 911 | 1044 | ||
| 912 | struct pn533_sync_cmd_response { | 1045 | struct pn533_sync_cmd_response { |
| @@ -982,6 +1115,23 @@ static void pn533_send_complete(struct urb *urb) | |||
| 982 | } | 1115 | } |
| 983 | } | 1116 | } |
| 984 | 1117 | ||
| 1118 | static void pn533_abort_cmd(struct pn533 *dev, gfp_t flags) | ||
| 1119 | { | ||
| 1120 | /* ACR122U does not support any command which aborts last | ||
| 1121 | * issued command i.e. as ACK for standard PN533. Additionally, | ||
| 1122 | * it behaves stange, sending broken or incorrect responses, | ||
| 1123 | * when we cancel urb before the chip will send response. | ||
| 1124 | */ | ||
| 1125 | if (dev->device_type == PN533_DEVICE_ACR122U) | ||
| 1126 | return; | ||
| 1127 | |||
| 1128 | /* An ack will cancel the last issued command */ | ||
| 1129 | pn533_send_ack(dev, flags); | ||
| 1130 | |||
| 1131 | /* cancel the urb request */ | ||
| 1132 | usb_kill_urb(dev->in_urb); | ||
| 1133 | } | ||
| 1134 | |||
| 985 | static struct sk_buff *pn533_alloc_skb(struct pn533 *dev, unsigned int size) | 1135 | static struct sk_buff *pn533_alloc_skb(struct pn533 *dev, unsigned int size) |
| 986 | { | 1136 | { |
| 987 | struct sk_buff *skb; | 1137 | struct sk_buff *skb; |
| @@ -1500,9 +1650,6 @@ static void pn533_listen_mode_timer(unsigned long data) | |||
| 1500 | 1650 | ||
| 1501 | nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout"); | 1651 | nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout"); |
| 1502 | 1652 | ||
| 1503 | /* An ack will cancel the last issued command (poll) */ | ||
| 1504 | pn533_send_ack(dev, GFP_ATOMIC); | ||
| 1505 | |||
| 1506 | dev->cancel_listen = 1; | 1653 | dev->cancel_listen = 1; |
| 1507 | 1654 | ||
| 1508 | pn533_poll_next_mod(dev); | 1655 | pn533_poll_next_mod(dev); |
| @@ -1549,6 +1696,11 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, | |||
| 1549 | if (!rc) | 1696 | if (!rc) |
| 1550 | goto done; | 1697 | goto done; |
| 1551 | 1698 | ||
| 1699 | if (!dev->poll_mod_count) { | ||
| 1700 | nfc_dev_dbg(&dev->interface->dev, "Polling has been stoped."); | ||
| 1701 | goto done; | ||
| 1702 | } | ||
| 1703 | |||
| 1552 | pn533_poll_next_mod(dev); | 1704 | pn533_poll_next_mod(dev); |
| 1553 | queue_work(dev->wq, &dev->poll_work); | 1705 | queue_work(dev->wq, &dev->poll_work); |
| 1554 | 1706 | ||
| @@ -1627,7 +1779,7 @@ static void pn533_wq_poll(struct work_struct *work) | |||
| 1627 | 1779 | ||
| 1628 | if (dev->cancel_listen == 1) { | 1780 | if (dev->cancel_listen == 1) { |
| 1629 | dev->cancel_listen = 0; | 1781 | dev->cancel_listen = 0; |
| 1630 | usb_kill_urb(dev->in_urb); | 1782 | pn533_abort_cmd(dev, GFP_ATOMIC); |
| 1631 | } | 1783 | } |
| 1632 | 1784 | ||
| 1633 | rc = pn533_send_poll_frame(dev); | 1785 | rc = pn533_send_poll_frame(dev); |
| @@ -1689,12 +1841,7 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) | |||
| 1689 | return; | 1841 | return; |
| 1690 | } | 1842 | } |
| 1691 | 1843 | ||
| 1692 | /* An ack will cancel the last issued command (poll) */ | 1844 | pn533_abort_cmd(dev, GFP_KERNEL); |
| 1693 | pn533_send_ack(dev, GFP_KERNEL); | ||
| 1694 | |||
| 1695 | /* prevent pn533_start_poll_complete to issue a new poll meanwhile */ | ||
| 1696 | usb_kill_urb(dev->in_urb); | ||
| 1697 | |||
| 1698 | pn533_poll_reset_mod_list(dev); | 1845 | pn533_poll_reset_mod_list(dev); |
| 1699 | } | 1846 | } |
| 1700 | 1847 | ||
| @@ -1723,6 +1870,8 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) | |||
| 1723 | rsp = (struct pn533_cmd_activate_response *)resp->data; | 1870 | rsp = (struct pn533_cmd_activate_response *)resp->data; |
| 1724 | rc = rsp->status & PN533_CMD_RET_MASK; | 1871 | rc = rsp->status & PN533_CMD_RET_MASK; |
| 1725 | if (rc != PN533_CMD_RET_SUCCESS) { | 1872 | if (rc != PN533_CMD_RET_SUCCESS) { |
| 1873 | nfc_dev_err(&dev->interface->dev, | ||
| 1874 | "Target activation failed (error 0x%x)", rc); | ||
| 1726 | dev_kfree_skb(resp); | 1875 | dev_kfree_skb(resp); |
| 1727 | return -EIO; | 1876 | return -EIO; |
| 1728 | } | 1877 | } |
| @@ -1850,7 +1999,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
| 1850 | rc = rsp->status & PN533_CMD_RET_MASK; | 1999 | rc = rsp->status & PN533_CMD_RET_MASK; |
| 1851 | if (rc != PN533_CMD_RET_SUCCESS) { | 2000 | if (rc != PN533_CMD_RET_SUCCESS) { |
| 1852 | nfc_dev_err(&dev->interface->dev, | 2001 | nfc_dev_err(&dev->interface->dev, |
| 1853 | "Bringing DEP link up failed %d", rc); | 2002 | "Bringing DEP link up failed (error 0x%x)", rc); |
| 1854 | goto error; | 2003 | goto error; |
| 1855 | } | 2004 | } |
| 1856 | 2005 | ||
| @@ -1985,10 +2134,8 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) | |||
| 1985 | 2134 | ||
| 1986 | pn533_poll_reset_mod_list(dev); | 2135 | pn533_poll_reset_mod_list(dev); |
| 1987 | 2136 | ||
| 1988 | if (dev->tgt_mode || dev->tgt_active_prot) { | 2137 | if (dev->tgt_mode || dev->tgt_active_prot) |
| 1989 | pn533_send_ack(dev, GFP_KERNEL); | 2138 | pn533_abort_cmd(dev, GFP_KERNEL); |
| 1990 | usb_kill_urb(dev->in_urb); | ||
| 1991 | } | ||
| 1992 | 2139 | ||
| 1993 | dev->tgt_active_prot = 0; | 2140 | dev->tgt_active_prot = 0; |
| 1994 | dev->tgt_mode = 0; | 2141 | dev->tgt_mode = 0; |
| @@ -2064,8 +2211,7 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, | |||
| 2064 | 2211 | ||
| 2065 | if (ret != PN533_CMD_RET_SUCCESS) { | 2212 | if (ret != PN533_CMD_RET_SUCCESS) { |
| 2066 | nfc_dev_err(&dev->interface->dev, | 2213 | nfc_dev_err(&dev->interface->dev, |
| 2067 | "PN533 reported error %d when exchanging data", | 2214 | "Exchanging data failed (error 0x%x)", ret); |
| 2068 | ret); | ||
| 2069 | rc = -EIO; | 2215 | rc = -EIO; |
| 2070 | goto error; | 2216 | goto error; |
| 2071 | } | 2217 | } |
| @@ -2253,7 +2399,7 @@ static void pn533_wq_mi_recv(struct work_struct *work) | |||
| 2253 | "Error %d when trying to perform data_exchange", rc); | 2399 | "Error %d when trying to perform data_exchange", rc); |
| 2254 | 2400 | ||
| 2255 | dev_kfree_skb(skb); | 2401 | dev_kfree_skb(skb); |
| 2256 | kfree(dev->cmd_complete_arg); | 2402 | kfree(dev->cmd_complete_mi_arg); |
| 2257 | 2403 | ||
| 2258 | error: | 2404 | error: |
| 2259 | pn533_send_ack(dev, GFP_KERNEL); | 2405 | pn533_send_ack(dev, GFP_KERNEL); |
| @@ -2310,7 +2456,7 @@ static int pn533_get_firmware_version(struct pn533 *dev, | |||
| 2310 | return 0; | 2456 | return 0; |
| 2311 | } | 2457 | } |
| 2312 | 2458 | ||
| 2313 | static int pn533_fw_reset(struct pn533 *dev) | 2459 | static int pn533_pasori_fw_reset(struct pn533 *dev) |
| 2314 | { | 2460 | { |
| 2315 | struct sk_buff *skb; | 2461 | struct sk_buff *skb; |
| 2316 | struct sk_buff *resp; | 2462 | struct sk_buff *resp; |
| @@ -2332,9 +2478,102 @@ static int pn533_fw_reset(struct pn533 *dev) | |||
| 2332 | return 0; | 2478 | return 0; |
| 2333 | } | 2479 | } |
| 2334 | 2480 | ||
| 2481 | struct pn533_acr122_poweron_rdr_arg { | ||
| 2482 | int rc; | ||
| 2483 | struct completion done; | ||
| 2484 | }; | ||
| 2485 | |||
| 2486 | static void pn533_acr122_poweron_rdr_resp(struct urb *urb) | ||
| 2487 | { | ||
| 2488 | struct pn533_acr122_poweron_rdr_arg *arg = urb->context; | ||
| 2489 | |||
| 2490 | nfc_dev_dbg(&urb->dev->dev, "%s", __func__); | ||
| 2491 | |||
| 2492 | print_hex_dump(KERN_ERR, "ACR122 RX: ", DUMP_PREFIX_NONE, 16, 1, | ||
| 2493 | urb->transfer_buffer, urb->transfer_buffer_length, | ||
| 2494 | false); | ||
| 2495 | |||
| 2496 | arg->rc = urb->status; | ||
| 2497 | complete(&arg->done); | ||
| 2498 | } | ||
| 2499 | |||
| 2500 | static int pn533_acr122_poweron_rdr(struct pn533 *dev) | ||
| 2501 | { | ||
| 2502 | /* Power on th reader (CCID cmd) */ | ||
| 2503 | u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON, | ||
| 2504 | 0, 0, 0, 0, 0, 0, 3, 0, 0}; | ||
| 2505 | u8 buf[255]; | ||
| 2506 | int rc; | ||
| 2507 | void *cntx; | ||
| 2508 | struct pn533_acr122_poweron_rdr_arg arg; | ||
| 2509 | |||
| 2510 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | ||
| 2511 | |||
| 2512 | init_completion(&arg.done); | ||
| 2513 | cntx = dev->in_urb->context; /* backup context */ | ||
| 2514 | |||
| 2515 | dev->in_urb->transfer_buffer = buf; | ||
| 2516 | dev->in_urb->transfer_buffer_length = 255; | ||
| 2517 | dev->in_urb->complete = pn533_acr122_poweron_rdr_resp; | ||
| 2518 | dev->in_urb->context = &arg; | ||
| 2519 | |||
| 2520 | dev->out_urb->transfer_buffer = cmd; | ||
| 2521 | dev->out_urb->transfer_buffer_length = sizeof(cmd); | ||
| 2522 | |||
| 2523 | print_hex_dump(KERN_ERR, "ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1, | ||
| 2524 | cmd, sizeof(cmd), false); | ||
| 2525 | |||
| 2526 | rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); | ||
| 2527 | if (rc) { | ||
| 2528 | nfc_dev_err(&dev->interface->dev, | ||
| 2529 | "Reader power on cmd error %d", rc); | ||
| 2530 | return rc; | ||
| 2531 | } | ||
| 2532 | |||
| 2533 | rc = usb_submit_urb(dev->in_urb, GFP_KERNEL); | ||
| 2534 | if (rc) { | ||
| 2535 | nfc_dev_err(&dev->interface->dev, | ||
| 2536 | "Can't submit for reader power on cmd response %d", | ||
| 2537 | rc); | ||
| 2538 | return rc; | ||
| 2539 | } | ||
| 2540 | |||
| 2541 | wait_for_completion(&arg.done); | ||
| 2542 | dev->in_urb->context = cntx; /* restore context */ | ||
| 2543 | |||
| 2544 | return arg.rc; | ||
| 2545 | } | ||
| 2546 | |||
| 2547 | static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf) | ||
| 2548 | { | ||
| 2549 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | ||
| 2550 | u8 rf_field = !!rf; | ||
| 2551 | int rc; | ||
| 2552 | |||
| 2553 | rc = pn533_set_configuration(dev, PN533_CFGITEM_RF_FIELD, | ||
| 2554 | (u8 *)&rf_field, 1); | ||
| 2555 | if (rc) { | ||
| 2556 | nfc_dev_err(&dev->interface->dev, | ||
| 2557 | "Error on setting RF field"); | ||
| 2558 | return rc; | ||
| 2559 | } | ||
| 2560 | |||
| 2561 | return rc; | ||
| 2562 | } | ||
| 2563 | |||
| 2564 | int pn533_dev_up(struct nfc_dev *nfc_dev) | ||
| 2565 | { | ||
| 2566 | return pn533_rf_field(nfc_dev, 1); | ||
| 2567 | } | ||
| 2568 | |||
| 2569 | int pn533_dev_down(struct nfc_dev *nfc_dev) | ||
| 2570 | { | ||
| 2571 | return pn533_rf_field(nfc_dev, 0); | ||
| 2572 | } | ||
| 2573 | |||
| 2335 | static struct nfc_ops pn533_nfc_ops = { | 2574 | static struct nfc_ops pn533_nfc_ops = { |
| 2336 | .dev_up = NULL, | 2575 | .dev_up = pn533_dev_up, |
| 2337 | .dev_down = NULL, | 2576 | .dev_down = pn533_dev_down, |
| 2338 | .dep_link_up = pn533_dep_link_up, | 2577 | .dep_link_up = pn533_dep_link_up, |
| 2339 | .dep_link_down = pn533_dep_link_down, | 2578 | .dep_link_down = pn533_dep_link_down, |
| 2340 | .start_poll = pn533_start_poll, | 2579 | .start_poll = pn533_start_poll, |
| @@ -2366,6 +2605,7 @@ static int pn533_setup(struct pn533 *dev) | |||
| 2366 | break; | 2605 | break; |
| 2367 | 2606 | ||
| 2368 | case PN533_DEVICE_PASORI: | 2607 | case PN533_DEVICE_PASORI: |
| 2608 | case PN533_DEVICE_ACR122U: | ||
| 2369 | max_retries.mx_rty_atr = 0x2; | 2609 | max_retries.mx_rty_atr = 0x2; |
| 2370 | max_retries.mx_rty_psl = 0x1; | 2610 | max_retries.mx_rty_psl = 0x1; |
| 2371 | max_retries.mx_rty_passive_act = | 2611 | max_retries.mx_rty_passive_act = |
| @@ -2405,7 +2645,7 @@ static int pn533_setup(struct pn533 *dev) | |||
| 2405 | break; | 2645 | break; |
| 2406 | 2646 | ||
| 2407 | case PN533_DEVICE_PASORI: | 2647 | case PN533_DEVICE_PASORI: |
| 2408 | pn533_fw_reset(dev); | 2648 | pn533_pasori_fw_reset(dev); |
| 2409 | 2649 | ||
| 2410 | rc = pn533_set_configuration(dev, PN533_CFGITEM_PASORI, | 2650 | rc = pn533_set_configuration(dev, PN533_CFGITEM_PASORI, |
| 2411 | pasori_cfg, 3); | 2651 | pasori_cfg, 3); |
| @@ -2415,7 +2655,7 @@ static int pn533_setup(struct pn533 *dev) | |||
| 2415 | return rc; | 2655 | return rc; |
| 2416 | } | 2656 | } |
| 2417 | 2657 | ||
| 2418 | pn533_fw_reset(dev); | 2658 | pn533_pasori_fw_reset(dev); |
| 2419 | 2659 | ||
| 2420 | break; | 2660 | break; |
| 2421 | } | 2661 | } |
| @@ -2496,6 +2736,7 @@ static int pn533_probe(struct usb_interface *interface, | |||
| 2496 | 2736 | ||
| 2497 | dev->ops = &pn533_std_frame_ops; | 2737 | dev->ops = &pn533_std_frame_ops; |
| 2498 | 2738 | ||
| 2739 | dev->protocol_type = PN533_PROTO_REQ_ACK_RESP; | ||
| 2499 | dev->device_type = id->driver_info; | 2740 | dev->device_type = id->driver_info; |
| 2500 | switch (dev->device_type) { | 2741 | switch (dev->device_type) { |
| 2501 | case PN533_DEVICE_STD: | 2742 | case PN533_DEVICE_STD: |
| @@ -2506,6 +2747,20 @@ static int pn533_probe(struct usb_interface *interface, | |||
| 2506 | protocols = PN533_NO_TYPE_B_PROTOCOLS; | 2747 | protocols = PN533_NO_TYPE_B_PROTOCOLS; |
| 2507 | break; | 2748 | break; |
| 2508 | 2749 | ||
| 2750 | case PN533_DEVICE_ACR122U: | ||
| 2751 | protocols = PN533_NO_TYPE_B_PROTOCOLS; | ||
| 2752 | dev->ops = &pn533_acr122_frame_ops; | ||
| 2753 | dev->protocol_type = PN533_PROTO_REQ_RESP, | ||
| 2754 | |||
| 2755 | rc = pn533_acr122_poweron_rdr(dev); | ||
| 2756 | if (rc < 0) { | ||
| 2757 | nfc_dev_err(&dev->interface->dev, | ||
| 2758 | "Couldn't poweron the reader (error %d)", | ||
| 2759 | rc); | ||
| 2760 | goto destroy_wq; | ||
| 2761 | } | ||
| 2762 | break; | ||
| 2763 | |||
| 2509 | default: | 2764 | default: |
| 2510 | nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n", | 2765 | nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n", |
| 2511 | dev->device_type); | 2766 | dev->device_type); |
| @@ -2555,6 +2810,7 @@ destroy_wq: | |||
| 2555 | error: | 2810 | error: |
| 2556 | usb_free_urb(dev->in_urb); | 2811 | usb_free_urb(dev->in_urb); |
| 2557 | usb_free_urb(dev->out_urb); | 2812 | usb_free_urb(dev->out_urb); |
| 2813 | usb_put_dev(dev->udev); | ||
| 2558 | kfree(dev); | 2814 | kfree(dev); |
| 2559 | return rc; | 2815 | return rc; |
| 2560 | } | 2816 | } |
| @@ -2600,8 +2856,9 @@ static struct usb_driver pn533_driver = { | |||
| 2600 | 2856 | ||
| 2601 | module_usb_driver(pn533_driver); | 2857 | module_usb_driver(pn533_driver); |
| 2602 | 2858 | ||
| 2603 | MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>," | 2859 | MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>"); |
| 2604 | " Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); | 2860 | MODULE_AUTHOR("Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); |
| 2861 | MODULE_AUTHOR("Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>"); | ||
| 2605 | MODULE_DESCRIPTION("PN533 usb driver ver " VERSION); | 2862 | MODULE_DESCRIPTION("PN533 usb driver ver " VERSION); |
| 2606 | MODULE_VERSION(VERSION); | 2863 | MODULE_VERSION(VERSION); |
| 2607 | MODULE_LICENSE("GPL"); | 2864 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/nfc/pn544/Kconfig b/drivers/nfc/pn544/Kconfig index c277790ac71c..ccf06f5f6ebb 100644 --- a/drivers/nfc/pn544/Kconfig +++ b/drivers/nfc/pn544/Kconfig | |||
| @@ -20,4 +20,15 @@ config NFC_PN544_I2C | |||
| 20 | Select this if your platform is using the i2c bus. | 20 | Select this if your platform is using the i2c bus. |
| 21 | 21 | ||
| 22 | If you choose to build a module, it'll be called pn544_i2c. | 22 | If you choose to build a module, it'll be called pn544_i2c. |
| 23 | Say N if unsure. \ No newline at end of file | 23 | Say N if unsure. |
| 24 | |||
| 25 | config NFC_PN544_MEI | ||
| 26 | tristate "NFC PN544 MEI support" | ||
| 27 | depends on NFC_PN544 && NFC_MEI_PHY | ||
| 28 | ---help--- | ||
| 29 | This module adds support for the mei interface of adapters using | ||
| 30 | NXP pn544 chipsets. Select this if your pn544 chipset | ||
| 31 | is handled by Intel's Management Engine Interface on your platform. | ||
| 32 | |||
| 33 | If you choose to build a module, it'll be called pn544_mei. | ||
| 34 | Say N if unsure. | ||
diff --git a/drivers/nfc/pn544/Makefile b/drivers/nfc/pn544/Makefile index ac076793687d..29fb5a174036 100644 --- a/drivers/nfc/pn544/Makefile +++ b/drivers/nfc/pn544/Makefile | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | pn544_i2c-objs = i2c.o | 5 | pn544_i2c-objs = i2c.o |
| 6 | pn544_mei-objs = mei.o | ||
| 6 | 7 | ||
| 7 | obj-$(CONFIG_NFC_PN544) += pn544.o | 8 | obj-$(CONFIG_NFC_PN544) += pn544.o |
| 8 | obj-$(CONFIG_NFC_PN544_I2C) += pn544_i2c.o | 9 | obj-$(CONFIG_NFC_PN544_I2C) += pn544_i2c.o |
| 10 | obj-$(CONFIG_NFC_PN544_MEI) += pn544_mei.o | ||
diff --git a/drivers/nfc/pn544/mei.c b/drivers/nfc/pn544/mei.c new file mode 100644 index 000000000000..1eb48848a35a --- /dev/null +++ b/drivers/nfc/pn544/mei.c | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | /* | ||
| 2 | * HCI based Driver for NXP pn544 NFC Chip | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Intel Corporation. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the | ||
| 17 | * Free Software Foundation, Inc., | ||
| 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/mod_devicetable.h> | ||
| 23 | #include <linux/nfc.h> | ||
| 24 | #include <net/nfc/hci.h> | ||
| 25 | #include <net/nfc/llc.h> | ||
| 26 | |||
| 27 | #include "../mei_phy.h" | ||
| 28 | #include "pn544.h" | ||
| 29 | |||
| 30 | #define PN544_DRIVER_NAME "pn544" | ||
| 31 | |||
| 32 | static int pn544_mei_probe(struct mei_cl_device *device, | ||
| 33 | const struct mei_cl_device_id *id) | ||
| 34 | { | ||
| 35 | struct nfc_mei_phy *phy; | ||
| 36 | int r; | ||
| 37 | |||
| 38 | pr_info("Probing NFC pn544\n"); | ||
| 39 | |||
| 40 | phy = nfc_mei_phy_alloc(device); | ||
| 41 | if (!phy) { | ||
| 42 | pr_err("Cannot allocate memory for pn544 mei phy.\n"); | ||
| 43 | return -ENOMEM; | ||
| 44 | } | ||
| 45 | |||
| 46 | r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); | ||
| 47 | if (r) { | ||
| 48 | pr_err(PN544_DRIVER_NAME ": event cb registration failed\n"); | ||
| 49 | goto err_out; | ||
| 50 | } | ||
| 51 | |||
| 52 | r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME, | ||
| 53 | MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD, | ||
| 54 | &phy->hdev); | ||
| 55 | if (r < 0) | ||
| 56 | goto err_out; | ||
| 57 | |||
| 58 | return 0; | ||
| 59 | |||
| 60 | err_out: | ||
| 61 | nfc_mei_phy_free(phy); | ||
| 62 | |||
| 63 | return r; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int pn544_mei_remove(struct mei_cl_device *device) | ||
| 67 | { | ||
| 68 | struct nfc_mei_phy *phy = mei_cl_get_drvdata(device); | ||
| 69 | |||
| 70 | pr_info("Removing pn544\n"); | ||
| 71 | |||
| 72 | pn544_hci_remove(phy->hdev); | ||
| 73 | |||
| 74 | nfc_mei_phy_disable(phy); | ||
| 75 | |||
| 76 | nfc_mei_phy_free(phy); | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static struct mei_cl_device_id pn544_mei_tbl[] = { | ||
| 82 | { PN544_DRIVER_NAME }, | ||
| 83 | |||
| 84 | /* required last entry */ | ||
| 85 | { } | ||
| 86 | }; | ||
| 87 | MODULE_DEVICE_TABLE(mei, pn544_mei_tbl); | ||
| 88 | |||
| 89 | static struct mei_cl_driver pn544_driver = { | ||
| 90 | .id_table = pn544_mei_tbl, | ||
| 91 | .name = PN544_DRIVER_NAME, | ||
| 92 | |||
| 93 | .probe = pn544_mei_probe, | ||
| 94 | .remove = pn544_mei_remove, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static int pn544_mei_init(void) | ||
| 98 | { | ||
| 99 | int r; | ||
| 100 | |||
| 101 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
| 102 | |||
| 103 | r = mei_cl_driver_register(&pn544_driver); | ||
| 104 | if (r) { | ||
| 105 | pr_err(PN544_DRIVER_NAME ": driver registration failed\n"); | ||
| 106 | return r; | ||
| 107 | } | ||
| 108 | |||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void pn544_mei_exit(void) | ||
| 113 | { | ||
| 114 | mei_cl_driver_unregister(&pn544_driver); | ||
| 115 | } | ||
| 116 | |||
| 117 | module_init(pn544_mei_init); | ||
| 118 | module_exit(pn544_mei_exit); | ||
| 119 | |||
| 120 | MODULE_LICENSE("GPL"); | ||
| 121 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 0ab6712fd76b..f14a98a79c9d 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
| @@ -134,6 +134,7 @@ struct bcma_host_ops { | |||
| 134 | #define BCMA_CORE_I2S 0x834 | 134 | #define BCMA_CORE_I2S 0x834 |
| 135 | #define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ | 135 | #define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ |
| 136 | #define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ | 136 | #define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ |
| 137 | #define BCMA_CORE_ARM_CR4 0x83e | ||
| 137 | #define BCMA_CORE_DEFAULT 0xFFF | 138 | #define BCMA_CORE_DEFAULT 0xFFF |
| 138 | 139 | ||
| 139 | #define BCMA_MAX_NR_CORES 16 | 140 | #define BCMA_MAX_NR_CORES 16 |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 453fcc914683..b8b09eac60a4 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
| @@ -316,6 +316,9 @@ | |||
| 316 | #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */ | 316 | #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */ |
| 317 | #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ | 317 | #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ |
| 318 | #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16 | 318 | #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16 |
| 319 | #define BCMA_CC_PMU_CTL_RES 0x00006000 /* reset control mask */ | ||
| 320 | #define BCMA_CC_PMU_CTL_RES_SHIFT 13 | ||
| 321 | #define BCMA_CC_PMU_CTL_RES_RELOAD 0x2 /* reload POR values */ | ||
| 319 | #define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400 | 322 | #define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400 |
| 320 | #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ | 323 | #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ |
| 321 | #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ | 324 | #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ |
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 7e8104bb7a7e..917dcd7965e7 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #define BCMA_IOST_BIST_DONE 0x8000 | 37 | #define BCMA_IOST_BIST_DONE 0x8000 |
| 38 | #define BCMA_RESET_CTL 0x0800 | 38 | #define BCMA_RESET_CTL 0x0800 |
| 39 | #define BCMA_RESET_CTL_RESET 0x0001 | 39 | #define BCMA_RESET_CTL_RESET 0x0001 |
| 40 | #define BCMA_RESET_ST 0x0804 | ||
| 40 | 41 | ||
| 41 | /* BCMA PCI config space registers. */ | 42 | /* BCMA PCI config space registers. */ |
| 42 | #define BCMA_PCI_PMCSR 0x44 | 43 | #define BCMA_PCI_PMCSR 0x44 |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 4cf0c9e4dd99..06b0ed0154a4 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
| @@ -673,6 +673,36 @@ struct ieee80211_channel_sw_ie { | |||
| 673 | } __packed; | 673 | } __packed; |
| 674 | 674 | ||
| 675 | /** | 675 | /** |
| 676 | * struct ieee80211_ext_chansw_ie | ||
| 677 | * | ||
| 678 | * This structure represents the "Extended Channel Switch Announcement element" | ||
| 679 | */ | ||
| 680 | struct ieee80211_ext_chansw_ie { | ||
| 681 | u8 mode; | ||
| 682 | u8 new_operating_class; | ||
| 683 | u8 new_ch_num; | ||
| 684 | u8 count; | ||
| 685 | } __packed; | ||
| 686 | |||
| 687 | /** | ||
| 688 | * struct ieee80211_sec_chan_offs_ie - secondary channel offset IE | ||
| 689 | * @sec_chan_offs: secondary channel offset, uses IEEE80211_HT_PARAM_CHA_SEC_* | ||
| 690 | * values here | ||
| 691 | * This structure represents the "Secondary Channel Offset element" | ||
| 692 | */ | ||
| 693 | struct ieee80211_sec_chan_offs_ie { | ||
| 694 | u8 sec_chan_offs; | ||
| 695 | } __packed; | ||
| 696 | |||
| 697 | /** | ||
| 698 | * struct ieee80211_wide_bw_chansw_ie - wide bandwidth channel switch IE | ||
| 699 | */ | ||
| 700 | struct ieee80211_wide_bw_chansw_ie { | ||
| 701 | u8 new_channel_width; | ||
| 702 | u8 new_center_freq_seg0, new_center_freq_seg1; | ||
| 703 | } __packed; | ||
| 704 | |||
| 705 | /** | ||
| 676 | * struct ieee80211_tim | 706 | * struct ieee80211_tim |
| 677 | * | 707 | * |
| 678 | * This structure refers to "Traffic Indication Map information element" | 708 | * This structure refers to "Traffic Indication Map information element" |
| @@ -840,12 +870,15 @@ struct ieee80211_mgmt { | |||
| 840 | } __packed wme_action; | 870 | } __packed wme_action; |
| 841 | struct{ | 871 | struct{ |
| 842 | u8 action_code; | 872 | u8 action_code; |
| 843 | u8 element_id; | 873 | u8 variable[0]; |
| 844 | u8 length; | ||
| 845 | struct ieee80211_channel_sw_ie sw_elem; | ||
| 846 | } __packed chan_switch; | 874 | } __packed chan_switch; |
| 847 | struct{ | 875 | struct{ |
| 848 | u8 action_code; | 876 | u8 action_code; |
| 877 | struct ieee80211_ext_chansw_ie data; | ||
| 878 | u8 variable[0]; | ||
| 879 | } __packed ext_chan_switch; | ||
| 880 | struct{ | ||
| 881 | u8 action_code; | ||
| 849 | u8 dialog_token; | 882 | u8 dialog_token; |
| 850 | u8 element_id; | 883 | u8 element_id; |
| 851 | u8 length; | 884 | u8 length; |
| @@ -1027,6 +1060,26 @@ enum ieee80211_p2p_attr_id { | |||
| 1027 | IEEE80211_P2P_ATTR_MAX | 1060 | IEEE80211_P2P_ATTR_MAX |
| 1028 | }; | 1061 | }; |
| 1029 | 1062 | ||
| 1063 | /* Notice of Absence attribute - described in P2P spec 4.1.14 */ | ||
| 1064 | /* Typical max value used here */ | ||
| 1065 | #define IEEE80211_P2P_NOA_DESC_MAX 4 | ||
| 1066 | |||
| 1067 | struct ieee80211_p2p_noa_desc { | ||
| 1068 | u8 count; | ||
| 1069 | __le32 duration; | ||
| 1070 | __le32 interval; | ||
| 1071 | __le32 start_time; | ||
| 1072 | } __packed; | ||
| 1073 | |||
| 1074 | struct ieee80211_p2p_noa_attr { | ||
| 1075 | u8 index; | ||
| 1076 | u8 oppps_ctwindow; | ||
| 1077 | struct ieee80211_p2p_noa_desc desc[IEEE80211_P2P_NOA_DESC_MAX]; | ||
| 1078 | } __packed; | ||
| 1079 | |||
| 1080 | #define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7) | ||
| 1081 | #define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F | ||
| 1082 | |||
| 1030 | /** | 1083 | /** |
| 1031 | * struct ieee80211_bar - HT Block Ack Request | 1084 | * struct ieee80211_bar - HT Block Ack Request |
| 1032 | * | 1085 | * |
| @@ -1618,6 +1671,7 @@ enum ieee80211_eid { | |||
| 1618 | 1671 | ||
| 1619 | WLAN_EID_HT_CAPABILITY = 45, | 1672 | WLAN_EID_HT_CAPABILITY = 45, |
| 1620 | WLAN_EID_HT_OPERATION = 61, | 1673 | WLAN_EID_HT_OPERATION = 61, |
| 1674 | WLAN_EID_SECONDARY_CHANNEL_OFFSET = 62, | ||
| 1621 | 1675 | ||
| 1622 | WLAN_EID_RSN = 48, | 1676 | WLAN_EID_RSN = 48, |
| 1623 | WLAN_EID_MMIE = 76, | 1677 | WLAN_EID_MMIE = 76, |
| @@ -1652,6 +1706,8 @@ enum ieee80211_eid { | |||
| 1652 | WLAN_EID_VHT_CAPABILITY = 191, | 1706 | WLAN_EID_VHT_CAPABILITY = 191, |
| 1653 | WLAN_EID_VHT_OPERATION = 192, | 1707 | WLAN_EID_VHT_OPERATION = 192, |
| 1654 | WLAN_EID_OPMODE_NOTIF = 199, | 1708 | WLAN_EID_OPMODE_NOTIF = 199, |
| 1709 | WLAN_EID_WIDE_BW_CHANNEL_SWITCH = 194, | ||
| 1710 | WLAN_EID_CHANNEL_SWITCH_WRAPPER = 196, | ||
| 1655 | 1711 | ||
| 1656 | /* 802.11ad */ | 1712 | /* 802.11ad */ |
| 1657 | WLAN_EID_NON_TX_BSSID_CAP = 83, | 1713 | WLAN_EID_NON_TX_BSSID_CAP = 83, |
| @@ -1775,6 +1831,7 @@ enum ieee80211_key_len { | |||
| 1775 | 1831 | ||
| 1776 | /* Public action codes */ | 1832 | /* Public action codes */ |
| 1777 | enum ieee80211_pub_actioncode { | 1833 | enum ieee80211_pub_actioncode { |
| 1834 | WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4, | ||
| 1778 | WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14, | 1835 | WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14, |
| 1779 | }; | 1836 | }; |
| 1780 | 1837 | ||
| @@ -1935,6 +1992,16 @@ enum ieee80211_timeout_interval_type { | |||
| 1935 | WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */, | 1992 | WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */, |
| 1936 | }; | 1993 | }; |
| 1937 | 1994 | ||
| 1995 | /** | ||
| 1996 | * struct ieee80211_timeout_interval_ie - Timeout Interval element | ||
| 1997 | * @type: type, see &enum ieee80211_timeout_interval_type | ||
| 1998 | * @value: timeout interval value | ||
| 1999 | */ | ||
| 2000 | struct ieee80211_timeout_interval_ie { | ||
| 2001 | u8 type; | ||
| 2002 | __le32 value; | ||
| 2003 | } __packed; | ||
| 2004 | |||
| 1938 | /* BACK action code */ | 2005 | /* BACK action code */ |
| 1939 | enum ieee80211_back_actioncode { | 2006 | enum ieee80211_back_actioncode { |
| 1940 | WLAN_ACTION_ADDBA_REQ = 0, | 2007 | WLAN_ACTION_ADDBA_REQ = 0, |
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h new file mode 100644 index 000000000000..1ade657d5fc1 --- /dev/null +++ b/include/linux/platform_data/brcmfmac-sdio.h | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _LINUX_BRCMFMAC_PLATFORM_H | ||
| 18 | #define _LINUX_BRCMFMAC_PLATFORM_H | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Platform specific driver functions and data. Through the platform specific | ||
| 22 | * device data functions can be provided to help the brcmfmac driver to | ||
| 23 | * operate with the device in combination with the used platform. | ||
| 24 | * | ||
| 25 | * Use the platform data in the following (similar) way: | ||
| 26 | * | ||
| 27 | * | ||
| 28 | #include <brcmfmac_platform.h> | ||
| 29 | |||
| 30 | |||
| 31 | static void brcmfmac_power_on(void) | ||
| 32 | { | ||
| 33 | } | ||
| 34 | |||
| 35 | static void brcmfmac_power_off(void) | ||
| 36 | { | ||
| 37 | } | ||
| 38 | |||
| 39 | static void brcmfmac_reset(void) | ||
| 40 | { | ||
| 41 | } | ||
| 42 | |||
| 43 | static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = { | ||
| 44 | .power_on = brcmfmac_power_on, | ||
| 45 | .power_off = brcmfmac_power_off, | ||
| 46 | .reset = brcmfmac_reset | ||
| 47 | }; | ||
| 48 | |||
| 49 | static struct platform_device brcmfmac_device = { | ||
| 50 | .name = BRCMFMAC_SDIO_PDATA_NAME, | ||
| 51 | .id = PLATFORM_DEVID_NONE, | ||
| 52 | .dev.platform_data = &brcmfmac_sdio_pdata | ||
| 53 | }; | ||
| 54 | |||
| 55 | void __init brcmfmac_init_pdata(void) | ||
| 56 | { | ||
| 57 | brcmfmac_sdio_pdata.oob_irq_supported = true; | ||
| 58 | brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB); | ||
| 59 | brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ | | ||
| 60 | IORESOURCE_IRQ_HIGHLEVEL; | ||
| 61 | platform_device_register(&brcmfmac_device); | ||
| 62 | } | ||
| 63 | * | ||
| 64 | * | ||
| 65 | * Note: the brcmfmac can be loaded as module or be statically built-in into | ||
| 66 | * the kernel. If built-in then do note that it uses module_init (and | ||
| 67 | * module_exit) routines which equal device_initcall. So if you intend to | ||
| 68 | * create a module with the platform specific data for the brcmfmac and have | ||
| 69 | * it built-in to the kernel then use a higher initcall then device_initcall | ||
| 70 | * (see init.h). If this is not done then brcmfmac will load without problems | ||
| 71 | * but will not pickup the platform data. | ||
| 72 | * | ||
| 73 | * When the driver does not "detect" platform driver data then it will continue | ||
| 74 | * without reporting anything and just assume there is no data needed. Which is | ||
| 75 | * probably true for most platforms. | ||
| 76 | * | ||
| 77 | * Explanation of the platform_data fields: | ||
| 78 | * | ||
| 79 | * drive_strength: is the preferred drive_strength to be used for the SDIO | ||
| 80 | * pins. If 0 then a default value will be used. This is the target drive | ||
| 81 | * strength, the exact drive strength which will be used depends on the | ||
| 82 | * capabilities of the device. | ||
| 83 | * | ||
| 84 | * oob_irq_supported: does the board have support for OOB interrupts. SDIO | ||
| 85 | * in-band interrupts are relatively slow and for having less overhead on | ||
| 86 | * interrupt processing an out of band interrupt can be used. If the HW | ||
| 87 | * supports this then enable this by setting this field to true and configure | ||
| 88 | * the oob related fields. | ||
| 89 | * | ||
| 90 | * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are | ||
| 91 | * used for registering the irq using request_irq function. | ||
| 92 | * | ||
| 93 | * power_on: This function is called by the brcmfmac when the module gets | ||
| 94 | * loaded. This can be particularly useful for low power devices. The platform | ||
| 95 | * spcific routine may for example decide to power up the complete device. | ||
| 96 | * If there is no use-case for this function then provide NULL. | ||
| 97 | * | ||
| 98 | * power_off: This function is called by the brcmfmac when the module gets | ||
| 99 | * unloaded. At this point the device can be powered down or otherwise be reset. | ||
| 100 | * So if an actual power_off is not supported but reset is then reset the device | ||
| 101 | * when this function gets called. This can be particularly useful for low power | ||
| 102 | * devices. If there is no use-case for this function (either power-down or | ||
| 103 | * reset) then provide NULL. | ||
| 104 | * | ||
| 105 | * reset: This function can get called if the device communication broke down. | ||
| 106 | * This functionality is particularly useful in case of SDIO type devices. It is | ||
| 107 | * possible to reset a dongle via sdio data interface, but it requires that | ||
| 108 | * this is fully functional. This function is chip/module specific and this | ||
| 109 | * function should return only after the complete reset has completed. | ||
| 110 | */ | ||
| 111 | |||
| 112 | #define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio" | ||
| 113 | |||
| 114 | struct brcmfmac_sdio_platform_data { | ||
| 115 | unsigned int drive_strength; | ||
| 116 | bool oob_irq_supported; | ||
| 117 | unsigned int oob_irq_nr; | ||
| 118 | unsigned long oob_irq_flags; | ||
| 119 | void (*power_on)(void); | ||
| 120 | void (*power_off)(void); | ||
| 121 | void (*reset)(void); | ||
| 122 | }; | ||
| 123 | |||
| 124 | #endif /* _LINUX_BRCMFMAC_PLATFORM_H */ | ||
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index ed6e9552252e..6912ef9a1881 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
| @@ -193,11 +193,11 @@ static inline bool bdaddr_type_is_le(__u8 type) | |||
| 193 | #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) | 193 | #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) |
| 194 | 194 | ||
| 195 | /* Copy, swap, convert BD Address */ | 195 | /* Copy, swap, convert BD Address */ |
| 196 | static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) | 196 | static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2) |
| 197 | { | 197 | { |
| 198 | return memcmp(ba1, ba2, sizeof(bdaddr_t)); | 198 | return memcmp(ba1, ba2, sizeof(bdaddr_t)); |
| 199 | } | 199 | } |
| 200 | static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) | 200 | static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src) |
| 201 | { | 201 | { |
| 202 | memcpy(dst, src, sizeof(bdaddr_t)); | 202 | memcpy(dst, src, sizeof(bdaddr_t)); |
| 203 | } | 203 | } |
| @@ -266,6 +266,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status); | |||
| 266 | 266 | ||
| 267 | struct hci_req_ctrl { | 267 | struct hci_req_ctrl { |
| 268 | bool start; | 268 | bool start; |
| 269 | u8 event; | ||
| 269 | hci_req_complete_t complete; | 270 | hci_req_complete_t complete; |
| 270 | }; | 271 | }; |
| 271 | 272 | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b3308927a0a1..e0512aaef4b8 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
| @@ -984,6 +984,9 @@ struct hci_cp_le_set_adv_data { | |||
| 984 | 984 | ||
| 985 | #define HCI_OP_LE_SET_ADV_ENABLE 0x200a | 985 | #define HCI_OP_LE_SET_ADV_ENABLE 0x200a |
| 986 | 986 | ||
| 987 | #define LE_SCAN_PASSIVE 0x00 | ||
| 988 | #define LE_SCAN_ACTIVE 0x01 | ||
| 989 | |||
| 987 | #define HCI_OP_LE_SET_SCAN_PARAM 0x200b | 990 | #define HCI_OP_LE_SET_SCAN_PARAM 0x200b |
| 988 | struct hci_cp_le_set_scan_param { | 991 | struct hci_cp_le_set_scan_param { |
| 989 | __u8 type; | 992 | __u8 type; |
| @@ -993,8 +996,10 @@ struct hci_cp_le_set_scan_param { | |||
| 993 | __u8 filter_policy; | 996 | __u8 filter_policy; |
| 994 | } __packed; | 997 | } __packed; |
| 995 | 998 | ||
| 996 | #define LE_SCANNING_DISABLED 0x00 | 999 | #define LE_SCAN_DISABLE 0x00 |
| 997 | #define LE_SCANNING_ENABLED 0x01 | 1000 | #define LE_SCAN_ENABLE 0x01 |
| 1001 | #define LE_SCAN_FILTER_DUP_DISABLE 0x00 | ||
| 1002 | #define LE_SCAN_FILTER_DUP_ENABLE 0x01 | ||
| 998 | 1003 | ||
| 999 | #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c | 1004 | #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c |
| 1000 | struct hci_cp_le_set_scan_enable { | 1005 | struct hci_cp_le_set_scan_enable { |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 358a6983d3bb..80d718a9b31f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
| @@ -134,6 +134,8 @@ struct amp_assoc { | |||
| 134 | __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; | 134 | __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | #define HCI_MAX_PAGES 3 | ||
| 138 | |||
| 137 | #define NUM_REASSEMBLY 4 | 139 | #define NUM_REASSEMBLY 4 |
| 138 | struct hci_dev { | 140 | struct hci_dev { |
| 139 | struct list_head list; | 141 | struct list_head list; |
| @@ -151,8 +153,8 @@ struct hci_dev { | |||
| 151 | __u8 dev_class[3]; | 153 | __u8 dev_class[3]; |
| 152 | __u8 major_class; | 154 | __u8 major_class; |
| 153 | __u8 minor_class; | 155 | __u8 minor_class; |
| 154 | __u8 features[8]; | 156 | __u8 max_page; |
| 155 | __u8 host_features[8]; | 157 | __u8 features[HCI_MAX_PAGES][8]; |
| 156 | __u8 le_features[8]; | 158 | __u8 le_features[8]; |
| 157 | __u8 le_white_list_size; | 159 | __u8 le_white_list_size; |
| 158 | __u8 le_states[8]; | 160 | __u8 le_states[8]; |
| @@ -244,6 +246,7 @@ struct hci_dev { | |||
| 244 | struct sk_buff_head raw_q; | 246 | struct sk_buff_head raw_q; |
| 245 | struct sk_buff_head cmd_q; | 247 | struct sk_buff_head cmd_q; |
| 246 | 248 | ||
| 249 | struct sk_buff *recv_evt; | ||
| 247 | struct sk_buff *sent_cmd; | 250 | struct sk_buff *sent_cmd; |
| 248 | struct sk_buff *reassembly[NUM_REASSEMBLY]; | 251 | struct sk_buff *reassembly[NUM_REASSEMBLY]; |
| 249 | 252 | ||
| @@ -268,8 +271,6 @@ struct hci_dev { | |||
| 268 | 271 | ||
| 269 | struct hci_dev_stats stat; | 272 | struct hci_dev_stats stat; |
| 270 | 273 | ||
| 271 | struct sk_buff_head driver_init; | ||
| 272 | |||
| 273 | atomic_t promisc; | 274 | atomic_t promisc; |
| 274 | 275 | ||
| 275 | struct dentry *debugfs; | 276 | struct dentry *debugfs; |
| @@ -292,6 +293,7 @@ struct hci_dev { | |||
| 292 | int (*open)(struct hci_dev *hdev); | 293 | int (*open)(struct hci_dev *hdev); |
| 293 | int (*close)(struct hci_dev *hdev); | 294 | int (*close)(struct hci_dev *hdev); |
| 294 | int (*flush)(struct hci_dev *hdev); | 295 | int (*flush)(struct hci_dev *hdev); |
| 296 | int (*setup)(struct hci_dev *hdev); | ||
| 295 | int (*send)(struct sk_buff *skb); | 297 | int (*send)(struct sk_buff *skb); |
| 296 | void (*notify)(struct hci_dev *hdev, unsigned int evt); | 298 | void (*notify)(struct hci_dev *hdev, unsigned int evt); |
| 297 | int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); | 299 | int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); |
| @@ -313,7 +315,7 @@ struct hci_conn { | |||
| 313 | bool out; | 315 | bool out; |
| 314 | __u8 attempt; | 316 | __u8 attempt; |
| 315 | __u8 dev_class[3]; | 317 | __u8 dev_class[3]; |
| 316 | __u8 features[8]; | 318 | __u8 features[HCI_MAX_PAGES][8]; |
| 317 | __u16 interval; | 319 | __u16 interval; |
| 318 | __u16 pkt_type; | 320 | __u16 pkt_type; |
| 319 | __u16 link_policy; | 321 | __u16 link_policy; |
| @@ -345,7 +347,6 @@ struct hci_conn { | |||
| 345 | struct timer_list auto_accept_timer; | 347 | struct timer_list auto_accept_timer; |
| 346 | 348 | ||
| 347 | struct device dev; | 349 | struct device dev; |
| 348 | atomic_t devref; | ||
| 349 | 350 | ||
| 350 | struct hci_dev *hdev; | 351 | struct hci_dev *hdev; |
| 351 | void *l2cap_data; | 352 | void *l2cap_data; |
| @@ -584,7 +585,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); | |||
| 584 | int hci_conn_del(struct hci_conn *conn); | 585 | int hci_conn_del(struct hci_conn *conn); |
| 585 | void hci_conn_hash_flush(struct hci_dev *hdev); | 586 | void hci_conn_hash_flush(struct hci_dev *hdev); |
| 586 | void hci_conn_check_pending(struct hci_dev *hdev); | 587 | void hci_conn_check_pending(struct hci_dev *hdev); |
| 587 | void hci_conn_accept(struct hci_conn *conn, int mask); | ||
| 588 | 588 | ||
| 589 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | 589 | struct hci_chan *hci_chan_create(struct hci_conn *conn); |
| 590 | void hci_chan_del(struct hci_chan *chan); | 590 | void hci_chan_del(struct hci_chan *chan); |
| @@ -601,8 +601,36 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); | |||
| 601 | 601 | ||
| 602 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); | 602 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); |
| 603 | 603 | ||
| 604 | void hci_conn_hold_device(struct hci_conn *conn); | 604 | /* |
| 605 | void hci_conn_put_device(struct hci_conn *conn); | 605 | * hci_conn_get() and hci_conn_put() are used to control the life-time of an |
| 606 | * "hci_conn" object. They do not guarantee that the hci_conn object is running, | ||
| 607 | * working or anything else. They just guarantee that the object is available | ||
| 608 | * and can be dereferenced. So you can use its locks, local variables and any | ||
| 609 | * other constant data. | ||
| 610 | * Before accessing runtime data, you _must_ lock the object and then check that | ||
| 611 | * it is still running. As soon as you release the locks, the connection might | ||
| 612 | * get dropped, though. | ||
| 613 | * | ||
| 614 | * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control | ||
| 615 | * how long the underlying connection is held. So every channel that runs on the | ||
| 616 | * hci_conn object calls this to prevent the connection from disappearing. As | ||
| 617 | * long as you hold a device, you must also guarantee that you have a valid | ||
| 618 | * reference to the device via hci_conn_get() (or the initial reference from | ||
| 619 | * hci_conn_add()). | ||
| 620 | * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't | ||
| 621 | * break because nobody cares for that. But this means, we cannot use | ||
| 622 | * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). | ||
| 623 | */ | ||
| 624 | |||
| 625 | static inline void hci_conn_get(struct hci_conn *conn) | ||
| 626 | { | ||
| 627 | get_device(&conn->dev); | ||
| 628 | } | ||
| 629 | |||
| 630 | static inline void hci_conn_put(struct hci_conn *conn) | ||
| 631 | { | ||
| 632 | put_device(&conn->dev); | ||
| 633 | } | ||
| 606 | 634 | ||
| 607 | static inline void hci_conn_hold(struct hci_conn *conn) | 635 | static inline void hci_conn_hold(struct hci_conn *conn) |
| 608 | { | 636 | { |
| @@ -612,7 +640,7 @@ static inline void hci_conn_hold(struct hci_conn *conn) | |||
| 612 | cancel_delayed_work(&conn->disc_work); | 640 | cancel_delayed_work(&conn->disc_work); |
| 613 | } | 641 | } |
| 614 | 642 | ||
| 615 | static inline void hci_conn_put(struct hci_conn *conn) | 643 | static inline void hci_conn_drop(struct hci_conn *conn) |
| 616 | { | 644 | { |
| 617 | BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); | 645 | BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); |
| 618 | 646 | ||
| @@ -760,29 +788,29 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
| 760 | #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) | 788 | #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) |
| 761 | 789 | ||
| 762 | /* ----- LMP capabilities ----- */ | 790 | /* ----- LMP capabilities ----- */ |
| 763 | #define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) | 791 | #define lmp_encrypt_capable(dev) ((dev)->features[0][0] & LMP_ENCRYPT) |
| 764 | #define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) | 792 | #define lmp_rswitch_capable(dev) ((dev)->features[0][0] & LMP_RSWITCH) |
| 765 | #define lmp_hold_capable(dev) ((dev)->features[0] & LMP_HOLD) | 793 | #define lmp_hold_capable(dev) ((dev)->features[0][0] & LMP_HOLD) |
| 766 | #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) | 794 | #define lmp_sniff_capable(dev) ((dev)->features[0][0] & LMP_SNIFF) |
| 767 | #define lmp_park_capable(dev) ((dev)->features[1] & LMP_PARK) | 795 | #define lmp_park_capable(dev) ((dev)->features[0][1] & LMP_PARK) |
| 768 | #define lmp_inq_rssi_capable(dev) ((dev)->features[3] & LMP_RSSI_INQ) | 796 | #define lmp_inq_rssi_capable(dev) ((dev)->features[0][3] & LMP_RSSI_INQ) |
| 769 | #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) | 797 | #define lmp_esco_capable(dev) ((dev)->features[0][3] & LMP_ESCO) |
| 770 | #define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) | 798 | #define lmp_bredr_capable(dev) (!((dev)->features[0][4] & LMP_NO_BREDR)) |
| 771 | #define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) | 799 | #define lmp_le_capable(dev) ((dev)->features[0][4] & LMP_LE) |
| 772 | #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) | 800 | #define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR) |
| 773 | #define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) | 801 | #define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC) |
| 774 | #define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) | 802 | #define lmp_ext_inq_capable(dev) ((dev)->features[0][6] & LMP_EXT_INQ) |
| 775 | #define lmp_le_br_capable(dev) !!((dev)->features[6] & LMP_SIMUL_LE_BR) | 803 | #define lmp_le_br_capable(dev) (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR)) |
| 776 | #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) | 804 | #define lmp_ssp_capable(dev) ((dev)->features[0][6] & LMP_SIMPLE_PAIR) |
| 777 | #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) | 805 | #define lmp_no_flush_capable(dev) ((dev)->features[0][6] & LMP_NO_FLUSH) |
| 778 | #define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) | 806 | #define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO) |
| 779 | #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR) | 807 | #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR) |
| 780 | #define lmp_ext_feat_capable(dev) ((dev)->features[7] & LMP_EXTFEATURES) | 808 | #define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES) |
| 781 | 809 | ||
| 782 | /* ----- Extended LMP capabilities ----- */ | 810 | /* ----- Extended LMP capabilities ----- */ |
| 783 | #define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) | 811 | #define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) |
| 784 | #define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE) | 812 | #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) |
| 785 | #define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR) | 813 | #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) |
| 786 | 814 | ||
| 787 | /* returns true if at least one AMP active */ | 815 | /* returns true if at least one AMP active */ |
| 788 | static inline bool hci_amp_capable(void) | 816 | static inline bool hci_amp_capable(void) |
| @@ -1054,8 +1082,14 @@ struct hci_request { | |||
| 1054 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); | 1082 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); |
| 1055 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); | 1083 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); |
| 1056 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); | 1084 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); |
| 1085 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, | ||
| 1086 | u8 event); | ||
| 1057 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); | 1087 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); |
| 1058 | void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status); | 1088 | |
| 1089 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | ||
| 1090 | void *param, u32 timeout); | ||
| 1091 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | ||
| 1092 | void *param, u8 event, u32 timeout); | ||
| 1059 | 1093 | ||
| 1060 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); | 1094 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); |
| 1061 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); | 1095 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index cdd33021f831..fb94cf13c777 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
| @@ -583,6 +583,14 @@ struct l2cap_conn { | |||
| 583 | 583 | ||
| 584 | struct list_head chan_l; | 584 | struct list_head chan_l; |
| 585 | struct mutex chan_lock; | 585 | struct mutex chan_lock; |
| 586 | struct kref ref; | ||
| 587 | struct list_head users; | ||
| 588 | }; | ||
| 589 | |||
| 590 | struct l2cap_user { | ||
| 591 | struct list_head list; | ||
| 592 | int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user); | ||
| 593 | void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user); | ||
| 586 | }; | 594 | }; |
| 587 | 595 | ||
| 588 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 | 596 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 |
| @@ -786,6 +794,7 @@ extern bool disable_ertm; | |||
| 786 | 794 | ||
| 787 | int l2cap_init_sockets(void); | 795 | int l2cap_init_sockets(void); |
| 788 | void l2cap_cleanup_sockets(void); | 796 | void l2cap_cleanup_sockets(void); |
| 797 | bool l2cap_is_socket(struct socket *sock); | ||
| 789 | 798 | ||
| 790 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); | 799 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); |
| 791 | int __l2cap_wait_ack(struct sock *sk); | 800 | int __l2cap_wait_ack(struct sock *sk); |
| @@ -812,4 +821,10 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, | |||
| 812 | u8 status); | 821 | u8 status); |
| 813 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); | 822 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); |
| 814 | 823 | ||
| 824 | void l2cap_conn_get(struct l2cap_conn *conn); | ||
| 825 | void l2cap_conn_put(struct l2cap_conn *conn); | ||
| 826 | |||
| 827 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); | ||
| 828 | void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); | ||
| 829 | |||
| 815 | #endif /* __L2CAP_H */ | 830 | #endif /* __L2CAP_H */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bdba9b619064..26b5b692c22b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -1998,6 +1998,16 @@ struct cfg80211_update_ft_ies_params { | |||
| 1998 | * advertise the support for MAC based ACL have to implement this callback. | 1998 | * advertise the support for MAC based ACL have to implement this callback. |
| 1999 | * | 1999 | * |
| 2000 | * @start_radar_detection: Start radar detection in the driver. | 2000 | * @start_radar_detection: Start radar detection in the driver. |
| 2001 | * | ||
| 2002 | * @update_ft_ies: Provide updated Fast BSS Transition information to the | ||
| 2003 | * driver. If the SME is in the driver/firmware, this information can be | ||
| 2004 | * used in building Authentication and Reassociation Request frames. | ||
| 2005 | * | ||
| 2006 | * @crit_proto_start: Indicates a critical protocol needs more link reliability | ||
| 2007 | * for a given duration (milliseconds). The protocol is provided so the | ||
| 2008 | * driver can take the most appropriate actions. | ||
| 2009 | * @crit_proto_stop: Indicates critical protocol no longer needs increased link | ||
| 2010 | * reliability. This operation can not fail. | ||
| 2001 | */ | 2011 | */ |
| 2002 | struct cfg80211_ops { | 2012 | struct cfg80211_ops { |
| 2003 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 2013 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
| @@ -2227,6 +2237,12 @@ struct cfg80211_ops { | |||
| 2227 | struct cfg80211_chan_def *chandef); | 2237 | struct cfg80211_chan_def *chandef); |
| 2228 | int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev, | 2238 | int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev, |
| 2229 | struct cfg80211_update_ft_ies_params *ftie); | 2239 | struct cfg80211_update_ft_ies_params *ftie); |
| 2240 | int (*crit_proto_start)(struct wiphy *wiphy, | ||
| 2241 | struct wireless_dev *wdev, | ||
| 2242 | enum nl80211_crit_proto_id protocol, | ||
| 2243 | u16 duration); | ||
| 2244 | void (*crit_proto_stop)(struct wiphy *wiphy, | ||
| 2245 | struct wireless_dev *wdev); | ||
| 2230 | }; | 2246 | }; |
| 2231 | 2247 | ||
| 2232 | /* | 2248 | /* |
| @@ -4020,6 +4036,17 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | |||
| 4020 | void cfg80211_ch_switch_notify(struct net_device *dev, | 4036 | void cfg80211_ch_switch_notify(struct net_device *dev, |
| 4021 | struct cfg80211_chan_def *chandef); | 4037 | struct cfg80211_chan_def *chandef); |
| 4022 | 4038 | ||
| 4039 | /** | ||
| 4040 | * ieee80211_operating_class_to_band - convert operating class to band | ||
| 4041 | * | ||
| 4042 | * @operating_class: the operating class to convert | ||
| 4043 | * @band: band pointer to fill | ||
| 4044 | * | ||
| 4045 | * Returns %true if the conversion was successful, %false otherwise. | ||
| 4046 | */ | ||
| 4047 | bool ieee80211_operating_class_to_band(u8 operating_class, | ||
| 4048 | enum ieee80211_band *band); | ||
| 4049 | |||
| 4023 | /* | 4050 | /* |
| 4024 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation | 4051 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation |
| 4025 | * @dev: the device on which the operation is requested | 4052 | * @dev: the device on which the operation is requested |
| @@ -4122,6 +4149,17 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 4122 | struct cfg80211_wowlan_wakeup *wakeup, | 4149 | struct cfg80211_wowlan_wakeup *wakeup, |
| 4123 | gfp_t gfp); | 4150 | gfp_t gfp); |
| 4124 | 4151 | ||
| 4152 | /** | ||
| 4153 | * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver. | ||
| 4154 | * | ||
| 4155 | * @wdev: the wireless device for which critical protocol is stopped. | ||
| 4156 | * | ||
| 4157 | * This function can be called by the driver to indicate it has reverted | ||
| 4158 | * operation back to normal. One reason could be that the duration given | ||
| 4159 | * by .crit_proto_start() has expired. | ||
| 4160 | */ | ||
| 4161 | void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); | ||
| 4162 | |||
| 4125 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 4163 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
| 4126 | 4164 | ||
| 4127 | /* wiphy_printk helpers, similar to dev_printk */ | 4165 | /* wiphy_printk helpers, similar to dev_printk */ |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dd73b8c6746b..04c2d4670dc6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -128,6 +128,7 @@ enum ieee80211_ac_numbers { | |||
| 128 | * 2^n-1 in the range 1..32767] | 128 | * 2^n-1 in the range 1..32767] |
| 129 | * @cw_max: maximum contention window [like @cw_min] | 129 | * @cw_max: maximum contention window [like @cw_min] |
| 130 | * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled | 130 | * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled |
| 131 | * @acm: is mandatory admission control required for the access category | ||
| 131 | * @uapsd: is U-APSD mode enabled for the queue | 132 | * @uapsd: is U-APSD mode enabled for the queue |
| 132 | */ | 133 | */ |
| 133 | struct ieee80211_tx_queue_params { | 134 | struct ieee80211_tx_queue_params { |
| @@ -135,6 +136,7 @@ struct ieee80211_tx_queue_params { | |||
| 135 | u16 cw_min; | 136 | u16 cw_min; |
| 136 | u16 cw_max; | 137 | u16 cw_max; |
| 137 | u8 aifs; | 138 | u8 aifs; |
| 139 | bool acm; | ||
| 138 | bool uapsd; | 140 | bool uapsd; |
| 139 | }; | 141 | }; |
| 140 | 142 | ||
| @@ -209,7 +211,7 @@ struct ieee80211_chanctx_conf { | |||
| 209 | * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note | 211 | * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note |
| 210 | * that it is only ever disabled for station mode. | 212 | * that it is only ever disabled for station mode. |
| 211 | * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. | 213 | * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. |
| 212 | * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) | 214 | * @BSS_CHANGED_SSID: SSID changed for this BSS (AP and IBSS mode) |
| 213 | * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) | 215 | * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) |
| 214 | * @BSS_CHANGED_PS: PS changed for this BSS (STA mode) | 216 | * @BSS_CHANGED_PS: PS changed for this BSS (STA mode) |
| 215 | * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface | 217 | * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface |
| @@ -326,12 +328,11 @@ enum ieee80211_rssi_event { | |||
| 326 | * your driver/device needs to do. | 328 | * your driver/device needs to do. |
| 327 | * @ps: power-save mode (STA only). This flag is NOT affected by | 329 | * @ps: power-save mode (STA only). This flag is NOT affected by |
| 328 | * offchannel/dynamic_ps operations. | 330 | * offchannel/dynamic_ps operations. |
| 329 | * @ssid: The SSID of the current vif. Only valid in AP-mode. | 331 | * @ssid: The SSID of the current vif. Valid in AP and IBSS mode. |
| 330 | * @ssid_len: Length of SSID given in @ssid. | 332 | * @ssid_len: Length of SSID given in @ssid. |
| 331 | * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. | 333 | * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. |
| 332 | * @txpower: TX power in dBm | 334 | * @txpower: TX power in dBm |
| 333 | * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces | 335 | * @p2p_noa_attr: P2P NoA attribute for P2P powersave |
| 334 | * @p2p_oppps: P2P opportunistic PS is enabled | ||
| 335 | */ | 336 | */ |
| 336 | struct ieee80211_bss_conf { | 337 | struct ieee80211_bss_conf { |
| 337 | const u8 *bssid; | 338 | const u8 *bssid; |
| @@ -365,8 +366,7 @@ struct ieee80211_bss_conf { | |||
| 365 | size_t ssid_len; | 366 | size_t ssid_len; |
| 366 | bool hidden_ssid; | 367 | bool hidden_ssid; |
| 367 | int txpower; | 368 | int txpower; |
| 368 | u8 p2p_ctwindow; | 369 | struct ieee80211_p2p_noa_attr p2p_noa_attr; |
| 369 | bool p2p_oppps; | ||
| 370 | }; | 370 | }; |
| 371 | 371 | ||
| 372 | /** | 372 | /** |
| @@ -563,6 +563,9 @@ enum mac80211_rate_control_flags { | |||
| 563 | /* maximum number of rate stages */ | 563 | /* maximum number of rate stages */ |
| 564 | #define IEEE80211_TX_MAX_RATES 4 | 564 | #define IEEE80211_TX_MAX_RATES 4 |
| 565 | 565 | ||
| 566 | /* maximum number of rate table entries */ | ||
| 567 | #define IEEE80211_TX_RATE_TABLE_SIZE 4 | ||
| 568 | |||
| 566 | /** | 569 | /** |
| 567 | * struct ieee80211_tx_rate - rate selection/status | 570 | * struct ieee80211_tx_rate - rate selection/status |
| 568 | * | 571 | * |
| @@ -603,8 +606,8 @@ static inline void ieee80211_rate_set_vht(struct ieee80211_tx_rate *rate, | |||
| 603 | u8 mcs, u8 nss) | 606 | u8 mcs, u8 nss) |
| 604 | { | 607 | { |
| 605 | WARN_ON(mcs & ~0xF); | 608 | WARN_ON(mcs & ~0xF); |
| 606 | WARN_ON(nss & ~0x7); | 609 | WARN_ON((nss - 1) & ~0x7); |
| 607 | rate->idx = (nss << 4) | mcs; | 610 | rate->idx = ((nss - 1) << 4) | mcs; |
| 608 | } | 611 | } |
| 609 | 612 | ||
| 610 | static inline u8 | 613 | static inline u8 |
| @@ -616,7 +619,7 @@ ieee80211_rate_get_vht_mcs(const struct ieee80211_tx_rate *rate) | |||
| 616 | static inline u8 | 619 | static inline u8 |
| 617 | ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) | 620 | ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) |
| 618 | { | 621 | { |
| 619 | return rate->idx >> 4; | 622 | return (rate->idx >> 4) + 1; |
| 620 | } | 623 | } |
| 621 | 624 | ||
| 622 | /** | 625 | /** |
| @@ -657,7 +660,11 @@ struct ieee80211_tx_info { | |||
| 657 | struct ieee80211_tx_rate rates[ | 660 | struct ieee80211_tx_rate rates[ |
| 658 | IEEE80211_TX_MAX_RATES]; | 661 | IEEE80211_TX_MAX_RATES]; |
| 659 | s8 rts_cts_rate_idx; | 662 | s8 rts_cts_rate_idx; |
| 660 | /* 3 bytes free */ | 663 | u8 use_rts:1; |
| 664 | u8 use_cts_prot:1; | ||
| 665 | u8 short_preamble:1; | ||
| 666 | u8 skip_table:1; | ||
| 667 | /* 2 bytes free */ | ||
| 661 | }; | 668 | }; |
| 662 | /* only needed before rate control */ | 669 | /* only needed before rate control */ |
| 663 | unsigned long jiffies; | 670 | unsigned long jiffies; |
| @@ -678,6 +685,8 @@ struct ieee80211_tx_info { | |||
| 678 | struct { | 685 | struct { |
| 679 | struct ieee80211_tx_rate driver_rates[ | 686 | struct ieee80211_tx_rate driver_rates[ |
| 680 | IEEE80211_TX_MAX_RATES]; | 687 | IEEE80211_TX_MAX_RATES]; |
| 688 | u8 pad[4]; | ||
| 689 | |||
| 681 | void *rate_driver_data[ | 690 | void *rate_driver_data[ |
| 682 | IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)]; | 691 | IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)]; |
| 683 | }; | 692 | }; |
| @@ -976,8 +985,7 @@ enum ieee80211_smps_mode { | |||
| 976 | * @power_level: requested transmit power (in dBm), backward compatibility | 985 | * @power_level: requested transmit power (in dBm), backward compatibility |
| 977 | * value only that is set to the minimum of all interfaces | 986 | * value only that is set to the minimum of all interfaces |
| 978 | * | 987 | * |
| 979 | * @channel: the channel to tune to | 988 | * @chandef: the channel definition to tune to |
| 980 | * @channel_type: the channel (HT) type | ||
| 981 | * @radar_enabled: whether radar detection is enabled | 989 | * @radar_enabled: whether radar detection is enabled |
| 982 | * | 990 | * |
| 983 | * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame | 991 | * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame |
| @@ -1003,8 +1011,7 @@ struct ieee80211_conf { | |||
| 1003 | 1011 | ||
| 1004 | u8 long_frame_max_tx_count, short_frame_max_tx_count; | 1012 | u8 long_frame_max_tx_count, short_frame_max_tx_count; |
| 1005 | 1013 | ||
| 1006 | struct ieee80211_channel *channel; | 1014 | struct cfg80211_chan_def chandef; |
| 1007 | enum nl80211_channel_type channel_type; | ||
| 1008 | bool radar_enabled; | 1015 | bool radar_enabled; |
| 1009 | enum ieee80211_smps_mode smps_mode; | 1016 | enum ieee80211_smps_mode smps_mode; |
| 1010 | }; | 1017 | }; |
| @@ -1021,13 +1028,13 @@ struct ieee80211_conf { | |||
| 1021 | * the driver passed into mac80211. | 1028 | * the driver passed into mac80211. |
| 1022 | * @block_tx: Indicates whether transmission must be blocked before the | 1029 | * @block_tx: Indicates whether transmission must be blocked before the |
| 1023 | * scheduled channel switch, as indicated by the AP. | 1030 | * scheduled channel switch, as indicated by the AP. |
| 1024 | * @channel: the new channel to switch to | 1031 | * @chandef: the new channel to switch to |
| 1025 | * @count: the number of TBTT's until the channel switch event | 1032 | * @count: the number of TBTT's until the channel switch event |
| 1026 | */ | 1033 | */ |
| 1027 | struct ieee80211_channel_switch { | 1034 | struct ieee80211_channel_switch { |
| 1028 | u64 timestamp; | 1035 | u64 timestamp; |
| 1029 | bool block_tx; | 1036 | bool block_tx; |
| 1030 | struct ieee80211_channel *channel; | 1037 | struct cfg80211_chan_def chandef; |
| 1031 | u8 count; | 1038 | u8 count; |
| 1032 | }; | 1039 | }; |
| 1033 | 1040 | ||
| @@ -1225,6 +1232,24 @@ enum ieee80211_sta_rx_bandwidth { | |||
| 1225 | }; | 1232 | }; |
| 1226 | 1233 | ||
| 1227 | /** | 1234 | /** |
| 1235 | * struct ieee80211_sta_rates - station rate selection table | ||
| 1236 | * | ||
| 1237 | * @rcu_head: RCU head used for freeing the table on update | ||
| 1238 | * @rates: transmit rates/flags to be used by default. | ||
| 1239 | * Overriding entries per-packet is possible by using cb tx control. | ||
| 1240 | */ | ||
| 1241 | struct ieee80211_sta_rates { | ||
| 1242 | struct rcu_head rcu_head; | ||
| 1243 | struct { | ||
| 1244 | s8 idx; | ||
| 1245 | u8 count; | ||
| 1246 | u8 count_cts; | ||
| 1247 | u8 count_rts; | ||
| 1248 | u16 flags; | ||
| 1249 | } rate[IEEE80211_TX_RATE_TABLE_SIZE]; | ||
| 1250 | }; | ||
| 1251 | |||
| 1252 | /** | ||
| 1228 | * struct ieee80211_sta - station table entry | 1253 | * struct ieee80211_sta - station table entry |
| 1229 | * | 1254 | * |
| 1230 | * A station table entry represents a station we are possibly | 1255 | * A station table entry represents a station we are possibly |
| @@ -1251,6 +1276,7 @@ enum ieee80211_sta_rx_bandwidth { | |||
| 1251 | * notifications and capabilities. The value is only valid after | 1276 | * notifications and capabilities. The value is only valid after |
| 1252 | * the station moves to associated state. | 1277 | * the station moves to associated state. |
| 1253 | * @smps_mode: current SMPS mode (off, static or dynamic) | 1278 | * @smps_mode: current SMPS mode (off, static or dynamic) |
| 1279 | * @tx_rates: rate control selection table | ||
| 1254 | */ | 1280 | */ |
| 1255 | struct ieee80211_sta { | 1281 | struct ieee80211_sta { |
| 1256 | u32 supp_rates[IEEE80211_NUM_BANDS]; | 1282 | u32 supp_rates[IEEE80211_NUM_BANDS]; |
| @@ -1264,6 +1290,7 @@ struct ieee80211_sta { | |||
| 1264 | u8 rx_nss; | 1290 | u8 rx_nss; |
| 1265 | enum ieee80211_sta_rx_bandwidth bandwidth; | 1291 | enum ieee80211_sta_rx_bandwidth bandwidth; |
| 1266 | enum ieee80211_smps_mode smps_mode; | 1292 | enum ieee80211_smps_mode smps_mode; |
| 1293 | struct ieee80211_sta_rates __rcu *rates; | ||
| 1267 | 1294 | ||
| 1268 | /* must be last */ | 1295 | /* must be last */ |
| 1269 | u8 drv_priv[0] __aligned(sizeof(void *)); | 1296 | u8 drv_priv[0] __aligned(sizeof(void *)); |
| @@ -1419,6 +1446,9 @@ struct ieee80211_tx_control { | |||
| 1419 | * for different virtual interfaces. See the doc section on HW queue | 1446 | * for different virtual interfaces. See the doc section on HW queue |
| 1420 | * control for more details. | 1447 | * control for more details. |
| 1421 | * | 1448 | * |
| 1449 | * @IEEE80211_HW_SUPPORTS_RC_TABLE: The driver supports using a rate | ||
| 1450 | * selection table provided by the rate control algorithm. | ||
| 1451 | * | ||
| 1422 | * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any | 1452 | * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any |
| 1423 | * P2P Interface. This will be honoured even if more than one interface | 1453 | * P2P Interface. This will be honoured even if more than one interface |
| 1424 | * is supported. | 1454 | * is supported. |
| @@ -1451,6 +1481,7 @@ enum ieee80211_hw_flags { | |||
| 1451 | IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, | 1481 | IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, |
| 1452 | IEEE80211_HW_AP_LINK_PS = 1<<22, | 1482 | IEEE80211_HW_AP_LINK_PS = 1<<22, |
| 1453 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, | 1483 | IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, |
| 1484 | IEEE80211_HW_SUPPORTS_RC_TABLE = 1<<24, | ||
| 1454 | IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, | 1485 | IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, |
| 1455 | IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, | 1486 | IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, |
| 1456 | }; | 1487 | }; |
| @@ -1536,6 +1567,17 @@ enum ieee80211_hw_flags { | |||
| 1536 | * @netdev_features: netdev features to be set in each netdev created | 1567 | * @netdev_features: netdev features to be set in each netdev created |
| 1537 | * from this HW. Note only HW checksum features are currently | 1568 | * from this HW. Note only HW checksum features are currently |
| 1538 | * compatible with mac80211. Other feature bits will be rejected. | 1569 | * compatible with mac80211. Other feature bits will be rejected. |
| 1570 | * | ||
| 1571 | * @uapsd_queues: This bitmap is included in (re)association frame to indicate | ||
| 1572 | * for each access category if it is uAPSD trigger-enabled and delivery- | ||
| 1573 | * enabled. Use IEEE80211_WMM_IE_STA_QOSINFO_AC_* to set this bitmap. | ||
| 1574 | * Each bit corresponds to different AC. Value '1' in specific bit means | ||
| 1575 | * that corresponding AC is both trigger- and delivery-enabled. '0' means | ||
| 1576 | * neither enabled. | ||
| 1577 | * | ||
| 1578 | * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may | ||
| 1579 | * deliver to a WMM STA during any Service Period triggered by the WMM STA. | ||
| 1580 | * Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values. | ||
| 1539 | */ | 1581 | */ |
| 1540 | struct ieee80211_hw { | 1582 | struct ieee80211_hw { |
| 1541 | struct ieee80211_conf conf; | 1583 | struct ieee80211_conf conf; |
| @@ -1561,6 +1603,8 @@ struct ieee80211_hw { | |||
| 1561 | u8 radiotap_mcs_details; | 1603 | u8 radiotap_mcs_details; |
| 1562 | u16 radiotap_vht_details; | 1604 | u16 radiotap_vht_details; |
| 1563 | netdev_features_t netdev_features; | 1605 | netdev_features_t netdev_features; |
| 1606 | u8 uapsd_queues; | ||
| 1607 | u8 uapsd_max_sp_len; | ||
| 1564 | }; | 1608 | }; |
| 1565 | 1609 | ||
| 1566 | /** | 1610 | /** |
| @@ -3124,6 +3168,25 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *sta, | |||
| 3124 | u8 tid, bool buffered); | 3168 | u8 tid, bool buffered); |
| 3125 | 3169 | ||
| 3126 | /** | 3170 | /** |
| 3171 | * ieee80211_get_tx_rates - get the selected transmit rates for a packet | ||
| 3172 | * | ||
| 3173 | * Call this function in a driver with per-packet rate selection support | ||
| 3174 | * to combine the rate info in the packet tx info with the most recent | ||
| 3175 | * rate selection table for the station entry. | ||
| 3176 | * | ||
| 3177 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
| 3178 | * @sta: the receiver station to which this packet is sent. | ||
| 3179 | * @skb: the frame to be transmitted. | ||
| 3180 | * @dest: buffer for extracted rate/retry information | ||
| 3181 | * @max_rates: maximum number of rates to fetch | ||
| 3182 | */ | ||
| 3183 | void ieee80211_get_tx_rates(struct ieee80211_vif *vif, | ||
| 3184 | struct ieee80211_sta *sta, | ||
| 3185 | struct sk_buff *skb, | ||
| 3186 | struct ieee80211_tx_rate *dest, | ||
| 3187 | int max_rates); | ||
| 3188 | |||
| 3189 | /** | ||
| 3127 | * ieee80211_tx_status - transmit status callback | 3190 | * ieee80211_tx_status - transmit status callback |
| 3128 | * | 3191 | * |
| 3129 | * Call this function for all transmitted frames after they have been | 3192 | * Call this function for all transmitted frames after they have been |
| @@ -4098,7 +4161,7 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); | |||
| 4098 | * (deprecated; this will be removed once drivers get updated to use | 4161 | * (deprecated; this will be removed once drivers get updated to use |
| 4099 | * rate_idx_mask) | 4162 | * rate_idx_mask) |
| 4100 | * @rate_idx_mask: user-requested (legacy) rate mask | 4163 | * @rate_idx_mask: user-requested (legacy) rate mask |
| 4101 | * @rate_idx_mcs_mask: user-requested MCS rate mask | 4164 | * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use) |
| 4102 | * @bss: whether this frame is sent out in AP or IBSS mode | 4165 | * @bss: whether this frame is sent out in AP or IBSS mode |
| 4103 | */ | 4166 | */ |
| 4104 | struct ieee80211_tx_rate_control { | 4167 | struct ieee80211_tx_rate_control { |
| @@ -4110,7 +4173,7 @@ struct ieee80211_tx_rate_control { | |||
| 4110 | bool rts, short_preamble; | 4173 | bool rts, short_preamble; |
| 4111 | u8 max_rate_idx; | 4174 | u8 max_rate_idx; |
| 4112 | u32 rate_idx_mask; | 4175 | u32 rate_idx_mask; |
| 4113 | u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; | 4176 | u8 *rate_idx_mcs_mask; |
| 4114 | bool bss; | 4177 | bool bss; |
| 4115 | }; | 4178 | }; |
| 4116 | 4179 | ||
| @@ -4199,37 +4262,55 @@ bool rate_usable_index_exists(struct ieee80211_supported_band *sband, | |||
| 4199 | return false; | 4262 | return false; |
| 4200 | } | 4263 | } |
| 4201 | 4264 | ||
| 4265 | /** | ||
| 4266 | * rate_control_set_rates - pass the sta rate selection to mac80211/driver | ||
| 4267 | * | ||
| 4268 | * When not doing a rate control probe to test rates, rate control should pass | ||
| 4269 | * its rate selection to mac80211. If the driver supports receiving a station | ||
| 4270 | * rate table, it will use it to ensure that frames are always sent based on | ||
| 4271 | * the most recent rate control module decision. | ||
| 4272 | * | ||
| 4273 | * @hw: pointer as obtained from ieee80211_alloc_hw() | ||
| 4274 | * @pubsta: &struct ieee80211_sta pointer to the target destination. | ||
| 4275 | * @rates: new tx rate set to be used for this station. | ||
| 4276 | */ | ||
| 4277 | int rate_control_set_rates(struct ieee80211_hw *hw, | ||
| 4278 | struct ieee80211_sta *pubsta, | ||
| 4279 | struct ieee80211_sta_rates *rates); | ||
| 4280 | |||
| 4202 | int ieee80211_rate_control_register(struct rate_control_ops *ops); | 4281 | int ieee80211_rate_control_register(struct rate_control_ops *ops); |
| 4203 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); | 4282 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); |
| 4204 | 4283 | ||
| 4205 | static inline bool | 4284 | static inline bool |
| 4206 | conf_is_ht20(struct ieee80211_conf *conf) | 4285 | conf_is_ht20(struct ieee80211_conf *conf) |
| 4207 | { | 4286 | { |
| 4208 | return conf->channel_type == NL80211_CHAN_HT20; | 4287 | return conf->chandef.width == NL80211_CHAN_WIDTH_20; |
| 4209 | } | 4288 | } |
| 4210 | 4289 | ||
| 4211 | static inline bool | 4290 | static inline bool |
| 4212 | conf_is_ht40_minus(struct ieee80211_conf *conf) | 4291 | conf_is_ht40_minus(struct ieee80211_conf *conf) |
| 4213 | { | 4292 | { |
| 4214 | return conf->channel_type == NL80211_CHAN_HT40MINUS; | 4293 | return conf->chandef.width == NL80211_CHAN_WIDTH_40 && |
| 4294 | conf->chandef.center_freq1 < conf->chandef.chan->center_freq; | ||
| 4215 | } | 4295 | } |
| 4216 | 4296 | ||
| 4217 | static inline bool | 4297 | static inline bool |
| 4218 | conf_is_ht40_plus(struct ieee80211_conf *conf) | 4298 | conf_is_ht40_plus(struct ieee80211_conf *conf) |
| 4219 | { | 4299 | { |
| 4220 | return conf->channel_type == NL80211_CHAN_HT40PLUS; | 4300 | return conf->chandef.width == NL80211_CHAN_WIDTH_40 && |
| 4301 | conf->chandef.center_freq1 > conf->chandef.chan->center_freq; | ||
| 4221 | } | 4302 | } |
| 4222 | 4303 | ||
| 4223 | static inline bool | 4304 | static inline bool |
| 4224 | conf_is_ht40(struct ieee80211_conf *conf) | 4305 | conf_is_ht40(struct ieee80211_conf *conf) |
| 4225 | { | 4306 | { |
| 4226 | return conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf); | 4307 | return conf->chandef.width == NL80211_CHAN_WIDTH_40; |
| 4227 | } | 4308 | } |
| 4228 | 4309 | ||
| 4229 | static inline bool | 4310 | static inline bool |
| 4230 | conf_is_ht(struct ieee80211_conf *conf) | 4311 | conf_is_ht(struct ieee80211_conf *conf) |
| 4231 | { | 4312 | { |
| 4232 | return conf->channel_type != NL80211_CHAN_NO_HT; | 4313 | return conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT; |
| 4233 | } | 4314 | } |
| 4234 | 4315 | ||
| 4235 | static inline enum nl80211_iftype | 4316 | static inline enum nl80211_iftype |
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 87a6417fc934..5eb80bb3cbb2 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
| @@ -122,6 +122,8 @@ struct nfc_dev { | |||
| 122 | 122 | ||
| 123 | bool shutting_down; | 123 | bool shutting_down; |
| 124 | 124 | ||
| 125 | struct rfkill *rfkill; | ||
| 126 | |||
| 125 | struct nfc_ops *ops; | 127 | struct nfc_ops *ops; |
| 126 | }; | 128 | }; |
| 127 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) | 129 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) |
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h index 7440bc81a04b..7c6f627a717d 100644 --- a/include/uapi/linux/nfc.h +++ b/include/uapi/linux/nfc.h | |||
| @@ -233,7 +233,10 @@ struct sockaddr_nfc_llcp { | |||
| 233 | #define NFC_LLCP_DIRECTION_TX 0x01 | 233 | #define NFC_LLCP_DIRECTION_TX 0x01 |
| 234 | 234 | ||
| 235 | /* socket option names */ | 235 | /* socket option names */ |
| 236 | #define NFC_LLCP_RW 0 | 236 | #define NFC_LLCP_RW 0 |
| 237 | #define NFC_LLCP_MIUX 1 | 237 | #define NFC_LLCP_MIUX 1 |
| 238 | #define NFC_LLCP_REMOTE_MIU 2 | ||
| 239 | #define NFC_LLCP_REMOTE_LTO 3 | ||
| 240 | #define NFC_LLCP_REMOTE_RW 4 | ||
| 238 | 241 | ||
| 239 | #endif /*__LINUX_NFC_H */ | 242 | #endif /*__LINUX_NFC_H */ |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 79da8710448e..d1e48b5e348f 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
| @@ -639,6 +639,13 @@ | |||
| 639 | * with the relevant Information Elements. This event is used to report | 639 | * with the relevant Information Elements. This event is used to report |
| 640 | * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE). | 640 | * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE). |
| 641 | * | 641 | * |
| 642 | * @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running | ||
| 643 | * a critical protocol that needs more reliability in the connection to | ||
| 644 | * complete. | ||
| 645 | * | ||
| 646 | * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can | ||
| 647 | * return back to normal. | ||
| 648 | * | ||
| 642 | * @NL80211_CMD_MAX: highest used command number | 649 | * @NL80211_CMD_MAX: highest used command number |
| 643 | * @__NL80211_CMD_AFTER_LAST: internal use | 650 | * @__NL80211_CMD_AFTER_LAST: internal use |
| 644 | */ | 651 | */ |
| @@ -798,6 +805,9 @@ enum nl80211_commands { | |||
| 798 | NL80211_CMD_UPDATE_FT_IES, | 805 | NL80211_CMD_UPDATE_FT_IES, |
| 799 | NL80211_CMD_FT_EVENT, | 806 | NL80211_CMD_FT_EVENT, |
| 800 | 807 | ||
| 808 | NL80211_CMD_CRIT_PROTOCOL_START, | ||
| 809 | NL80211_CMD_CRIT_PROTOCOL_STOP, | ||
| 810 | |||
| 801 | /* add new commands above here */ | 811 | /* add new commands above here */ |
| 802 | 812 | ||
| 803 | /* used to define NL80211_CMD_MAX below */ | 813 | /* used to define NL80211_CMD_MAX below */ |
| @@ -1414,6 +1424,11 @@ enum nl80211_commands { | |||
| 1414 | * @NL80211_ATTR_IE_RIC: Resource Information Container Information | 1424 | * @NL80211_ATTR_IE_RIC: Resource Information Container Information |
| 1415 | * Element | 1425 | * Element |
| 1416 | * | 1426 | * |
| 1427 | * @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased | ||
| 1428 | * reliability, see &enum nl80211_crit_proto_id (u16). | ||
| 1429 | * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which | ||
| 1430 | * the connection should have increased reliability (u16). | ||
| 1431 | * | ||
| 1417 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1432 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 1418 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1433 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| 1419 | */ | 1434 | */ |
| @@ -1709,6 +1724,9 @@ enum nl80211_attrs { | |||
| 1709 | NL80211_ATTR_MDID, | 1724 | NL80211_ATTR_MDID, |
| 1710 | NL80211_ATTR_IE_RIC, | 1725 | NL80211_ATTR_IE_RIC, |
| 1711 | 1726 | ||
| 1727 | NL80211_ATTR_CRIT_PROT_ID, | ||
| 1728 | NL80211_ATTR_MAX_CRIT_PROT_DURATION, | ||
| 1729 | |||
| 1712 | /* add attributes here, update the policy in nl80211.c */ | 1730 | /* add attributes here, update the policy in nl80211.c */ |
| 1713 | 1731 | ||
| 1714 | __NL80211_ATTR_AFTER_LAST, | 1732 | __NL80211_ATTR_AFTER_LAST, |
| @@ -3682,4 +3700,25 @@ enum nl80211_protocol_features { | |||
| 3682 | NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0, | 3700 | NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0, |
| 3683 | }; | 3701 | }; |
| 3684 | 3702 | ||
| 3703 | /** | ||
| 3704 | * enum nl80211_crit_proto_id - nl80211 critical protocol identifiers | ||
| 3705 | * | ||
| 3706 | * @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified. | ||
| 3707 | * @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol. | ||
| 3708 | * @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol. | ||
| 3709 | * @NL80211_CRIT_PROTO_APIPA: APIPA protocol. | ||
| 3710 | * @NUM_NL80211_CRIT_PROTO: must be kept last. | ||
| 3711 | */ | ||
| 3712 | enum nl80211_crit_proto_id { | ||
| 3713 | NL80211_CRIT_PROTO_UNSPEC, | ||
| 3714 | NL80211_CRIT_PROTO_DHCP, | ||
| 3715 | NL80211_CRIT_PROTO_EAPOL, | ||
| 3716 | NL80211_CRIT_PROTO_APIPA, | ||
| 3717 | /* add other protocols before this one */ | ||
| 3718 | NUM_NL80211_CRIT_PROTO | ||
| 3719 | }; | ||
| 3720 | |||
| 3721 | /* maximum duration for critical protocol measures */ | ||
| 3722 | #define NL80211_CRIT_PROTO_MAX_DURATION 5000 /* msec */ | ||
| 3723 | |||
| 3685 | #endif /* __LINUX_NL80211_H */ | 3724 | #endif /* __LINUX_NL80211_H */ |
diff --git a/include/uapi/linux/rfkill.h b/include/uapi/linux/rfkill.h index 2753c6cc9740..058757f7a733 100644 --- a/include/uapi/linux/rfkill.h +++ b/include/uapi/linux/rfkill.h | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device. | 37 | * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device. |
| 38 | * @RFKILL_TYPE_GPS: switch is on a GPS device. | 38 | * @RFKILL_TYPE_GPS: switch is on a GPS device. |
| 39 | * @RFKILL_TYPE_FM: switch is on a FM radio device. | 39 | * @RFKILL_TYPE_FM: switch is on a FM radio device. |
| 40 | * @RFKILL_TYPE_NFC: switch is on an NFC device. | ||
| 40 | * @NUM_RFKILL_TYPES: number of defined rfkill types | 41 | * @NUM_RFKILL_TYPES: number of defined rfkill types |
| 41 | */ | 42 | */ |
| 42 | enum rfkill_type { | 43 | enum rfkill_type { |
| @@ -48,6 +49,7 @@ enum rfkill_type { | |||
| 48 | RFKILL_TYPE_WWAN, | 49 | RFKILL_TYPE_WWAN, |
| 49 | RFKILL_TYPE_GPS, | 50 | RFKILL_TYPE_GPS, |
| 50 | RFKILL_TYPE_FM, | 51 | RFKILL_TYPE_FM, |
| 52 | RFKILL_TYPE_NFC, | ||
| 51 | NUM_RFKILL_TYPES, | 53 | NUM_RFKILL_TYPES, |
| 52 | }; | 54 | }; |
| 53 | 55 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b9f90169940b..6c7f36379722 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -117,6 +117,16 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) | |||
| 117 | hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); | 117 | hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static void hci_reject_sco(struct hci_conn *conn) | ||
| 121 | { | ||
| 122 | struct hci_cp_reject_sync_conn_req cp; | ||
| 123 | |||
| 124 | cp.reason = HCI_ERROR_REMOTE_USER_TERM; | ||
| 125 | bacpy(&cp.bdaddr, &conn->dst); | ||
| 126 | |||
| 127 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); | ||
| 128 | } | ||
| 129 | |||
| 120 | void hci_disconnect(struct hci_conn *conn, __u8 reason) | 130 | void hci_disconnect(struct hci_conn *conn, __u8 reason) |
| 121 | { | 131 | { |
| 122 | struct hci_cp_disconnect cp; | 132 | struct hci_cp_disconnect cp; |
| @@ -276,6 +286,8 @@ static void hci_conn_timeout(struct work_struct *work) | |||
| 276 | hci_acl_create_connection_cancel(conn); | 286 | hci_acl_create_connection_cancel(conn); |
| 277 | else if (conn->type == LE_LINK) | 287 | else if (conn->type == LE_LINK) |
| 278 | hci_le_create_connection_cancel(conn); | 288 | hci_le_create_connection_cancel(conn); |
| 289 | } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) { | ||
| 290 | hci_reject_sco(conn); | ||
| 279 | } | 291 | } |
| 280 | break; | 292 | break; |
| 281 | case BT_CONFIG: | 293 | case BT_CONFIG: |
| @@ -398,8 +410,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
| 398 | if (hdev->notify) | 410 | if (hdev->notify) |
| 399 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); | 411 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); |
| 400 | 412 | ||
| 401 | atomic_set(&conn->devref, 0); | ||
| 402 | |||
| 403 | hci_conn_init_sysfs(conn); | 413 | hci_conn_init_sysfs(conn); |
| 404 | 414 | ||
| 405 | return conn; | 415 | return conn; |
| @@ -433,7 +443,7 @@ int hci_conn_del(struct hci_conn *conn) | |||
| 433 | struct hci_conn *acl = conn->link; | 443 | struct hci_conn *acl = conn->link; |
| 434 | if (acl) { | 444 | if (acl) { |
| 435 | acl->link = NULL; | 445 | acl->link = NULL; |
| 436 | hci_conn_put(acl); | 446 | hci_conn_drop(acl); |
| 437 | } | 447 | } |
| 438 | } | 448 | } |
| 439 | 449 | ||
| @@ -448,12 +458,11 @@ int hci_conn_del(struct hci_conn *conn) | |||
| 448 | 458 | ||
| 449 | skb_queue_purge(&conn->data_q); | 459 | skb_queue_purge(&conn->data_q); |
| 450 | 460 | ||
| 451 | hci_conn_put_device(conn); | 461 | hci_conn_del_sysfs(conn); |
| 452 | 462 | ||
| 453 | hci_dev_put(hdev); | 463 | hci_dev_put(hdev); |
| 454 | 464 | ||
| 455 | if (conn->handle == 0) | 465 | hci_conn_put(conn); |
| 456 | kfree(conn); | ||
| 457 | 466 | ||
| 458 | return 0; | 467 | return 0; |
| 459 | } | 468 | } |
| @@ -565,7 +574,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, | |||
| 565 | if (!sco) { | 574 | if (!sco) { |
| 566 | sco = hci_conn_add(hdev, type, dst); | 575 | sco = hci_conn_add(hdev, type, dst); |
| 567 | if (!sco) { | 576 | if (!sco) { |
| 568 | hci_conn_put(acl); | 577 | hci_conn_drop(acl); |
| 569 | return ERR_PTR(-ENOMEM); | 578 | return ERR_PTR(-ENOMEM); |
| 570 | } | 579 | } |
| 571 | } | 580 | } |
| @@ -835,19 +844,6 @@ void hci_conn_check_pending(struct hci_dev *hdev) | |||
| 835 | hci_dev_unlock(hdev); | 844 | hci_dev_unlock(hdev); |
| 836 | } | 845 | } |
| 837 | 846 | ||
| 838 | void hci_conn_hold_device(struct hci_conn *conn) | ||
| 839 | { | ||
| 840 | atomic_inc(&conn->devref); | ||
| 841 | } | ||
| 842 | EXPORT_SYMBOL(hci_conn_hold_device); | ||
| 843 | |||
| 844 | void hci_conn_put_device(struct hci_conn *conn) | ||
| 845 | { | ||
| 846 | if (atomic_dec_and_test(&conn->devref)) | ||
| 847 | hci_conn_del_sysfs(conn); | ||
| 848 | } | ||
| 849 | EXPORT_SYMBOL(hci_conn_put_device); | ||
| 850 | |||
| 851 | int hci_get_conn_list(void __user *arg) | 847 | int hci_get_conn_list(void __user *arg) |
| 852 | { | 848 | { |
| 853 | struct hci_conn *c; | 849 | struct hci_conn *c; |
| @@ -980,7 +976,7 @@ void hci_chan_del(struct hci_chan *chan) | |||
| 980 | 976 | ||
| 981 | synchronize_rcu(); | 977 | synchronize_rcu(); |
| 982 | 978 | ||
| 983 | hci_conn_put(conn); | 979 | hci_conn_drop(conn); |
| 984 | 980 | ||
| 985 | skb_queue_purge(&chan->data_q); | 981 | skb_queue_purge(&chan->data_q); |
| 986 | kfree(chan); | 982 | kfree(chan); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cfcad5423f1c..ce82265f5619 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -79,6 +79,121 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) | |||
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 event) | ||
| 83 | { | ||
| 84 | struct hci_ev_cmd_complete *ev; | ||
| 85 | struct hci_event_hdr *hdr; | ||
| 86 | struct sk_buff *skb; | ||
| 87 | |||
| 88 | hci_dev_lock(hdev); | ||
| 89 | |||
| 90 | skb = hdev->recv_evt; | ||
| 91 | hdev->recv_evt = NULL; | ||
| 92 | |||
| 93 | hci_dev_unlock(hdev); | ||
| 94 | |||
| 95 | if (!skb) | ||
| 96 | return ERR_PTR(-ENODATA); | ||
| 97 | |||
| 98 | if (skb->len < sizeof(*hdr)) { | ||
| 99 | BT_ERR("Too short HCI event"); | ||
| 100 | goto failed; | ||
| 101 | } | ||
| 102 | |||
| 103 | hdr = (void *) skb->data; | ||
| 104 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | ||
| 105 | |||
| 106 | if (event) { | ||
| 107 | if (hdr->evt != event) | ||
| 108 | goto failed; | ||
| 109 | return skb; | ||
| 110 | } | ||
| 111 | |||
| 112 | if (hdr->evt != HCI_EV_CMD_COMPLETE) { | ||
| 113 | BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); | ||
| 114 | goto failed; | ||
| 115 | } | ||
| 116 | |||
| 117 | if (skb->len < sizeof(*ev)) { | ||
| 118 | BT_ERR("Too short cmd_complete event"); | ||
| 119 | goto failed; | ||
| 120 | } | ||
| 121 | |||
| 122 | ev = (void *) skb->data; | ||
| 123 | skb_pull(skb, sizeof(*ev)); | ||
| 124 | |||
| 125 | if (opcode == __le16_to_cpu(ev->opcode)) | ||
| 126 | return skb; | ||
| 127 | |||
| 128 | BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, | ||
| 129 | __le16_to_cpu(ev->opcode)); | ||
| 130 | |||
| 131 | failed: | ||
| 132 | kfree_skb(skb); | ||
| 133 | return ERR_PTR(-ENODATA); | ||
| 134 | } | ||
| 135 | |||
| 136 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | ||
| 137 | void *param, u8 event, u32 timeout) | ||
| 138 | { | ||
| 139 | DECLARE_WAITQUEUE(wait, current); | ||
| 140 | struct hci_request req; | ||
| 141 | int err = 0; | ||
| 142 | |||
| 143 | BT_DBG("%s", hdev->name); | ||
| 144 | |||
| 145 | hci_req_init(&req, hdev); | ||
| 146 | |||
| 147 | hci_req_add_ev(&req, opcode, plen, param, event); | ||
| 148 | |||
| 149 | hdev->req_status = HCI_REQ_PEND; | ||
| 150 | |||
| 151 | err = hci_req_run(&req, hci_req_sync_complete); | ||
| 152 | if (err < 0) | ||
| 153 | return ERR_PTR(err); | ||
| 154 | |||
| 155 | add_wait_queue(&hdev->req_wait_q, &wait); | ||
| 156 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 157 | |||
| 158 | schedule_timeout(timeout); | ||
| 159 | |||
| 160 | remove_wait_queue(&hdev->req_wait_q, &wait); | ||
| 161 | |||
| 162 | if (signal_pending(current)) | ||
| 163 | return ERR_PTR(-EINTR); | ||
| 164 | |||
| 165 | switch (hdev->req_status) { | ||
| 166 | case HCI_REQ_DONE: | ||
| 167 | err = -bt_to_errno(hdev->req_result); | ||
| 168 | break; | ||
| 169 | |||
| 170 | case HCI_REQ_CANCELED: | ||
| 171 | err = -hdev->req_result; | ||
| 172 | break; | ||
| 173 | |||
| 174 | default: | ||
| 175 | err = -ETIMEDOUT; | ||
| 176 | break; | ||
| 177 | } | ||
| 178 | |||
| 179 | hdev->req_status = hdev->req_result = 0; | ||
| 180 | |||
| 181 | BT_DBG("%s end: err %d", hdev->name, err); | ||
| 182 | |||
| 183 | if (err < 0) | ||
| 184 | return ERR_PTR(err); | ||
| 185 | |||
| 186 | return hci_get_cmd_complete(hdev, opcode, event); | ||
| 187 | } | ||
| 188 | EXPORT_SYMBOL(__hci_cmd_sync_ev); | ||
| 189 | |||
| 190 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | ||
| 191 | void *param, u32 timeout) | ||
| 192 | { | ||
| 193 | return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); | ||
| 194 | } | ||
| 195 | EXPORT_SYMBOL(__hci_cmd_sync); | ||
| 196 | |||
| 82 | /* Execute request and wait for completion. */ | 197 | /* Execute request and wait for completion. */ |
| 83 | static int __hci_req_sync(struct hci_dev *hdev, | 198 | static int __hci_req_sync(struct hci_dev *hdev, |
| 84 | void (*func)(struct hci_request *req, | 199 | void (*func)(struct hci_request *req, |
| @@ -201,29 +316,9 @@ static void amp_init(struct hci_request *req) | |||
| 201 | static void hci_init1_req(struct hci_request *req, unsigned long opt) | 316 | static void hci_init1_req(struct hci_request *req, unsigned long opt) |
| 202 | { | 317 | { |
| 203 | struct hci_dev *hdev = req->hdev; | 318 | struct hci_dev *hdev = req->hdev; |
| 204 | struct hci_request init_req; | ||
| 205 | struct sk_buff *skb; | ||
| 206 | 319 | ||
| 207 | BT_DBG("%s %ld", hdev->name, opt); | 320 | BT_DBG("%s %ld", hdev->name, opt); |
| 208 | 321 | ||
| 209 | /* Driver initialization */ | ||
| 210 | |||
| 211 | hci_req_init(&init_req, hdev); | ||
| 212 | |||
| 213 | /* Special commands */ | ||
| 214 | while ((skb = skb_dequeue(&hdev->driver_init))) { | ||
| 215 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | ||
| 216 | skb->dev = (void *) hdev; | ||
| 217 | |||
| 218 | if (skb_queue_empty(&init_req.cmd_q)) | ||
| 219 | bt_cb(skb)->req.start = true; | ||
| 220 | |||
| 221 | skb_queue_tail(&init_req.cmd_q, skb); | ||
| 222 | } | ||
| 223 | skb_queue_purge(&hdev->driver_init); | ||
| 224 | |||
| 225 | hci_req_run(&init_req, NULL); | ||
| 226 | |||
| 227 | /* Reset */ | 322 | /* Reset */ |
| 228 | if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) | 323 | if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) |
| 229 | hci_reset_req(req, 0); | 324 | hci_reset_req(req, 0); |
| @@ -494,6 +589,7 @@ static void hci_set_le_support(struct hci_request *req) | |||
| 494 | static void hci_init3_req(struct hci_request *req, unsigned long opt) | 589 | static void hci_init3_req(struct hci_request *req, unsigned long opt) |
| 495 | { | 590 | { |
| 496 | struct hci_dev *hdev = req->hdev; | 591 | struct hci_dev *hdev = req->hdev; |
| 592 | u8 p; | ||
| 497 | 593 | ||
| 498 | if (hdev->commands[5] & 0x10) | 594 | if (hdev->commands[5] & 0x10) |
| 499 | hci_setup_link_policy(req); | 595 | hci_setup_link_policy(req); |
| @@ -502,6 +598,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
| 502 | hci_set_le_support(req); | 598 | hci_set_le_support(req); |
| 503 | hci_update_ad(req); | 599 | hci_update_ad(req); |
| 504 | } | 600 | } |
| 601 | |||
| 602 | /* Read features beyond page 1 if available */ | ||
| 603 | for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { | ||
| 604 | struct hci_cp_read_local_ext_features cp; | ||
| 605 | |||
| 606 | cp.page = p; | ||
| 607 | hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES, | ||
| 608 | sizeof(cp), &cp); | ||
| 609 | } | ||
| 505 | } | 610 | } |
| 506 | 611 | ||
| 507 | static int __hci_init(struct hci_dev *hdev) | 612 | static int __hci_init(struct hci_dev *hdev) |
| @@ -818,6 +923,12 @@ static void hci_inq_req(struct hci_request *req, unsigned long opt) | |||
| 818 | hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); | 923 | hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); |
| 819 | } | 924 | } |
| 820 | 925 | ||
| 926 | static int wait_inquiry(void *word) | ||
| 927 | { | ||
| 928 | schedule(); | ||
| 929 | return signal_pending(current); | ||
| 930 | } | ||
| 931 | |||
| 821 | int hci_inquiry(void __user *arg) | 932 | int hci_inquiry(void __user *arg) |
| 822 | { | 933 | { |
| 823 | __u8 __user *ptr = arg; | 934 | __u8 __user *ptr = arg; |
| @@ -849,6 +960,13 @@ int hci_inquiry(void __user *arg) | |||
| 849 | timeo); | 960 | timeo); |
| 850 | if (err < 0) | 961 | if (err < 0) |
| 851 | goto done; | 962 | goto done; |
| 963 | |||
| 964 | /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is | ||
| 965 | * cleared). If it is interrupted by a signal, return -EINTR. | ||
| 966 | */ | ||
| 967 | if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry, | ||
| 968 | TASK_INTERRUPTIBLE)) | ||
| 969 | return -EINTR; | ||
| 852 | } | 970 | } |
| 853 | 971 | ||
| 854 | /* for unlimited number of responses we will use buffer with | 972 | /* for unlimited number of responses we will use buffer with |
| @@ -999,26 +1117,33 @@ int hci_dev_open(__u16 dev) | |||
| 999 | goto done; | 1117 | goto done; |
| 1000 | } | 1118 | } |
| 1001 | 1119 | ||
| 1002 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) | ||
| 1003 | set_bit(HCI_RAW, &hdev->flags); | ||
| 1004 | |||
| 1005 | /* Treat all non BR/EDR controllers as raw devices if | ||
| 1006 | enable_hs is not set */ | ||
| 1007 | if (hdev->dev_type != HCI_BREDR && !enable_hs) | ||
| 1008 | set_bit(HCI_RAW, &hdev->flags); | ||
| 1009 | |||
| 1010 | if (hdev->open(hdev)) { | 1120 | if (hdev->open(hdev)) { |
| 1011 | ret = -EIO; | 1121 | ret = -EIO; |
| 1012 | goto done; | 1122 | goto done; |
| 1013 | } | 1123 | } |
| 1014 | 1124 | ||
| 1015 | if (!test_bit(HCI_RAW, &hdev->flags)) { | 1125 | atomic_set(&hdev->cmd_cnt, 1); |
| 1016 | atomic_set(&hdev->cmd_cnt, 1); | 1126 | set_bit(HCI_INIT, &hdev->flags); |
| 1017 | set_bit(HCI_INIT, &hdev->flags); | 1127 | |
| 1018 | ret = __hci_init(hdev); | 1128 | if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags)) |
| 1019 | clear_bit(HCI_INIT, &hdev->flags); | 1129 | ret = hdev->setup(hdev); |
| 1130 | |||
| 1131 | if (!ret) { | ||
| 1132 | /* Treat all non BR/EDR controllers as raw devices if | ||
| 1133 | * enable_hs is not set. | ||
| 1134 | */ | ||
| 1135 | if (hdev->dev_type != HCI_BREDR && !enable_hs) | ||
| 1136 | set_bit(HCI_RAW, &hdev->flags); | ||
| 1137 | |||
| 1138 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) | ||
| 1139 | set_bit(HCI_RAW, &hdev->flags); | ||
| 1140 | |||
| 1141 | if (!test_bit(HCI_RAW, &hdev->flags)) | ||
| 1142 | ret = __hci_init(hdev); | ||
| 1020 | } | 1143 | } |
| 1021 | 1144 | ||
| 1145 | clear_bit(HCI_INIT, &hdev->flags); | ||
| 1146 | |||
| 1022 | if (!ret) { | 1147 | if (!ret) { |
| 1023 | hci_dev_hold(hdev); | 1148 | hci_dev_hold(hdev); |
| 1024 | set_bit(HCI_UP, &hdev->flags); | 1149 | set_bit(HCI_UP, &hdev->flags); |
| @@ -1123,6 +1248,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
| 1123 | hdev->sent_cmd = NULL; | 1248 | hdev->sent_cmd = NULL; |
| 1124 | } | 1249 | } |
| 1125 | 1250 | ||
| 1251 | kfree_skb(hdev->recv_evt); | ||
| 1252 | hdev->recv_evt = NULL; | ||
| 1253 | |||
| 1126 | /* After this point our queues are empty | 1254 | /* After this point our queues are empty |
| 1127 | * and no tasks are scheduled. */ | 1255 | * and no tasks are scheduled. */ |
| 1128 | hdev->close(hdev); | 1256 | hdev->close(hdev); |
| @@ -1861,8 +1989,8 @@ static void le_scan_enable_req(struct hci_request *req, unsigned long opt) | |||
| 1861 | struct hci_cp_le_set_scan_enable cp; | 1989 | struct hci_cp_le_set_scan_enable cp; |
| 1862 | 1990 | ||
| 1863 | memset(&cp, 0, sizeof(cp)); | 1991 | memset(&cp, 0, sizeof(cp)); |
| 1864 | cp.enable = 1; | 1992 | cp.enable = LE_SCAN_ENABLE; |
| 1865 | cp.filter_dup = 1; | 1993 | cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; |
| 1866 | 1994 | ||
| 1867 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | 1995 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); |
| 1868 | } | 1996 | } |
| @@ -1896,7 +2024,7 @@ static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, | |||
| 1896 | return err; | 2024 | return err; |
| 1897 | 2025 | ||
| 1898 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | 2026 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, |
| 1899 | msecs_to_jiffies(timeout)); | 2027 | timeout); |
| 1900 | 2028 | ||
| 1901 | return 0; | 2029 | return 0; |
| 1902 | } | 2030 | } |
| @@ -2006,7 +2134,6 @@ struct hci_dev *hci_alloc_dev(void) | |||
| 2006 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | 2134 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); |
| 2007 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); | 2135 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); |
| 2008 | 2136 | ||
| 2009 | skb_queue_head_init(&hdev->driver_init); | ||
| 2010 | skb_queue_head_init(&hdev->rx_q); | 2137 | skb_queue_head_init(&hdev->rx_q); |
| 2011 | skb_queue_head_init(&hdev->cmd_q); | 2138 | skb_queue_head_init(&hdev->cmd_q); |
| 2012 | skb_queue_head_init(&hdev->raw_q); | 2139 | skb_queue_head_init(&hdev->raw_q); |
| @@ -2025,8 +2152,6 @@ EXPORT_SYMBOL(hci_alloc_dev); | |||
| 2025 | /* Free HCI device */ | 2152 | /* Free HCI device */ |
| 2026 | void hci_free_dev(struct hci_dev *hdev) | 2153 | void hci_free_dev(struct hci_dev *hdev) |
| 2027 | { | 2154 | { |
| 2028 | skb_queue_purge(&hdev->driver_init); | ||
| 2029 | |||
| 2030 | /* will free via device release */ | 2155 | /* will free via device release */ |
| 2031 | put_device(&hdev->dev); | 2156 | put_device(&hdev->dev); |
| 2032 | } | 2157 | } |
| @@ -2527,7 +2652,8 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
| 2527 | } | 2652 | } |
| 2528 | 2653 | ||
| 2529 | /* Queue a command to an asynchronous HCI request */ | 2654 | /* Queue a command to an asynchronous HCI request */ |
| 2530 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param) | 2655 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, |
| 2656 | u8 event) | ||
| 2531 | { | 2657 | { |
| 2532 | struct hci_dev *hdev = req->hdev; | 2658 | struct hci_dev *hdev = req->hdev; |
| 2533 | struct sk_buff *skb; | 2659 | struct sk_buff *skb; |
| @@ -2551,9 +2677,16 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param) | |||
| 2551 | if (skb_queue_empty(&req->cmd_q)) | 2677 | if (skb_queue_empty(&req->cmd_q)) |
| 2552 | bt_cb(skb)->req.start = true; | 2678 | bt_cb(skb)->req.start = true; |
| 2553 | 2679 | ||
| 2680 | bt_cb(skb)->req.event = event; | ||
| 2681 | |||
| 2554 | skb_queue_tail(&req->cmd_q, skb); | 2682 | skb_queue_tail(&req->cmd_q, skb); |
| 2555 | } | 2683 | } |
| 2556 | 2684 | ||
| 2685 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param) | ||
| 2686 | { | ||
| 2687 | hci_req_add_ev(req, opcode, plen, param, 0); | ||
| 2688 | } | ||
| 2689 | |||
| 2557 | /* Get data from the previously sent command */ | 2690 | /* Get data from the previously sent command */ |
| 2558 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) | 2691 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) |
| 2559 | { | 2692 | { |
| @@ -3309,32 +3442,6 @@ call_complete: | |||
| 3309 | req_complete(hdev, status); | 3442 | req_complete(hdev, status); |
| 3310 | } | 3443 | } |
| 3311 | 3444 | ||
| 3312 | void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status) | ||
| 3313 | { | ||
| 3314 | hci_req_complete_t req_complete = NULL; | ||
| 3315 | |||
| 3316 | BT_DBG("opcode 0x%04x status 0x%02x", opcode, status); | ||
| 3317 | |||
| 3318 | if (status) { | ||
| 3319 | hci_req_cmd_complete(hdev, opcode, status); | ||
| 3320 | return; | ||
| 3321 | } | ||
| 3322 | |||
| 3323 | /* No need to handle success status if there are more commands */ | ||
| 3324 | if (!hci_req_is_complete(hdev)) | ||
| 3325 | return; | ||
| 3326 | |||
| 3327 | if (hdev->sent_cmd) | ||
| 3328 | req_complete = bt_cb(hdev->sent_cmd)->req.complete; | ||
| 3329 | |||
| 3330 | /* If the request doesn't have a complete callback or there | ||
| 3331 | * are other commands/requests in the hdev queue we consider | ||
| 3332 | * this request as completed. | ||
| 3333 | */ | ||
| 3334 | if (!req_complete || !skb_queue_empty(&hdev->cmd_q)) | ||
| 3335 | hci_req_cmd_complete(hdev, opcode, status); | ||
| 3336 | } | ||
| 3337 | |||
| 3338 | static void hci_rx_work(struct work_struct *work) | 3445 | static void hci_rx_work(struct work_struct *work) |
| 3339 | { | 3446 | { |
| 3340 | struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); | 3447 | struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 138580745c2c..b93cd2eb5d58 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -48,13 +48,13 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | clear_bit(HCI_INQUIRY, &hdev->flags); | 50 | clear_bit(HCI_INQUIRY, &hdev->flags); |
| 51 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ | ||
| 52 | wake_up_bit(&hdev->flags, HCI_INQUIRY); | ||
| 51 | 53 | ||
| 52 | hci_dev_lock(hdev); | 54 | hci_dev_lock(hdev); |
| 53 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 55 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
| 54 | hci_dev_unlock(hdev); | 56 | hci_dev_unlock(hdev); |
| 55 | 57 | ||
| 56 | hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status); | ||
| 57 | |||
| 58 | hci_conn_check_pending(hdev); | 58 | hci_conn_check_pending(hdev); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| @@ -433,9 +433,9 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 433 | 433 | ||
| 434 | if (!status) { | 434 | if (!status) { |
| 435 | if (sent->mode) | 435 | if (sent->mode) |
| 436 | hdev->host_features[0] |= LMP_HOST_SSP; | 436 | hdev->features[1][0] |= LMP_HOST_SSP; |
| 437 | else | 437 | else |
| 438 | hdev->host_features[0] &= ~LMP_HOST_SSP; | 438 | hdev->features[1][0] &= ~LMP_HOST_SSP; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 441 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
| @@ -493,18 +493,18 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, | |||
| 493 | /* Adjust default settings according to features | 493 | /* Adjust default settings according to features |
| 494 | * supported by device. */ | 494 | * supported by device. */ |
| 495 | 495 | ||
| 496 | if (hdev->features[0] & LMP_3SLOT) | 496 | if (hdev->features[0][0] & LMP_3SLOT) |
| 497 | hdev->pkt_type |= (HCI_DM3 | HCI_DH3); | 497 | hdev->pkt_type |= (HCI_DM3 | HCI_DH3); |
| 498 | 498 | ||
| 499 | if (hdev->features[0] & LMP_5SLOT) | 499 | if (hdev->features[0][0] & LMP_5SLOT) |
| 500 | hdev->pkt_type |= (HCI_DM5 | HCI_DH5); | 500 | hdev->pkt_type |= (HCI_DM5 | HCI_DH5); |
| 501 | 501 | ||
| 502 | if (hdev->features[1] & LMP_HV2) { | 502 | if (hdev->features[0][1] & LMP_HV2) { |
| 503 | hdev->pkt_type |= (HCI_HV2); | 503 | hdev->pkt_type |= (HCI_HV2); |
| 504 | hdev->esco_type |= (ESCO_HV2); | 504 | hdev->esco_type |= (ESCO_HV2); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | if (hdev->features[1] & LMP_HV3) { | 507 | if (hdev->features[0][1] & LMP_HV3) { |
| 508 | hdev->pkt_type |= (HCI_HV3); | 508 | hdev->pkt_type |= (HCI_HV3); |
| 509 | hdev->esco_type |= (ESCO_HV3); | 509 | hdev->esco_type |= (ESCO_HV3); |
| 510 | } | 510 | } |
| @@ -512,26 +512,26 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, | |||
| 512 | if (lmp_esco_capable(hdev)) | 512 | if (lmp_esco_capable(hdev)) |
| 513 | hdev->esco_type |= (ESCO_EV3); | 513 | hdev->esco_type |= (ESCO_EV3); |
| 514 | 514 | ||
| 515 | if (hdev->features[4] & LMP_EV4) | 515 | if (hdev->features[0][4] & LMP_EV4) |
| 516 | hdev->esco_type |= (ESCO_EV4); | 516 | hdev->esco_type |= (ESCO_EV4); |
| 517 | 517 | ||
| 518 | if (hdev->features[4] & LMP_EV5) | 518 | if (hdev->features[0][4] & LMP_EV5) |
| 519 | hdev->esco_type |= (ESCO_EV5); | 519 | hdev->esco_type |= (ESCO_EV5); |
| 520 | 520 | ||
| 521 | if (hdev->features[5] & LMP_EDR_ESCO_2M) | 521 | if (hdev->features[0][5] & LMP_EDR_ESCO_2M) |
| 522 | hdev->esco_type |= (ESCO_2EV3); | 522 | hdev->esco_type |= (ESCO_2EV3); |
| 523 | 523 | ||
| 524 | if (hdev->features[5] & LMP_EDR_ESCO_3M) | 524 | if (hdev->features[0][5] & LMP_EDR_ESCO_3M) |
| 525 | hdev->esco_type |= (ESCO_3EV3); | 525 | hdev->esco_type |= (ESCO_3EV3); |
| 526 | 526 | ||
| 527 | if (hdev->features[5] & LMP_EDR_3S_ESCO) | 527 | if (hdev->features[0][5] & LMP_EDR_3S_ESCO) |
| 528 | hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); | 528 | hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); |
| 529 | 529 | ||
| 530 | BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, | 530 | BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, |
| 531 | hdev->features[0], hdev->features[1], | 531 | hdev->features[0][0], hdev->features[0][1], |
| 532 | hdev->features[2], hdev->features[3], | 532 | hdev->features[0][2], hdev->features[0][3], |
| 533 | hdev->features[4], hdev->features[5], | 533 | hdev->features[0][4], hdev->features[0][5], |
| 534 | hdev->features[6], hdev->features[7]); | 534 | hdev->features[0][6], hdev->features[0][7]); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | 537 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, |
| @@ -544,14 +544,10 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
| 544 | if (rp->status) | 544 | if (rp->status) |
| 545 | return; | 545 | return; |
| 546 | 546 | ||
| 547 | switch (rp->page) { | 547 | hdev->max_page = rp->max_page; |
| 548 | case 0: | 548 | |
| 549 | memcpy(hdev->features, rp->features, 8); | 549 | if (rp->page < HCI_MAX_PAGES) |
| 550 | break; | 550 | memcpy(hdev->features[rp->page], rp->features, 8); |
| 551 | case 1: | ||
| 552 | memcpy(hdev->host_features, rp->features, 8); | ||
| 553 | break; | ||
| 554 | } | ||
| 555 | } | 551 | } |
| 556 | 552 | ||
| 557 | static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, | 553 | static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, |
| @@ -968,7 +964,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
| 968 | return; | 964 | return; |
| 969 | 965 | ||
| 970 | switch (cp->enable) { | 966 | switch (cp->enable) { |
| 971 | case LE_SCANNING_ENABLED: | 967 | case LE_SCAN_ENABLE: |
| 972 | if (status) { | 968 | if (status) { |
| 973 | hci_dev_lock(hdev); | 969 | hci_dev_lock(hdev); |
| 974 | mgmt_start_discovery_failed(hdev, status); | 970 | mgmt_start_discovery_failed(hdev, status); |
| @@ -983,7 +979,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
| 983 | hci_dev_unlock(hdev); | 979 | hci_dev_unlock(hdev); |
| 984 | break; | 980 | break; |
| 985 | 981 | ||
| 986 | case LE_SCANNING_DISABLED: | 982 | case LE_SCAN_DISABLE: |
| 987 | if (status) { | 983 | if (status) { |
| 988 | hci_dev_lock(hdev); | 984 | hci_dev_lock(hdev); |
| 989 | mgmt_stop_discovery_failed(hdev, status); | 985 | mgmt_stop_discovery_failed(hdev, status); |
| @@ -1046,14 +1042,14 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
| 1046 | 1042 | ||
| 1047 | if (!status) { | 1043 | if (!status) { |
| 1048 | if (sent->le) | 1044 | if (sent->le) |
| 1049 | hdev->host_features[0] |= LMP_HOST_LE; | 1045 | hdev->features[1][0] |= LMP_HOST_LE; |
| 1050 | else | 1046 | else |
| 1051 | hdev->host_features[0] &= ~LMP_HOST_LE; | 1047 | hdev->features[1][0] &= ~LMP_HOST_LE; |
| 1052 | 1048 | ||
| 1053 | if (sent->simul) | 1049 | if (sent->simul) |
| 1054 | hdev->host_features[0] |= LMP_HOST_LE_BREDR; | 1050 | hdev->features[1][0] |= LMP_HOST_LE_BREDR; |
| 1055 | else | 1051 | else |
| 1056 | hdev->host_features[0] &= ~LMP_HOST_LE_BREDR; | 1052 | hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; |
| 1057 | } | 1053 | } |
| 1058 | 1054 | ||
| 1059 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | 1055 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && |
| @@ -1190,7 +1186,7 @@ static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) | |||
| 1190 | if (conn) { | 1186 | if (conn) { |
| 1191 | if (conn->state == BT_CONFIG) { | 1187 | if (conn->state == BT_CONFIG) { |
| 1192 | hci_proto_connect_cfm(conn, status); | 1188 | hci_proto_connect_cfm(conn, status); |
| 1193 | hci_conn_put(conn); | 1189 | hci_conn_drop(conn); |
| 1194 | } | 1190 | } |
| 1195 | } | 1191 | } |
| 1196 | 1192 | ||
| @@ -1217,7 +1213,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) | |||
| 1217 | if (conn) { | 1213 | if (conn) { |
| 1218 | if (conn->state == BT_CONFIG) { | 1214 | if (conn->state == BT_CONFIG) { |
| 1219 | hci_proto_connect_cfm(conn, status); | 1215 | hci_proto_connect_cfm(conn, status); |
| 1220 | hci_conn_put(conn); | 1216 | hci_conn_drop(conn); |
| 1221 | } | 1217 | } |
| 1222 | } | 1218 | } |
| 1223 | 1219 | ||
| @@ -1379,7 +1375,7 @@ static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) | |||
| 1379 | if (conn) { | 1375 | if (conn) { |
| 1380 | if (conn->state == BT_CONFIG) { | 1376 | if (conn->state == BT_CONFIG) { |
| 1381 | hci_proto_connect_cfm(conn, status); | 1377 | hci_proto_connect_cfm(conn, status); |
| 1382 | hci_conn_put(conn); | 1378 | hci_conn_drop(conn); |
| 1383 | } | 1379 | } |
| 1384 | } | 1380 | } |
| 1385 | 1381 | ||
| @@ -1406,7 +1402,7 @@ static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) | |||
| 1406 | if (conn) { | 1402 | if (conn) { |
| 1407 | if (conn->state == BT_CONFIG) { | 1403 | if (conn->state == BT_CONFIG) { |
| 1408 | hci_proto_connect_cfm(conn, status); | 1404 | hci_proto_connect_cfm(conn, status); |
| 1409 | hci_conn_put(conn); | 1405 | hci_conn_drop(conn); |
| 1410 | } | 1406 | } |
| 1411 | } | 1407 | } |
| 1412 | 1408 | ||
| @@ -1600,13 +1596,14 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1600 | 1596 | ||
| 1601 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1597 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
| 1602 | 1598 | ||
| 1603 | hci_req_cmd_complete(hdev, HCI_OP_INQUIRY, status); | ||
| 1604 | |||
| 1605 | hci_conn_check_pending(hdev); | 1599 | hci_conn_check_pending(hdev); |
| 1606 | 1600 | ||
| 1607 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | 1601 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) |
| 1608 | return; | 1602 | return; |
| 1609 | 1603 | ||
| 1604 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ | ||
| 1605 | wake_up_bit(&hdev->flags, HCI_INQUIRY); | ||
| 1606 | |||
| 1610 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) | 1607 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) |
| 1611 | return; | 1608 | return; |
| 1612 | 1609 | ||
| @@ -1705,7 +1702,6 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1705 | } else | 1702 | } else |
| 1706 | conn->state = BT_CONNECTED; | 1703 | conn->state = BT_CONNECTED; |
| 1707 | 1704 | ||
| 1708 | hci_conn_hold_device(conn); | ||
| 1709 | hci_conn_add_sysfs(conn); | 1705 | hci_conn_add_sysfs(conn); |
| 1710 | 1706 | ||
| 1711 | if (test_bit(HCI_AUTH, &hdev->flags)) | 1707 | if (test_bit(HCI_AUTH, &hdev->flags)) |
| @@ -1752,42 +1748,6 @@ unlock: | |||
| 1752 | hci_conn_check_pending(hdev); | 1748 | hci_conn_check_pending(hdev); |
| 1753 | } | 1749 | } |
| 1754 | 1750 | ||
| 1755 | void hci_conn_accept(struct hci_conn *conn, int mask) | ||
| 1756 | { | ||
| 1757 | struct hci_dev *hdev = conn->hdev; | ||
| 1758 | |||
| 1759 | BT_DBG("conn %p", conn); | ||
| 1760 | |||
| 1761 | conn->state = BT_CONFIG; | ||
| 1762 | |||
| 1763 | if (!lmp_esco_capable(hdev)) { | ||
| 1764 | struct hci_cp_accept_conn_req cp; | ||
| 1765 | |||
| 1766 | bacpy(&cp.bdaddr, &conn->dst); | ||
| 1767 | |||
| 1768 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | ||
| 1769 | cp.role = 0x00; /* Become master */ | ||
| 1770 | else | ||
| 1771 | cp.role = 0x01; /* Remain slave */ | ||
| 1772 | |||
| 1773 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
| 1774 | } else /* lmp_esco_capable(hdev)) */ { | ||
| 1775 | struct hci_cp_accept_sync_conn_req cp; | ||
| 1776 | |||
| 1777 | bacpy(&cp.bdaddr, &conn->dst); | ||
| 1778 | cp.pkt_type = cpu_to_le16(conn->pkt_type); | ||
| 1779 | |||
| 1780 | cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
| 1781 | cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
| 1782 | cp.max_latency = __constant_cpu_to_le16(0xffff); | ||
| 1783 | cp.content_format = cpu_to_le16(hdev->voice_setting); | ||
| 1784 | cp.retrans_effort = 0xff; | ||
| 1785 | |||
| 1786 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, | ||
| 1787 | sizeof(cp), &cp); | ||
| 1788 | } | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1751 | static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 1792 | { | 1752 | { |
| 1793 | struct hci_ev_conn_request *ev = (void *) skb->data; | 1753 | struct hci_ev_conn_request *ev = (void *) skb->data; |
| @@ -1859,7 +1819,6 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1859 | } else { | 1819 | } else { |
| 1860 | conn->state = BT_CONNECT2; | 1820 | conn->state = BT_CONNECT2; |
| 1861 | hci_proto_connect_cfm(conn, 0); | 1821 | hci_proto_connect_cfm(conn, 0); |
| 1862 | hci_conn_put(conn); | ||
| 1863 | } | 1822 | } |
| 1864 | } else { | 1823 | } else { |
| 1865 | /* Connection rejected */ | 1824 | /* Connection rejected */ |
| @@ -1966,14 +1925,14 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1966 | } else { | 1925 | } else { |
| 1967 | conn->state = BT_CONNECTED; | 1926 | conn->state = BT_CONNECTED; |
| 1968 | hci_proto_connect_cfm(conn, ev->status); | 1927 | hci_proto_connect_cfm(conn, ev->status); |
| 1969 | hci_conn_put(conn); | 1928 | hci_conn_drop(conn); |
| 1970 | } | 1929 | } |
| 1971 | } else { | 1930 | } else { |
| 1972 | hci_auth_cfm(conn, ev->status); | 1931 | hci_auth_cfm(conn, ev->status); |
| 1973 | 1932 | ||
| 1974 | hci_conn_hold(conn); | 1933 | hci_conn_hold(conn); |
| 1975 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1934 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
| 1976 | hci_conn_put(conn); | 1935 | hci_conn_drop(conn); |
| 1977 | } | 1936 | } |
| 1978 | 1937 | ||
| 1979 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { | 1938 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { |
| @@ -2057,7 +2016,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2057 | 2016 | ||
| 2058 | if (ev->status && conn->state == BT_CONNECTED) { | 2017 | if (ev->status && conn->state == BT_CONNECTED) { |
| 2059 | hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); | 2018 | hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); |
| 2060 | hci_conn_put(conn); | 2019 | hci_conn_drop(conn); |
| 2061 | goto unlock; | 2020 | goto unlock; |
| 2062 | } | 2021 | } |
| 2063 | 2022 | ||
| @@ -2066,7 +2025,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2066 | conn->state = BT_CONNECTED; | 2025 | conn->state = BT_CONNECTED; |
| 2067 | 2026 | ||
| 2068 | hci_proto_connect_cfm(conn, ev->status); | 2027 | hci_proto_connect_cfm(conn, ev->status); |
| 2069 | hci_conn_put(conn); | 2028 | hci_conn_drop(conn); |
| 2070 | } else | 2029 | } else |
| 2071 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); | 2030 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); |
| 2072 | } | 2031 | } |
| @@ -2113,7 +2072,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, | |||
| 2113 | goto unlock; | 2072 | goto unlock; |
| 2114 | 2073 | ||
| 2115 | if (!ev->status) | 2074 | if (!ev->status) |
| 2116 | memcpy(conn->features, ev->features, 8); | 2075 | memcpy(conn->features[0], ev->features, 8); |
| 2117 | 2076 | ||
| 2118 | if (conn->state != BT_CONFIG) | 2077 | if (conn->state != BT_CONFIG) |
| 2119 | goto unlock; | 2078 | goto unlock; |
| @@ -2141,7 +2100,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, | |||
| 2141 | if (!hci_outgoing_auth_needed(hdev, conn)) { | 2100 | if (!hci_outgoing_auth_needed(hdev, conn)) { |
| 2142 | conn->state = BT_CONNECTED; | 2101 | conn->state = BT_CONNECTED; |
| 2143 | hci_proto_connect_cfm(conn, ev->status); | 2102 | hci_proto_connect_cfm(conn, ev->status); |
| 2144 | hci_conn_put(conn); | 2103 | hci_conn_drop(conn); |
| 2145 | } | 2104 | } |
| 2146 | 2105 | ||
| 2147 | unlock: | 2106 | unlock: |
| @@ -2462,7 +2421,9 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2462 | if (opcode != HCI_OP_NOP) | 2421 | if (opcode != HCI_OP_NOP) |
| 2463 | del_timer(&hdev->cmd_timer); | 2422 | del_timer(&hdev->cmd_timer); |
| 2464 | 2423 | ||
| 2465 | hci_req_cmd_status(hdev, opcode, ev->status); | 2424 | if (ev->status || |
| 2425 | (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) | ||
| 2426 | hci_req_cmd_complete(hdev, opcode, ev->status); | ||
| 2466 | 2427 | ||
| 2467 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { | 2428 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { |
| 2468 | atomic_set(&hdev->cmd_cnt, 1); | 2429 | atomic_set(&hdev->cmd_cnt, 1); |
| @@ -2679,7 +2640,7 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2679 | if (conn->state == BT_CONNECTED) { | 2640 | if (conn->state == BT_CONNECTED) { |
| 2680 | hci_conn_hold(conn); | 2641 | hci_conn_hold(conn); |
| 2681 | conn->disc_timeout = HCI_PAIRING_TIMEOUT; | 2642 | conn->disc_timeout = HCI_PAIRING_TIMEOUT; |
| 2682 | hci_conn_put(conn); | 2643 | hci_conn_drop(conn); |
| 2683 | } | 2644 | } |
| 2684 | 2645 | ||
| 2685 | if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) | 2646 | if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) |
| @@ -2782,7 +2743,7 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 2782 | if (ev->key_type != HCI_LK_CHANGED_COMBINATION) | 2743 | if (ev->key_type != HCI_LK_CHANGED_COMBINATION) |
| 2783 | conn->key_type = ev->key_type; | 2744 | conn->key_type = ev->key_type; |
| 2784 | 2745 | ||
| 2785 | hci_conn_put(conn); | 2746 | hci_conn_drop(conn); |
| 2786 | } | 2747 | } |
| 2787 | 2748 | ||
| 2788 | if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) | 2749 | if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) |
| @@ -2923,6 +2884,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, | |||
| 2923 | if (!conn) | 2884 | if (!conn) |
| 2924 | goto unlock; | 2885 | goto unlock; |
| 2925 | 2886 | ||
| 2887 | if (ev->page < HCI_MAX_PAGES) | ||
| 2888 | memcpy(conn->features[ev->page], ev->features, 8); | ||
| 2889 | |||
| 2926 | if (!ev->status && ev->page == 0x01) { | 2890 | if (!ev->status && ev->page == 0x01) { |
| 2927 | struct inquiry_entry *ie; | 2891 | struct inquiry_entry *ie; |
| 2928 | 2892 | ||
| @@ -2930,8 +2894,19 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, | |||
| 2930 | if (ie) | 2894 | if (ie) |
| 2931 | ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); | 2895 | ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); |
| 2932 | 2896 | ||
| 2933 | if (ev->features[0] & LMP_HOST_SSP) | 2897 | if (ev->features[0] & LMP_HOST_SSP) { |
| 2934 | set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); | 2898 | set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); |
| 2899 | } else { | ||
| 2900 | /* It is mandatory by the Bluetooth specification that | ||
| 2901 | * Extended Inquiry Results are only used when Secure | ||
| 2902 | * Simple Pairing is enabled, but some devices violate | ||
| 2903 | * this. | ||
| 2904 | * | ||
| 2905 | * To make these devices work, the internal SSP | ||
| 2906 | * enabled flag needs to be cleared if the remote host | ||
| 2907 | * features do not indicate SSP support */ | ||
| 2908 | clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); | ||
| 2909 | } | ||
| 2935 | } | 2910 | } |
| 2936 | 2911 | ||
| 2937 | if (conn->state != BT_CONFIG) | 2912 | if (conn->state != BT_CONFIG) |
| @@ -2951,7 +2926,7 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, | |||
| 2951 | if (!hci_outgoing_auth_needed(hdev, conn)) { | 2926 | if (!hci_outgoing_auth_needed(hdev, conn)) { |
| 2952 | conn->state = BT_CONNECTED; | 2927 | conn->state = BT_CONNECTED; |
| 2953 | hci_proto_connect_cfm(conn, ev->status); | 2928 | hci_proto_connect_cfm(conn, ev->status); |
| 2954 | hci_conn_put(conn); | 2929 | hci_conn_drop(conn); |
| 2955 | } | 2930 | } |
| 2956 | 2931 | ||
| 2957 | unlock: | 2932 | unlock: |
| @@ -2985,7 +2960,6 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, | |||
| 2985 | conn->handle = __le16_to_cpu(ev->handle); | 2960 | conn->handle = __le16_to_cpu(ev->handle); |
| 2986 | conn->state = BT_CONNECTED; | 2961 | conn->state = BT_CONNECTED; |
| 2987 | 2962 | ||
| 2988 | hci_conn_hold_device(conn); | ||
| 2989 | hci_conn_add_sysfs(conn); | 2963 | hci_conn_add_sysfs(conn); |
| 2990 | break; | 2964 | break; |
| 2991 | 2965 | ||
| @@ -3084,7 +3058,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | |||
| 3084 | 3058 | ||
| 3085 | if (ev->status && conn->state == BT_CONNECTED) { | 3059 | if (ev->status && conn->state == BT_CONNECTED) { |
| 3086 | hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); | 3060 | hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); |
| 3087 | hci_conn_put(conn); | 3061 | hci_conn_drop(conn); |
| 3088 | goto unlock; | 3062 | goto unlock; |
| 3089 | } | 3063 | } |
| 3090 | 3064 | ||
| @@ -3093,13 +3067,13 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | |||
| 3093 | conn->state = BT_CONNECTED; | 3067 | conn->state = BT_CONNECTED; |
| 3094 | 3068 | ||
| 3095 | hci_proto_connect_cfm(conn, ev->status); | 3069 | hci_proto_connect_cfm(conn, ev->status); |
| 3096 | hci_conn_put(conn); | 3070 | hci_conn_drop(conn); |
| 3097 | } else { | 3071 | } else { |
| 3098 | hci_auth_cfm(conn, ev->status); | 3072 | hci_auth_cfm(conn, ev->status); |
| 3099 | 3073 | ||
| 3100 | hci_conn_hold(conn); | 3074 | hci_conn_hold(conn); |
| 3101 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 3075 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
| 3102 | hci_conn_put(conn); | 3076 | hci_conn_drop(conn); |
| 3103 | } | 3077 | } |
| 3104 | 3078 | ||
| 3105 | unlock: | 3079 | unlock: |
| @@ -3360,7 +3334,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | |||
| 3360 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 3334 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, |
| 3361 | ev->status); | 3335 | ev->status); |
| 3362 | 3336 | ||
| 3363 | hci_conn_put(conn); | 3337 | hci_conn_drop(conn); |
| 3364 | 3338 | ||
| 3365 | unlock: | 3339 | unlock: |
| 3366 | hci_dev_unlock(hdev); | 3340 | hci_dev_unlock(hdev); |
| @@ -3371,11 +3345,16 @@ static void hci_remote_host_features_evt(struct hci_dev *hdev, | |||
| 3371 | { | 3345 | { |
| 3372 | struct hci_ev_remote_host_features *ev = (void *) skb->data; | 3346 | struct hci_ev_remote_host_features *ev = (void *) skb->data; |
| 3373 | struct inquiry_entry *ie; | 3347 | struct inquiry_entry *ie; |
| 3348 | struct hci_conn *conn; | ||
| 3374 | 3349 | ||
| 3375 | BT_DBG("%s", hdev->name); | 3350 | BT_DBG("%s", hdev->name); |
| 3376 | 3351 | ||
| 3377 | hci_dev_lock(hdev); | 3352 | hci_dev_lock(hdev); |
| 3378 | 3353 | ||
| 3354 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
| 3355 | if (conn) | ||
| 3356 | memcpy(conn->features[1], ev->features, 8); | ||
| 3357 | |||
| 3379 | ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); | 3358 | ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); |
| 3380 | if (ie) | 3359 | if (ie) |
| 3381 | ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); | 3360 | ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); |
| @@ -3448,9 +3427,8 @@ static void hci_phy_link_complete_evt(struct hci_dev *hdev, | |||
| 3448 | 3427 | ||
| 3449 | hci_conn_hold(hcon); | 3428 | hci_conn_hold(hcon); |
| 3450 | hcon->disc_timeout = HCI_DISCONN_TIMEOUT; | 3429 | hcon->disc_timeout = HCI_DISCONN_TIMEOUT; |
| 3451 | hci_conn_put(hcon); | 3430 | hci_conn_drop(hcon); |
| 3452 | 3431 | ||
| 3453 | hci_conn_hold_device(hcon); | ||
| 3454 | hci_conn_add_sysfs(hcon); | 3432 | hci_conn_add_sysfs(hcon); |
| 3455 | 3433 | ||
| 3456 | amp_physical_cfm(bredr_hcon, hcon); | 3434 | amp_physical_cfm(bredr_hcon, hcon); |
| @@ -3584,7 +3562,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 3584 | conn->handle = __le16_to_cpu(ev->handle); | 3562 | conn->handle = __le16_to_cpu(ev->handle); |
| 3585 | conn->state = BT_CONNECTED; | 3563 | conn->state = BT_CONNECTED; |
| 3586 | 3564 | ||
| 3587 | hci_conn_hold_device(conn); | ||
| 3588 | hci_conn_add_sysfs(conn); | 3565 | hci_conn_add_sysfs(conn); |
| 3589 | 3566 | ||
| 3590 | hci_proto_connect_cfm(conn, ev->status); | 3567 | hci_proto_connect_cfm(conn, ev->status); |
| @@ -3698,8 +3675,27 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 3698 | struct hci_event_hdr *hdr = (void *) skb->data; | 3675 | struct hci_event_hdr *hdr = (void *) skb->data; |
| 3699 | __u8 event = hdr->evt; | 3676 | __u8 event = hdr->evt; |
| 3700 | 3677 | ||
| 3678 | hci_dev_lock(hdev); | ||
| 3679 | |||
| 3680 | /* Received events are (currently) only needed when a request is | ||
| 3681 | * ongoing so avoid unnecessary memory allocation. | ||
| 3682 | */ | ||
| 3683 | if (hdev->req_status == HCI_REQ_PEND) { | ||
| 3684 | kfree_skb(hdev->recv_evt); | ||
| 3685 | hdev->recv_evt = skb_clone(skb, GFP_KERNEL); | ||
| 3686 | } | ||
| 3687 | |||
| 3688 | hci_dev_unlock(hdev); | ||
| 3689 | |||
| 3701 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | 3690 | skb_pull(skb, HCI_EVENT_HDR_SIZE); |
| 3702 | 3691 | ||
| 3692 | if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { | ||
| 3693 | struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data; | ||
| 3694 | u16 opcode = __le16_to_cpu(hdr->opcode); | ||
| 3695 | |||
| 3696 | hci_req_cmd_complete(hdev, opcode, 0); | ||
| 3697 | } | ||
| 3698 | |||
| 3703 | switch (event) { | 3699 | switch (event) { |
| 3704 | case HCI_EV_INQUIRY_COMPLETE: | 3700 | case HCI_EV_INQUIRY_COMPLETE: |
| 3705 | hci_inquiry_complete_evt(hdev, skb); | 3701 | hci_inquiry_complete_evt(hdev, skb); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index ff38561385de..7ad6ecf36f20 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
| @@ -48,10 +48,10 @@ static ssize_t show_link_features(struct device *dev, | |||
| 48 | struct hci_conn *conn = to_hci_conn(dev); | 48 | struct hci_conn *conn = to_hci_conn(dev); |
| 49 | 49 | ||
| 50 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 50 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
| 51 | conn->features[0], conn->features[1], | 51 | conn->features[0][0], conn->features[0][1], |
| 52 | conn->features[2], conn->features[3], | 52 | conn->features[0][2], conn->features[0][3], |
| 53 | conn->features[4], conn->features[5], | 53 | conn->features[0][4], conn->features[0][5], |
| 54 | conn->features[6], conn->features[7]); | 54 | conn->features[0][6], conn->features[0][7]); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | #define LINK_ATTR(_name, _mode, _show, _store) \ | 57 | #define LINK_ATTR(_name, _mode, _show, _store) \ |
| @@ -146,7 +146,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn) | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | device_del(&conn->dev); | 148 | device_del(&conn->dev); |
| 149 | put_device(&conn->dev); | ||
| 150 | 149 | ||
| 151 | hci_dev_put(hdev); | 150 | hci_dev_put(hdev); |
| 152 | } | 151 | } |
| @@ -234,10 +233,10 @@ static ssize_t show_features(struct device *dev, | |||
| 234 | struct hci_dev *hdev = to_hci_dev(dev); | 233 | struct hci_dev *hdev = to_hci_dev(dev); |
| 235 | 234 | ||
| 236 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 235 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
| 237 | hdev->features[0], hdev->features[1], | 236 | hdev->features[0][0], hdev->features[0][1], |
| 238 | hdev->features[2], hdev->features[3], | 237 | hdev->features[0][2], hdev->features[0][3], |
| 239 | hdev->features[4], hdev->features[5], | 238 | hdev->features[0][4], hdev->features[0][5], |
| 240 | hdev->features[6], hdev->features[7]); | 239 | hdev->features[0][6], hdev->features[0][7]); |
| 241 | } | 240 | } |
| 242 | 241 | ||
| 243 | static ssize_t show_manufacturer(struct device *dev, | 242 | static ssize_t show_manufacturer(struct device *dev, |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 2342327f3335..940f5acb6694 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | HIDP implementation for Linux Bluetooth stack (BlueZ). | 2 | HIDP implementation for Linux Bluetooth stack (BlueZ). |
| 3 | Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org> | 3 | Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org> |
| 4 | Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.com> | ||
| 4 | 5 | ||
| 5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License version 2 as | 7 | it under the terms of the GNU General Public License version 2 as |
| @@ -20,6 +21,7 @@ | |||
| 20 | SOFTWARE IS DISCLAIMED. | 21 | SOFTWARE IS DISCLAIMED. |
| 21 | */ | 22 | */ |
| 22 | 23 | ||
| 24 | #include <linux/kref.h> | ||
| 23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 24 | #include <linux/file.h> | 26 | #include <linux/file.h> |
| 25 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
| @@ -59,39 +61,20 @@ static unsigned char hidp_keycode[256] = { | |||
| 59 | 61 | ||
| 60 | static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; | 62 | static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; |
| 61 | 63 | ||
| 62 | static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) | 64 | static int hidp_session_probe(struct l2cap_conn *conn, |
| 63 | { | 65 | struct l2cap_user *user); |
| 64 | struct hidp_session *session; | 66 | static void hidp_session_remove(struct l2cap_conn *conn, |
| 65 | 67 | struct l2cap_user *user); | |
| 66 | BT_DBG(""); | 68 | static int hidp_session_thread(void *arg); |
| 69 | static void hidp_session_terminate(struct hidp_session *s); | ||
| 67 | 70 | ||
| 68 | list_for_each_entry(session, &hidp_session_list, list) { | 71 | static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) |
| 69 | if (!bacmp(bdaddr, &session->bdaddr)) | ||
| 70 | return session; | ||
| 71 | } | ||
| 72 | |||
| 73 | return NULL; | ||
| 74 | } | ||
| 75 | |||
| 76 | static void __hidp_link_session(struct hidp_session *session) | ||
| 77 | { | ||
| 78 | list_add(&session->list, &hidp_session_list); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void __hidp_unlink_session(struct hidp_session *session) | ||
| 82 | { | ||
| 83 | hci_conn_put_device(session->conn); | ||
| 84 | |||
| 85 | list_del(&session->list); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) | ||
| 89 | { | 72 | { |
| 90 | memset(ci, 0, sizeof(*ci)); | 73 | memset(ci, 0, sizeof(*ci)); |
| 91 | bacpy(&ci->bdaddr, &session->bdaddr); | 74 | bacpy(&ci->bdaddr, &session->bdaddr); |
| 92 | 75 | ||
| 93 | ci->flags = session->flags; | 76 | ci->flags = session->flags; |
| 94 | ci->state = session->state; | 77 | ci->state = BT_CONNECTED; |
| 95 | 78 | ||
| 96 | ci->vendor = 0x0000; | 79 | ci->vendor = 0x0000; |
| 97 | ci->product = 0x0000; | 80 | ci->product = 0x0000; |
| @@ -115,58 +98,80 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin | |||
| 115 | } | 98 | } |
| 116 | } | 99 | } |
| 117 | 100 | ||
| 118 | static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, | 101 | /* assemble skb, queue message on @transmit and wake up the session thread */ |
| 119 | unsigned int type, unsigned int code, int value) | 102 | static int hidp_send_message(struct hidp_session *session, struct socket *sock, |
| 103 | struct sk_buff_head *transmit, unsigned char hdr, | ||
| 104 | const unsigned char *data, int size) | ||
| 120 | { | 105 | { |
| 121 | unsigned char newleds; | ||
| 122 | struct sk_buff *skb; | 106 | struct sk_buff *skb; |
| 107 | struct sock *sk = sock->sk; | ||
| 123 | 108 | ||
| 124 | BT_DBG("session %p type %d code %d value %d", session, type, code, value); | 109 | BT_DBG("session %p data %p size %d", session, data, size); |
| 125 | |||
| 126 | if (type != EV_LED) | ||
| 127 | return -1; | ||
| 128 | |||
| 129 | newleds = (!!test_bit(LED_KANA, dev->led) << 3) | | ||
| 130 | (!!test_bit(LED_COMPOSE, dev->led) << 3) | | ||
| 131 | (!!test_bit(LED_SCROLLL, dev->led) << 2) | | ||
| 132 | (!!test_bit(LED_CAPSL, dev->led) << 1) | | ||
| 133 | (!!test_bit(LED_NUML, dev->led)); | ||
| 134 | |||
| 135 | if (session->leds == newleds) | ||
| 136 | return 0; | ||
| 137 | 110 | ||
| 138 | session->leds = newleds; | 111 | if (atomic_read(&session->terminate)) |
| 112 | return -EIO; | ||
| 139 | 113 | ||
| 140 | skb = alloc_skb(3, GFP_ATOMIC); | 114 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
| 141 | if (!skb) { | 115 | if (!skb) { |
| 142 | BT_ERR("Can't allocate memory for new frame"); | 116 | BT_ERR("Can't allocate memory for new frame"); |
| 143 | return -ENOMEM; | 117 | return -ENOMEM; |
| 144 | } | 118 | } |
| 145 | 119 | ||
| 146 | *skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | 120 | *skb_put(skb, 1) = hdr; |
| 147 | *skb_put(skb, 1) = 0x01; | 121 | if (data && size > 0) |
| 148 | *skb_put(skb, 1) = newleds; | 122 | memcpy(skb_put(skb, size), data, size); |
| 149 | |||
| 150 | skb_queue_tail(&session->intr_transmit, skb); | ||
| 151 | 123 | ||
| 152 | hidp_schedule(session); | 124 | skb_queue_tail(transmit, skb); |
| 125 | wake_up_interruptible(sk_sleep(sk)); | ||
| 153 | 126 | ||
| 154 | return 0; | 127 | return 0; |
| 155 | } | 128 | } |
| 156 | 129 | ||
| 157 | static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 130 | static int hidp_send_ctrl_message(struct hidp_session *session, |
| 131 | unsigned char hdr, const unsigned char *data, | ||
| 132 | int size) | ||
| 158 | { | 133 | { |
| 159 | struct hid_device *hid = input_get_drvdata(dev); | 134 | return hidp_send_message(session, session->ctrl_sock, |
| 160 | struct hidp_session *session = hid->driver_data; | 135 | &session->ctrl_transmit, hdr, data, size); |
| 136 | } | ||
| 161 | 137 | ||
| 162 | return hidp_queue_event(session, dev, type, code, value); | 138 | static int hidp_send_intr_message(struct hidp_session *session, |
| 139 | unsigned char hdr, const unsigned char *data, | ||
| 140 | int size) | ||
| 141 | { | ||
| 142 | return hidp_send_message(session, session->intr_sock, | ||
| 143 | &session->intr_transmit, hdr, data, size); | ||
| 163 | } | 144 | } |
| 164 | 145 | ||
| 165 | static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 146 | static int hidp_input_event(struct input_dev *dev, unsigned int type, |
| 147 | unsigned int code, int value) | ||
| 166 | { | 148 | { |
| 167 | struct hidp_session *session = input_get_drvdata(dev); | 149 | struct hidp_session *session = input_get_drvdata(dev); |
| 150 | unsigned char newleds; | ||
| 151 | unsigned char hdr, data[2]; | ||
| 152 | |||
| 153 | BT_DBG("session %p type %d code %d value %d", | ||
| 154 | session, type, code, value); | ||
| 155 | |||
| 156 | if (type != EV_LED) | ||
| 157 | return -1; | ||
| 158 | |||
| 159 | newleds = (!!test_bit(LED_KANA, dev->led) << 3) | | ||
| 160 | (!!test_bit(LED_COMPOSE, dev->led) << 3) | | ||
| 161 | (!!test_bit(LED_SCROLLL, dev->led) << 2) | | ||
| 162 | (!!test_bit(LED_CAPSL, dev->led) << 1) | | ||
| 163 | (!!test_bit(LED_NUML, dev->led)); | ||
| 168 | 164 | ||
| 169 | return hidp_queue_event(session, dev, type, code, value); | 165 | if (session->leds == newleds) |
| 166 | return 0; | ||
| 167 | |||
| 168 | session->leds = newleds; | ||
| 169 | |||
| 170 | hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | ||
| 171 | data[0] = 0x01; | ||
| 172 | data[1] = newleds; | ||
| 173 | |||
| 174 | return hidp_send_intr_message(session, hdr, data, 2); | ||
| 170 | } | 175 | } |
| 171 | 176 | ||
| 172 | static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) | 177 | static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) |
| @@ -224,71 +229,9 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) | |||
| 224 | input_sync(dev); | 229 | input_sync(dev); |
| 225 | } | 230 | } |
| 226 | 231 | ||
| 227 | static int __hidp_send_ctrl_message(struct hidp_session *session, | ||
| 228 | unsigned char hdr, unsigned char *data, | ||
| 229 | int size) | ||
| 230 | { | ||
| 231 | struct sk_buff *skb; | ||
| 232 | |||
| 233 | BT_DBG("session %p data %p size %d", session, data, size); | ||
| 234 | |||
| 235 | if (atomic_read(&session->terminate)) | ||
| 236 | return -EIO; | ||
| 237 | |||
| 238 | skb = alloc_skb(size + 1, GFP_ATOMIC); | ||
| 239 | if (!skb) { | ||
| 240 | BT_ERR("Can't allocate memory for new frame"); | ||
| 241 | return -ENOMEM; | ||
| 242 | } | ||
| 243 | |||
| 244 | *skb_put(skb, 1) = hdr; | ||
| 245 | if (data && size > 0) | ||
| 246 | memcpy(skb_put(skb, size), data, size); | ||
| 247 | |||
| 248 | skb_queue_tail(&session->ctrl_transmit, skb); | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int hidp_send_ctrl_message(struct hidp_session *session, | ||
| 254 | unsigned char hdr, unsigned char *data, int size) | ||
| 255 | { | ||
| 256 | int err; | ||
| 257 | |||
| 258 | err = __hidp_send_ctrl_message(session, hdr, data, size); | ||
| 259 | |||
| 260 | hidp_schedule(session); | ||
| 261 | |||
| 262 | return err; | ||
| 263 | } | ||
| 264 | |||
| 265 | static int hidp_queue_report(struct hidp_session *session, | ||
| 266 | unsigned char *data, int size) | ||
| 267 | { | ||
| 268 | struct sk_buff *skb; | ||
| 269 | |||
| 270 | BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size); | ||
| 271 | |||
| 272 | skb = alloc_skb(size + 1, GFP_ATOMIC); | ||
| 273 | if (!skb) { | ||
| 274 | BT_ERR("Can't allocate memory for new frame"); | ||
| 275 | return -ENOMEM; | ||
| 276 | } | ||
| 277 | |||
| 278 | *skb_put(skb, 1) = 0xa2; | ||
| 279 | if (size > 0) | ||
| 280 | memcpy(skb_put(skb, size), data, size); | ||
| 281 | |||
| 282 | skb_queue_tail(&session->intr_transmit, skb); | ||
| 283 | |||
| 284 | hidp_schedule(session); | ||
| 285 | |||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | static int hidp_send_report(struct hidp_session *session, struct hid_report *report) | 232 | static int hidp_send_report(struct hidp_session *session, struct hid_report *report) |
| 290 | { | 233 | { |
| 291 | unsigned char buf[32]; | 234 | unsigned char buf[32], hdr; |
| 292 | int rsize; | 235 | int rsize; |
| 293 | 236 | ||
| 294 | rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 237 | rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
| @@ -296,8 +239,9 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep | |||
| 296 | return -EIO; | 239 | return -EIO; |
| 297 | 240 | ||
| 298 | hid_output_report(report, buf); | 241 | hid_output_report(report, buf); |
| 242 | hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | ||
| 299 | 243 | ||
| 300 | return hidp_queue_report(session, buf, rsize); | 244 | return hidp_send_intr_message(session, hdr, buf, rsize); |
| 301 | } | 245 | } |
| 302 | 246 | ||
| 303 | static int hidp_get_raw_report(struct hid_device *hid, | 247 | static int hidp_get_raw_report(struct hid_device *hid, |
| @@ -336,17 +280,19 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
| 336 | session->waiting_report_number = numbered_reports ? report_number : -1; | 280 | session->waiting_report_number = numbered_reports ? report_number : -1; |
| 337 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | 281 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
| 338 | data[0] = report_number; | 282 | data[0] = report_number; |
| 339 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1); | 283 | ret = hidp_send_ctrl_message(session, report_type, data, 1); |
| 340 | if (ret) | 284 | if (ret) |
| 341 | goto err; | 285 | goto err; |
| 342 | 286 | ||
| 343 | /* Wait for the return of the report. The returned report | 287 | /* Wait for the return of the report. The returned report |
| 344 | gets put in session->report_return. */ | 288 | gets put in session->report_return. */ |
| 345 | while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) { | 289 | while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) && |
| 290 | !atomic_read(&session->terminate)) { | ||
| 346 | int res; | 291 | int res; |
| 347 | 292 | ||
| 348 | res = wait_event_interruptible_timeout(session->report_queue, | 293 | res = wait_event_interruptible_timeout(session->report_queue, |
| 349 | !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags), | 294 | !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) |
| 295 | || atomic_read(&session->terminate), | ||
| 350 | 5*HZ); | 296 | 5*HZ); |
| 351 | if (res == 0) { | 297 | if (res == 0) { |
| 352 | /* timeout */ | 298 | /* timeout */ |
| @@ -389,14 +335,11 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
| 389 | struct hidp_session *session = hid->driver_data; | 335 | struct hidp_session *session = hid->driver_data; |
| 390 | int ret; | 336 | int ret; |
| 391 | 337 | ||
| 392 | switch (report_type) { | 338 | if (report_type == HID_OUTPUT_REPORT) { |
| 393 | case HID_FEATURE_REPORT: | 339 | report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; |
| 394 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; | 340 | return hidp_send_intr_message(session, report_type, |
| 395 | break; | 341 | data, count); |
| 396 | case HID_OUTPUT_REPORT: | 342 | } else if (report_type != HID_FEATURE_REPORT) { |
| 397 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT; | ||
| 398 | break; | ||
| 399 | default: | ||
| 400 | return -EINVAL; | 343 | return -EINVAL; |
| 401 | } | 344 | } |
| 402 | 345 | ||
| @@ -405,17 +348,19 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
| 405 | 348 | ||
| 406 | /* Set up our wait, and send the report request to the device. */ | 349 | /* Set up our wait, and send the report request to the device. */ |
| 407 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | 350 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
| 408 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, | 351 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; |
| 409 | count); | 352 | ret = hidp_send_ctrl_message(session, report_type, data, count); |
| 410 | if (ret) | 353 | if (ret) |
| 411 | goto err; | 354 | goto err; |
| 412 | 355 | ||
| 413 | /* Wait for the ACK from the device. */ | 356 | /* Wait for the ACK from the device. */ |
| 414 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { | 357 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) && |
| 358 | !atomic_read(&session->terminate)) { | ||
| 415 | int res; | 359 | int res; |
| 416 | 360 | ||
| 417 | res = wait_event_interruptible_timeout(session->report_queue, | 361 | res = wait_event_interruptible_timeout(session->report_queue, |
| 418 | !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags), | 362 | !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) |
| 363 | || atomic_read(&session->terminate), | ||
| 419 | 10*HZ); | 364 | 10*HZ); |
| 420 | if (res == 0) { | 365 | if (res == 0) { |
| 421 | /* timeout */ | 366 | /* timeout */ |
| @@ -446,8 +391,7 @@ static void hidp_idle_timeout(unsigned long arg) | |||
| 446 | { | 391 | { |
| 447 | struct hidp_session *session = (struct hidp_session *) arg; | 392 | struct hidp_session *session = (struct hidp_session *) arg; |
| 448 | 393 | ||
| 449 | atomic_inc(&session->terminate); | 394 | hidp_session_terminate(session); |
| 450 | wake_up_process(session->task); | ||
| 451 | } | 395 | } |
| 452 | 396 | ||
| 453 | static void hidp_set_timer(struct hidp_session *session) | 397 | static void hidp_set_timer(struct hidp_session *session) |
| @@ -490,12 +434,12 @@ static void hidp_process_handshake(struct hidp_session *session, | |||
| 490 | case HIDP_HSHK_ERR_FATAL: | 434 | case HIDP_HSHK_ERR_FATAL: |
| 491 | /* Device requests a reboot, as this is the only way this error | 435 | /* Device requests a reboot, as this is the only way this error |
| 492 | * can be recovered. */ | 436 | * can be recovered. */ |
| 493 | __hidp_send_ctrl_message(session, | 437 | hidp_send_ctrl_message(session, |
| 494 | HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0); | 438 | HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0); |
| 495 | break; | 439 | break; |
| 496 | 440 | ||
| 497 | default: | 441 | default: |
| 498 | __hidp_send_ctrl_message(session, | 442 | hidp_send_ctrl_message(session, |
| 499 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); | 443 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); |
| 500 | break; | 444 | break; |
| 501 | } | 445 | } |
| @@ -515,8 +459,7 @@ static void hidp_process_hid_control(struct hidp_session *session, | |||
| 515 | skb_queue_purge(&session->ctrl_transmit); | 459 | skb_queue_purge(&session->ctrl_transmit); |
| 516 | skb_queue_purge(&session->intr_transmit); | 460 | skb_queue_purge(&session->intr_transmit); |
| 517 | 461 | ||
| 518 | atomic_inc(&session->terminate); | 462 | hidp_session_terminate(session); |
| 519 | wake_up_process(current); | ||
| 520 | } | 463 | } |
| 521 | } | 464 | } |
| 522 | 465 | ||
| @@ -544,7 +487,7 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, | |||
| 544 | break; | 487 | break; |
| 545 | 488 | ||
| 546 | default: | 489 | default: |
| 547 | __hidp_send_ctrl_message(session, | 490 | hidp_send_ctrl_message(session, |
| 548 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); | 491 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); |
| 549 | } | 492 | } |
| 550 | 493 | ||
| @@ -591,7 +534,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session, | |||
| 591 | break; | 534 | break; |
| 592 | 535 | ||
| 593 | default: | 536 | default: |
| 594 | __hidp_send_ctrl_message(session, | 537 | hidp_send_ctrl_message(session, |
| 595 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0); | 538 | HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0); |
| 596 | break; | 539 | break; |
| 597 | } | 540 | } |
| @@ -642,32 +585,24 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) | |||
| 642 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 585 | return kernel_sendmsg(sock, &msg, &iv, 1, len); |
| 643 | } | 586 | } |
| 644 | 587 | ||
| 645 | static void hidp_process_intr_transmit(struct hidp_session *session) | 588 | /* dequeue message from @transmit and send via @sock */ |
| 589 | static void hidp_process_transmit(struct hidp_session *session, | ||
| 590 | struct sk_buff_head *transmit, | ||
| 591 | struct socket *sock) | ||
| 646 | { | 592 | { |
| 647 | struct sk_buff *skb; | 593 | struct sk_buff *skb; |
| 594 | int ret; | ||
| 648 | 595 | ||
| 649 | BT_DBG("session %p", session); | 596 | BT_DBG("session %p", session); |
| 650 | 597 | ||
| 651 | while ((skb = skb_dequeue(&session->intr_transmit))) { | 598 | while ((skb = skb_dequeue(transmit))) { |
| 652 | if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) { | 599 | ret = hidp_send_frame(sock, skb->data, skb->len); |
| 653 | skb_queue_head(&session->intr_transmit, skb); | 600 | if (ret == -EAGAIN) { |
| 601 | skb_queue_head(transmit, skb); | ||
| 654 | break; | 602 | break; |
| 655 | } | 603 | } else if (ret < 0) { |
| 656 | 604 | hidp_session_terminate(session); | |
| 657 | hidp_set_timer(session); | 605 | kfree_skb(skb); |
| 658 | kfree_skb(skb); | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | static void hidp_process_ctrl_transmit(struct hidp_session *session) | ||
| 663 | { | ||
| 664 | struct sk_buff *skb; | ||
| 665 | |||
| 666 | BT_DBG("session %p", session); | ||
| 667 | |||
| 668 | while ((skb = skb_dequeue(&session->ctrl_transmit))) { | ||
| 669 | if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) { | ||
| 670 | skb_queue_head(&session->ctrl_transmit, skb); | ||
| 671 | break; | 606 | break; |
| 672 | } | 607 | } |
| 673 | 608 | ||
| @@ -676,122 +611,6 @@ static void hidp_process_ctrl_transmit(struct hidp_session *session) | |||
| 676 | } | 611 | } |
| 677 | } | 612 | } |
| 678 | 613 | ||
| 679 | static int hidp_session(void *arg) | ||
| 680 | { | ||
| 681 | struct hidp_session *session = arg; | ||
| 682 | struct sock *ctrl_sk = session->ctrl_sock->sk; | ||
| 683 | struct sock *intr_sk = session->intr_sock->sk; | ||
| 684 | struct sk_buff *skb; | ||
| 685 | wait_queue_t ctrl_wait, intr_wait; | ||
| 686 | |||
| 687 | BT_DBG("session %p", session); | ||
| 688 | |||
| 689 | __module_get(THIS_MODULE); | ||
| 690 | set_user_nice(current, -15); | ||
| 691 | |||
| 692 | init_waitqueue_entry(&ctrl_wait, current); | ||
| 693 | init_waitqueue_entry(&intr_wait, current); | ||
| 694 | add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); | ||
| 695 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); | ||
| 696 | session->waiting_for_startup = 0; | ||
| 697 | wake_up_interruptible(&session->startup_queue); | ||
| 698 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 699 | while (!atomic_read(&session->terminate)) { | ||
| 700 | if (ctrl_sk->sk_state != BT_CONNECTED || | ||
| 701 | intr_sk->sk_state != BT_CONNECTED) | ||
| 702 | break; | ||
| 703 | |||
| 704 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { | ||
| 705 | skb_orphan(skb); | ||
| 706 | if (!skb_linearize(skb)) | ||
| 707 | hidp_recv_intr_frame(session, skb); | ||
| 708 | else | ||
| 709 | kfree_skb(skb); | ||
| 710 | } | ||
| 711 | |||
| 712 | hidp_process_intr_transmit(session); | ||
| 713 | |||
| 714 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | ||
| 715 | skb_orphan(skb); | ||
| 716 | if (!skb_linearize(skb)) | ||
| 717 | hidp_recv_ctrl_frame(session, skb); | ||
| 718 | else | ||
| 719 | kfree_skb(skb); | ||
| 720 | } | ||
| 721 | |||
| 722 | hidp_process_ctrl_transmit(session); | ||
| 723 | |||
| 724 | schedule(); | ||
| 725 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 726 | } | ||
| 727 | set_current_state(TASK_RUNNING); | ||
| 728 | atomic_inc(&session->terminate); | ||
| 729 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | ||
| 730 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); | ||
| 731 | |||
| 732 | clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | ||
| 733 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
| 734 | wake_up_interruptible(&session->report_queue); | ||
| 735 | |||
| 736 | down_write(&hidp_session_sem); | ||
| 737 | |||
| 738 | hidp_del_timer(session); | ||
| 739 | |||
| 740 | if (session->input) { | ||
| 741 | input_unregister_device(session->input); | ||
| 742 | session->input = NULL; | ||
| 743 | } | ||
| 744 | |||
| 745 | if (session->hid) { | ||
| 746 | hid_destroy_device(session->hid); | ||
| 747 | session->hid = NULL; | ||
| 748 | } | ||
| 749 | |||
| 750 | /* Wakeup user-space polling for socket errors */ | ||
| 751 | session->intr_sock->sk->sk_err = EUNATCH; | ||
| 752 | session->ctrl_sock->sk->sk_err = EUNATCH; | ||
| 753 | |||
| 754 | hidp_schedule(session); | ||
| 755 | |||
| 756 | fput(session->intr_sock->file); | ||
| 757 | |||
| 758 | wait_event_timeout(*(sk_sleep(ctrl_sk)), | ||
| 759 | (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); | ||
| 760 | |||
| 761 | fput(session->ctrl_sock->file); | ||
| 762 | |||
| 763 | __hidp_unlink_session(session); | ||
| 764 | |||
| 765 | up_write(&hidp_session_sem); | ||
| 766 | |||
| 767 | kfree(session->rd_data); | ||
| 768 | kfree(session); | ||
| 769 | module_put_and_exit(0); | ||
| 770 | return 0; | ||
| 771 | } | ||
| 772 | |||
| 773 | static struct hci_conn *hidp_get_connection(struct hidp_session *session) | ||
| 774 | { | ||
| 775 | bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; | ||
| 776 | bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; | ||
| 777 | struct hci_conn *conn; | ||
| 778 | struct hci_dev *hdev; | ||
| 779 | |||
| 780 | hdev = hci_get_route(dst, src); | ||
| 781 | if (!hdev) | ||
| 782 | return NULL; | ||
| 783 | |||
| 784 | hci_dev_lock(hdev); | ||
| 785 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | ||
| 786 | if (conn) | ||
| 787 | hci_conn_hold_device(conn); | ||
| 788 | hci_dev_unlock(hdev); | ||
| 789 | |||
| 790 | hci_dev_put(hdev); | ||
| 791 | |||
| 792 | return conn; | ||
| 793 | } | ||
| 794 | |||
| 795 | static int hidp_setup_input(struct hidp_session *session, | 614 | static int hidp_setup_input(struct hidp_session *session, |
| 796 | struct hidp_connadd_req *req) | 615 | struct hidp_connadd_req *req) |
| 797 | { | 616 | { |
| @@ -839,7 +658,7 @@ static int hidp_setup_input(struct hidp_session *session, | |||
| 839 | input->relbit[0] |= BIT_MASK(REL_WHEEL); | 658 | input->relbit[0] |= BIT_MASK(REL_WHEEL); |
| 840 | } | 659 | } |
| 841 | 660 | ||
| 842 | input->dev.parent = &session->conn->dev; | 661 | input->dev.parent = &session->conn->hcon->dev; |
| 843 | 662 | ||
| 844 | input->event = hidp_input_event; | 663 | input->event = hidp_input_event; |
| 845 | 664 | ||
| @@ -898,7 +717,6 @@ static struct hid_ll_driver hidp_hid_driver = { | |||
| 898 | .stop = hidp_stop, | 717 | .stop = hidp_stop, |
| 899 | .open = hidp_open, | 718 | .open = hidp_open, |
| 900 | .close = hidp_close, | 719 | .close = hidp_close, |
| 901 | .hidinput_input_event = hidp_hidinput_event, | ||
| 902 | }; | 720 | }; |
| 903 | 721 | ||
| 904 | /* This function sets up the hid device. It does not add it | 722 | /* This function sets up the hid device. It does not add it |
| @@ -943,7 +761,7 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
| 943 | snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", | 761 | snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", |
| 944 | &bt_sk(session->ctrl_sock->sk)->dst); | 762 | &bt_sk(session->ctrl_sock->sk)->dst); |
| 945 | 763 | ||
| 946 | hid->dev.parent = &session->conn->dev; | 764 | hid->dev.parent = &session->conn->hcon->dev; |
| 947 | hid->ll_driver = &hidp_hid_driver; | 765 | hid->ll_driver = &hidp_hid_driver; |
| 948 | 766 | ||
| 949 | hid->hid_get_raw_report = hidp_get_raw_report; | 767 | hid->hid_get_raw_report = hidp_get_raw_report; |
| @@ -965,80 +783,217 @@ fault: | |||
| 965 | return err; | 783 | return err; |
| 966 | } | 784 | } |
| 967 | 785 | ||
| 968 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) | 786 | /* initialize session devices */ |
| 787 | static int hidp_session_dev_init(struct hidp_session *session, | ||
| 788 | struct hidp_connadd_req *req) | ||
| 969 | { | 789 | { |
| 970 | struct hidp_session *session, *s; | 790 | int ret; |
| 971 | int vendor, product; | ||
| 972 | int err; | ||
| 973 | 791 | ||
| 974 | BT_DBG(""); | 792 | if (req->rd_size > 0) { |
| 793 | ret = hidp_setup_hid(session, req); | ||
| 794 | if (ret && ret != -ENODEV) | ||
| 795 | return ret; | ||
| 796 | } | ||
| 975 | 797 | ||
| 976 | if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) || | 798 | if (!session->hid) { |
| 977 | bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) | 799 | ret = hidp_setup_input(session, req); |
| 978 | return -ENOTUNIQ; | 800 | if (ret < 0) |
| 801 | return ret; | ||
| 802 | } | ||
| 979 | 803 | ||
| 980 | BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); | 804 | return 0; |
| 805 | } | ||
| 981 | 806 | ||
| 982 | down_write(&hidp_session_sem); | 807 | /* destroy session devices */ |
| 808 | static void hidp_session_dev_destroy(struct hidp_session *session) | ||
| 809 | { | ||
| 810 | if (session->hid) | ||
| 811 | put_device(&session->hid->dev); | ||
| 812 | else if (session->input) | ||
| 813 | input_put_device(session->input); | ||
| 983 | 814 | ||
| 984 | s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); | 815 | kfree(session->rd_data); |
| 985 | if (s && s->state == BT_CONNECTED) { | 816 | session->rd_data = NULL; |
| 986 | up_write(&hidp_session_sem); | 817 | } |
| 987 | return -EEXIST; | ||
| 988 | } | ||
| 989 | 818 | ||
| 990 | session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); | 819 | /* add HID/input devices to their underlying bus systems */ |
| 991 | if (!session) { | 820 | static int hidp_session_dev_add(struct hidp_session *session) |
| 992 | up_write(&hidp_session_sem); | 821 | { |
| 993 | return -ENOMEM; | 822 | int ret; |
| 994 | } | ||
| 995 | 823 | ||
| 996 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); | 824 | /* Both HID and input systems drop a ref-count when unregistering the |
| 825 | * device but they don't take a ref-count when registering them. Work | ||
| 826 | * around this by explicitly taking a refcount during registration | ||
| 827 | * which is dropped automatically by unregistering the devices. */ | ||
| 997 | 828 | ||
| 998 | session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu, | 829 | if (session->hid) { |
| 999 | l2cap_pi(ctrl_sock->sk)->chan->imtu); | 830 | ret = hid_add_device(session->hid); |
| 1000 | session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu, | 831 | if (ret) |
| 1001 | l2cap_pi(intr_sock->sk)->chan->imtu); | 832 | return ret; |
| 833 | get_device(&session->hid->dev); | ||
| 834 | } else if (session->input) { | ||
| 835 | ret = input_register_device(session->input); | ||
| 836 | if (ret) | ||
| 837 | return ret; | ||
| 838 | input_get_device(session->input); | ||
| 839 | } | ||
| 1002 | 840 | ||
| 1003 | BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu); | 841 | return 0; |
| 842 | } | ||
| 1004 | 843 | ||
| 1005 | session->ctrl_sock = ctrl_sock; | 844 | /* remove HID/input devices from their bus systems */ |
| 1006 | session->intr_sock = intr_sock; | 845 | static void hidp_session_dev_del(struct hidp_session *session) |
| 1007 | session->state = BT_CONNECTED; | 846 | { |
| 847 | if (session->hid) | ||
| 848 | hid_destroy_device(session->hid); | ||
| 849 | else if (session->input) | ||
| 850 | input_unregister_device(session->input); | ||
| 851 | } | ||
| 1008 | 852 | ||
| 1009 | session->conn = hidp_get_connection(session); | 853 | /* |
| 1010 | if (!session->conn) { | 854 | * Create new session object |
| 1011 | err = -ENOTCONN; | 855 | * Allocate session object, initialize static fields, copy input data into the |
| 1012 | goto failed; | 856 | * object and take a reference to all sub-objects. |
| 1013 | } | 857 | * This returns 0 on success and puts a pointer to the new session object in |
| 858 | * \out. Otherwise, an error code is returned. | ||
| 859 | * The new session object has an initial ref-count of 1. | ||
| 860 | */ | ||
| 861 | static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, | ||
| 862 | struct socket *ctrl_sock, | ||
| 863 | struct socket *intr_sock, | ||
| 864 | struct hidp_connadd_req *req, | ||
| 865 | struct l2cap_conn *conn) | ||
| 866 | { | ||
| 867 | struct hidp_session *session; | ||
| 868 | int ret; | ||
| 869 | struct bt_sock *ctrl, *intr; | ||
| 870 | |||
| 871 | ctrl = bt_sk(ctrl_sock->sk); | ||
| 872 | intr = bt_sk(intr_sock->sk); | ||
| 1014 | 873 | ||
| 1015 | setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); | 874 | session = kzalloc(sizeof(*session), GFP_KERNEL); |
| 875 | if (!session) | ||
| 876 | return -ENOMEM; | ||
| 1016 | 877 | ||
| 878 | /* object and runtime management */ | ||
| 879 | kref_init(&session->ref); | ||
| 880 | atomic_set(&session->state, HIDP_SESSION_IDLING); | ||
| 881 | init_waitqueue_head(&session->state_queue); | ||
| 882 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); | ||
| 883 | |||
| 884 | /* connection management */ | ||
| 885 | bacpy(&session->bdaddr, bdaddr); | ||
| 886 | session->conn = conn; | ||
| 887 | session->user.probe = hidp_session_probe; | ||
| 888 | session->user.remove = hidp_session_remove; | ||
| 889 | session->ctrl_sock = ctrl_sock; | ||
| 890 | session->intr_sock = intr_sock; | ||
| 1017 | skb_queue_head_init(&session->ctrl_transmit); | 891 | skb_queue_head_init(&session->ctrl_transmit); |
| 1018 | skb_queue_head_init(&session->intr_transmit); | 892 | skb_queue_head_init(&session->intr_transmit); |
| 893 | session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl)->chan->omtu, | ||
| 894 | l2cap_pi(ctrl)->chan->imtu); | ||
| 895 | session->intr_mtu = min_t(uint, l2cap_pi(intr)->chan->omtu, | ||
| 896 | l2cap_pi(intr)->chan->imtu); | ||
| 897 | session->idle_to = req->idle_to; | ||
| 898 | |||
| 899 | /* device management */ | ||
| 900 | setup_timer(&session->timer, hidp_idle_timeout, | ||
| 901 | (unsigned long)session); | ||
| 1019 | 902 | ||
| 903 | /* session data */ | ||
| 1020 | mutex_init(&session->report_mutex); | 904 | mutex_init(&session->report_mutex); |
| 1021 | init_waitqueue_head(&session->report_queue); | 905 | init_waitqueue_head(&session->report_queue); |
| 1022 | init_waitqueue_head(&session->startup_queue); | ||
| 1023 | session->waiting_for_startup = 1; | ||
| 1024 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); | ||
| 1025 | session->idle_to = req->idle_to; | ||
| 1026 | 906 | ||
| 1027 | __hidp_link_session(session); | 907 | ret = hidp_session_dev_init(session, req); |
| 908 | if (ret) | ||
| 909 | goto err_free; | ||
| 1028 | 910 | ||
| 1029 | if (req->rd_size > 0) { | 911 | l2cap_conn_get(session->conn); |
| 1030 | err = hidp_setup_hid(session, req); | 912 | get_file(session->intr_sock->file); |
| 1031 | if (err && err != -ENODEV) | 913 | get_file(session->ctrl_sock->file); |
| 1032 | goto purge; | 914 | *out = session; |
| 1033 | } | 915 | return 0; |
| 1034 | 916 | ||
| 1035 | if (!session->hid) { | 917 | err_free: |
| 1036 | err = hidp_setup_input(session, req); | 918 | kfree(session); |
| 1037 | if (err < 0) | 919 | return ret; |
| 1038 | goto purge; | 920 | } |
| 921 | |||
| 922 | /* increase ref-count of the given session by one */ | ||
| 923 | static void hidp_session_get(struct hidp_session *session) | ||
| 924 | { | ||
| 925 | kref_get(&session->ref); | ||
| 926 | } | ||
| 927 | |||
| 928 | /* release callback */ | ||
| 929 | static void session_free(struct kref *ref) | ||
| 930 | { | ||
| 931 | struct hidp_session *session = container_of(ref, struct hidp_session, | ||
| 932 | ref); | ||
| 933 | |||
| 934 | hidp_session_dev_destroy(session); | ||
| 935 | skb_queue_purge(&session->ctrl_transmit); | ||
| 936 | skb_queue_purge(&session->intr_transmit); | ||
| 937 | fput(session->intr_sock->file); | ||
| 938 | fput(session->ctrl_sock->file); | ||
| 939 | l2cap_conn_put(session->conn); | ||
| 940 | kfree(session); | ||
| 941 | } | ||
| 942 | |||
| 943 | /* decrease ref-count of the given session by one */ | ||
| 944 | static void hidp_session_put(struct hidp_session *session) | ||
| 945 | { | ||
| 946 | kref_put(&session->ref, session_free); | ||
| 947 | } | ||
| 948 | |||
| 949 | /* | ||
| 950 | * Search the list of active sessions for a session with target address | ||
| 951 | * \bdaddr. You must hold at least a read-lock on \hidp_session_sem. As long as | ||
| 952 | * you do not release this lock, the session objects cannot vanish and you can | ||
| 953 | * safely take a reference to the session yourself. | ||
| 954 | */ | ||
| 955 | static struct hidp_session *__hidp_session_find(const bdaddr_t *bdaddr) | ||
| 956 | { | ||
| 957 | struct hidp_session *session; | ||
| 958 | |||
| 959 | list_for_each_entry(session, &hidp_session_list, list) { | ||
| 960 | if (!bacmp(bdaddr, &session->bdaddr)) | ||
| 961 | return session; | ||
| 1039 | } | 962 | } |
| 1040 | 963 | ||
| 1041 | hidp_set_timer(session); | 964 | return NULL; |
| 965 | } | ||
| 966 | |||
| 967 | /* | ||
| 968 | * Same as __hidp_session_find() but no locks must be held. This also takes a | ||
| 969 | * reference of the returned session (if non-NULL) so you must drop this | ||
| 970 | * reference if you no longer use the object. | ||
| 971 | */ | ||
| 972 | static struct hidp_session *hidp_session_find(const bdaddr_t *bdaddr) | ||
| 973 | { | ||
| 974 | struct hidp_session *session; | ||
| 975 | |||
| 976 | down_read(&hidp_session_sem); | ||
| 977 | |||
| 978 | session = __hidp_session_find(bdaddr); | ||
| 979 | if (session) | ||
| 980 | hidp_session_get(session); | ||
| 981 | |||
| 982 | up_read(&hidp_session_sem); | ||
| 983 | |||
| 984 | return session; | ||
| 985 | } | ||
| 986 | |||
| 987 | /* | ||
| 988 | * Start session synchronously | ||
| 989 | * This starts a session thread and waits until initialization | ||
| 990 | * is done or returns an error if it couldn't be started. | ||
| 991 | * If this returns 0 the session thread is up and running. You must call | ||
| 992 | * hipd_session_stop_sync() before deleting any runtime resources. | ||
| 993 | */ | ||
| 994 | static int hidp_session_start_sync(struct hidp_session *session) | ||
| 995 | { | ||
| 996 | unsigned int vendor, product; | ||
| 1042 | 997 | ||
| 1043 | if (session->hid) { | 998 | if (session->hid) { |
| 1044 | vendor = session->hid->vendor; | 999 | vendor = session->hid->vendor; |
| @@ -1051,98 +1006,320 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
| 1051 | product = 0x0000; | 1006 | product = 0x0000; |
| 1052 | } | 1007 | } |
| 1053 | 1008 | ||
| 1054 | session->task = kthread_run(hidp_session, session, "khidpd_%04x%04x", | 1009 | session->task = kthread_run(hidp_session_thread, session, |
| 1055 | vendor, product); | 1010 | "khidpd_%04x%04x", vendor, product); |
| 1056 | if (IS_ERR(session->task)) { | 1011 | if (IS_ERR(session->task)) |
| 1057 | err = PTR_ERR(session->task); | 1012 | return PTR_ERR(session->task); |
| 1058 | goto unlink; | ||
| 1059 | } | ||
| 1060 | 1013 | ||
| 1061 | while (session->waiting_for_startup) { | 1014 | while (atomic_read(&session->state) <= HIDP_SESSION_IDLING) |
| 1062 | wait_event_interruptible(session->startup_queue, | 1015 | wait_event(session->state_queue, |
| 1063 | !session->waiting_for_startup); | 1016 | atomic_read(&session->state) > HIDP_SESSION_IDLING); |
| 1064 | } | ||
| 1065 | 1017 | ||
| 1066 | if (session->hid) | 1018 | return 0; |
| 1067 | err = hid_add_device(session->hid); | 1019 | } |
| 1068 | else | ||
| 1069 | err = input_register_device(session->input); | ||
| 1070 | 1020 | ||
| 1071 | if (err < 0) { | 1021 | /* |
| 1072 | atomic_inc(&session->terminate); | 1022 | * Terminate session thread |
| 1073 | wake_up_process(session->task); | 1023 | * Wake up session thread and notify it to stop. This is asynchronous and |
| 1074 | up_write(&hidp_session_sem); | 1024 | * returns immediately. Call this whenever a runtime error occurs and you want |
| 1075 | return err; | 1025 | * the session to stop. |
| 1076 | } | 1026 | * Note: wake_up_process() performs any necessary memory-barriers for us. |
| 1027 | */ | ||
| 1028 | static void hidp_session_terminate(struct hidp_session *session) | ||
| 1029 | { | ||
| 1030 | atomic_inc(&session->terminate); | ||
| 1031 | wake_up_process(session->task); | ||
| 1032 | } | ||
| 1077 | 1033 | ||
| 1078 | if (session->input) { | 1034 | /* |
| 1079 | hidp_send_ctrl_message(session, | 1035 | * Probe HIDP session |
| 1080 | HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0); | 1036 | * This is called from the l2cap_conn core when our l2cap_user object is bound |
| 1081 | session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); | 1037 | * to the hci-connection. We get the session via the \user object and can now |
| 1038 | * start the session thread, register the HID/input devices and link it into | ||
| 1039 | * the global session list. | ||
| 1040 | * The global session-list owns its own reference to the session object so you | ||
| 1041 | * can drop your own reference after registering the l2cap_user object. | ||
| 1042 | */ | ||
| 1043 | static int hidp_session_probe(struct l2cap_conn *conn, | ||
| 1044 | struct l2cap_user *user) | ||
| 1045 | { | ||
| 1046 | struct hidp_session *session = container_of(user, | ||
| 1047 | struct hidp_session, | ||
| 1048 | user); | ||
| 1049 | struct hidp_session *s; | ||
| 1050 | int ret; | ||
| 1051 | |||
| 1052 | down_write(&hidp_session_sem); | ||
| 1082 | 1053 | ||
| 1083 | session->leds = 0xff; | 1054 | /* check that no other session for this device exists */ |
| 1084 | hidp_input_event(session->input, EV_LED, 0, 0); | 1055 | s = __hidp_session_find(&session->bdaddr); |
| 1056 | if (s) { | ||
| 1057 | ret = -EEXIST; | ||
| 1058 | goto out_unlock; | ||
| 1085 | } | 1059 | } |
| 1086 | 1060 | ||
| 1061 | ret = hidp_session_start_sync(session); | ||
| 1062 | if (ret) | ||
| 1063 | goto out_unlock; | ||
| 1064 | |||
| 1065 | ret = hidp_session_dev_add(session); | ||
| 1066 | if (ret) | ||
| 1067 | goto out_stop; | ||
| 1068 | |||
| 1069 | hidp_session_get(session); | ||
| 1070 | list_add(&session->list, &hidp_session_list); | ||
| 1071 | ret = 0; | ||
| 1072 | goto out_unlock; | ||
| 1073 | |||
| 1074 | out_stop: | ||
| 1075 | hidp_session_terminate(session); | ||
| 1076 | out_unlock: | ||
| 1087 | up_write(&hidp_session_sem); | 1077 | up_write(&hidp_session_sem); |
| 1088 | return 0; | 1078 | return ret; |
| 1079 | } | ||
| 1080 | |||
| 1081 | /* | ||
| 1082 | * Remove HIDP session | ||
| 1083 | * Called from the l2cap_conn core when either we explicitly unregistered | ||
| 1084 | * the l2cap_user object or if the underlying connection is shut down. | ||
| 1085 | * We signal the hidp-session thread to shut down, unregister the HID/input | ||
| 1086 | * devices and unlink the session from the global list. | ||
| 1087 | * This drops the reference to the session that is owned by the global | ||
| 1088 | * session-list. | ||
| 1089 | * Note: We _must_ not synchronosly wait for the session-thread to shut down. | ||
| 1090 | * This is, because the session-thread might be waiting for an HCI lock that is | ||
| 1091 | * held while we are called. Therefore, we only unregister the devices and | ||
| 1092 | * notify the session-thread to terminate. The thread itself owns a reference | ||
| 1093 | * to the session object so it can safely shut down. | ||
| 1094 | */ | ||
| 1095 | static void hidp_session_remove(struct l2cap_conn *conn, | ||
| 1096 | struct l2cap_user *user) | ||
| 1097 | { | ||
| 1098 | struct hidp_session *session = container_of(user, | ||
| 1099 | struct hidp_session, | ||
| 1100 | user); | ||
| 1101 | |||
| 1102 | down_write(&hidp_session_sem); | ||
| 1103 | |||
| 1104 | hidp_session_terminate(session); | ||
| 1105 | hidp_session_dev_del(session); | ||
| 1106 | list_del(&session->list); | ||
| 1107 | |||
| 1108 | up_write(&hidp_session_sem); | ||
| 1109 | |||
| 1110 | hidp_session_put(session); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /* | ||
| 1114 | * Session Worker | ||
| 1115 | * This performs the actual main-loop of the HIDP worker. We first check | ||
| 1116 | * whether the underlying connection is still alive, then parse all pending | ||
| 1117 | * messages and finally send all outstanding messages. | ||
| 1118 | */ | ||
| 1119 | static void hidp_session_run(struct hidp_session *session) | ||
| 1120 | { | ||
| 1121 | struct sock *ctrl_sk = session->ctrl_sock->sk; | ||
| 1122 | struct sock *intr_sk = session->intr_sock->sk; | ||
| 1123 | struct sk_buff *skb; | ||
| 1124 | |||
| 1125 | for (;;) { | ||
| 1126 | /* | ||
| 1127 | * This thread can be woken up two ways: | ||
| 1128 | * - You call hidp_session_terminate() which sets the | ||
| 1129 | * session->terminate flag and wakes this thread up. | ||
| 1130 | * - Via modifying the socket state of ctrl/intr_sock. This | ||
| 1131 | * thread is woken up by ->sk_state_changed(). | ||
| 1132 | * | ||
| 1133 | * Note: set_current_state() performs any necessary | ||
| 1134 | * memory-barriers for us. | ||
| 1135 | */ | ||
| 1136 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1137 | |||
| 1138 | if (atomic_read(&session->terminate)) | ||
| 1139 | break; | ||
| 1140 | |||
| 1141 | if (ctrl_sk->sk_state != BT_CONNECTED || | ||
| 1142 | intr_sk->sk_state != BT_CONNECTED) | ||
| 1143 | break; | ||
| 1144 | |||
| 1145 | /* parse incoming intr-skbs */ | ||
| 1146 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { | ||
| 1147 | skb_orphan(skb); | ||
| 1148 | if (!skb_linearize(skb)) | ||
| 1149 | hidp_recv_intr_frame(session, skb); | ||
| 1150 | else | ||
| 1151 | kfree_skb(skb); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /* send pending intr-skbs */ | ||
| 1155 | hidp_process_transmit(session, &session->intr_transmit, | ||
| 1156 | session->intr_sock); | ||
| 1089 | 1157 | ||
| 1090 | unlink: | 1158 | /* parse incoming ctrl-skbs */ |
| 1159 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | ||
| 1160 | skb_orphan(skb); | ||
| 1161 | if (!skb_linearize(skb)) | ||
| 1162 | hidp_recv_ctrl_frame(session, skb); | ||
| 1163 | else | ||
| 1164 | kfree_skb(skb); | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | /* send pending ctrl-skbs */ | ||
| 1168 | hidp_process_transmit(session, &session->ctrl_transmit, | ||
| 1169 | session->ctrl_sock); | ||
| 1170 | |||
| 1171 | schedule(); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | atomic_inc(&session->terminate); | ||
| 1175 | set_current_state(TASK_RUNNING); | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | /* | ||
| 1179 | * HIDP session thread | ||
| 1180 | * This thread runs the I/O for a single HIDP session. Startup is synchronous | ||
| 1181 | * which allows us to take references to ourself here instead of doing that in | ||
| 1182 | * the caller. | ||
| 1183 | * When we are ready to run we notify the caller and call hidp_session_run(). | ||
| 1184 | */ | ||
| 1185 | static int hidp_session_thread(void *arg) | ||
| 1186 | { | ||
| 1187 | struct hidp_session *session = arg; | ||
| 1188 | wait_queue_t ctrl_wait, intr_wait; | ||
| 1189 | |||
| 1190 | BT_DBG("session %p", session); | ||
| 1191 | |||
| 1192 | /* initialize runtime environment */ | ||
| 1193 | hidp_session_get(session); | ||
| 1194 | __module_get(THIS_MODULE); | ||
| 1195 | set_user_nice(current, -15); | ||
| 1196 | hidp_set_timer(session); | ||
| 1197 | |||
| 1198 | init_waitqueue_entry(&ctrl_wait, current); | ||
| 1199 | init_waitqueue_entry(&intr_wait, current); | ||
| 1200 | add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); | ||
| 1201 | add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); | ||
| 1202 | /* This memory barrier is paired with wq_has_sleeper(). See | ||
| 1203 | * sock_poll_wait() for more information why this is needed. */ | ||
| 1204 | smp_mb(); | ||
| 1205 | |||
| 1206 | /* notify synchronous startup that we're ready */ | ||
| 1207 | atomic_inc(&session->state); | ||
| 1208 | wake_up(&session->state_queue); | ||
| 1209 | |||
| 1210 | /* run session */ | ||
| 1211 | hidp_session_run(session); | ||
| 1212 | |||
| 1213 | /* cleanup runtime environment */ | ||
| 1214 | remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); | ||
| 1215 | remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait); | ||
| 1216 | wake_up_interruptible(&session->report_queue); | ||
| 1091 | hidp_del_timer(session); | 1217 | hidp_del_timer(session); |
| 1092 | 1218 | ||
| 1093 | if (session->input) { | 1219 | /* |
| 1094 | input_unregister_device(session->input); | 1220 | * If we stopped ourself due to any internal signal, we should try to |
| 1095 | session->input = NULL; | 1221 | * unregister our own session here to avoid having it linger until the |
| 1222 | * parent l2cap_conn dies or user-space cleans it up. | ||
| 1223 | * This does not deadlock as we don't do any synchronous shutdown. | ||
| 1224 | * Instead, this call has the same semantics as if user-space tried to | ||
| 1225 | * delete the session. | ||
| 1226 | */ | ||
| 1227 | l2cap_unregister_user(session->conn, &session->user); | ||
| 1228 | hidp_session_put(session); | ||
| 1229 | |||
| 1230 | module_put_and_exit(0); | ||
| 1231 | return 0; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | static int hidp_verify_sockets(struct socket *ctrl_sock, | ||
| 1235 | struct socket *intr_sock) | ||
| 1236 | { | ||
| 1237 | struct bt_sock *ctrl, *intr; | ||
| 1238 | struct hidp_session *session; | ||
| 1239 | |||
| 1240 | if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock)) | ||
| 1241 | return -EINVAL; | ||
| 1242 | |||
| 1243 | ctrl = bt_sk(ctrl_sock->sk); | ||
| 1244 | intr = bt_sk(intr_sock->sk); | ||
| 1245 | |||
| 1246 | if (bacmp(&ctrl->src, &intr->src) || bacmp(&ctrl->dst, &intr->dst)) | ||
| 1247 | return -ENOTUNIQ; | ||
| 1248 | if (ctrl->sk.sk_state != BT_CONNECTED || | ||
| 1249 | intr->sk.sk_state != BT_CONNECTED) | ||
| 1250 | return -EBADFD; | ||
| 1251 | |||
| 1252 | /* early session check, we check again during session registration */ | ||
| 1253 | session = hidp_session_find(&ctrl->dst); | ||
| 1254 | if (session) { | ||
| 1255 | hidp_session_put(session); | ||
| 1256 | return -EEXIST; | ||
| 1096 | } | 1257 | } |
| 1097 | 1258 | ||
| 1098 | if (session->hid) { | 1259 | return 0; |
| 1099 | hid_destroy_device(session->hid); | 1260 | } |
| 1100 | session->hid = NULL; | 1261 | |
| 1262 | int hidp_connection_add(struct hidp_connadd_req *req, | ||
| 1263 | struct socket *ctrl_sock, | ||
| 1264 | struct socket *intr_sock) | ||
| 1265 | { | ||
| 1266 | struct hidp_session *session; | ||
| 1267 | struct l2cap_conn *conn; | ||
| 1268 | struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan; | ||
| 1269 | int ret; | ||
| 1270 | |||
| 1271 | ret = hidp_verify_sockets(ctrl_sock, intr_sock); | ||
| 1272 | if (ret) | ||
| 1273 | return ret; | ||
| 1274 | |||
| 1275 | conn = NULL; | ||
| 1276 | l2cap_chan_lock(chan); | ||
| 1277 | if (chan->conn) { | ||
| 1278 | l2cap_conn_get(chan->conn); | ||
| 1279 | conn = chan->conn; | ||
| 1101 | } | 1280 | } |
| 1281 | l2cap_chan_unlock(chan); | ||
| 1102 | 1282 | ||
| 1103 | kfree(session->rd_data); | 1283 | if (!conn) |
| 1104 | session->rd_data = NULL; | 1284 | return -EBADFD; |
| 1105 | 1285 | ||
| 1106 | purge: | 1286 | ret = hidp_session_new(&session, &bt_sk(ctrl_sock->sk)->dst, ctrl_sock, |
| 1107 | __hidp_unlink_session(session); | 1287 | intr_sock, req, conn); |
| 1288 | if (ret) | ||
| 1289 | goto out_conn; | ||
| 1108 | 1290 | ||
| 1109 | skb_queue_purge(&session->ctrl_transmit); | 1291 | ret = l2cap_register_user(conn, &session->user); |
| 1110 | skb_queue_purge(&session->intr_transmit); | 1292 | if (ret) |
| 1293 | goto out_session; | ||
| 1111 | 1294 | ||
| 1112 | failed: | 1295 | ret = 0; |
| 1113 | up_write(&hidp_session_sem); | ||
| 1114 | 1296 | ||
| 1115 | kfree(session); | 1297 | out_session: |
| 1116 | return err; | 1298 | hidp_session_put(session); |
| 1299 | out_conn: | ||
| 1300 | l2cap_conn_put(conn); | ||
| 1301 | return ret; | ||
| 1117 | } | 1302 | } |
| 1118 | 1303 | ||
| 1119 | int hidp_del_connection(struct hidp_conndel_req *req) | 1304 | int hidp_connection_del(struct hidp_conndel_req *req) |
| 1120 | { | 1305 | { |
| 1121 | struct hidp_session *session; | 1306 | struct hidp_session *session; |
| 1122 | int err = 0; | ||
| 1123 | 1307 | ||
| 1124 | BT_DBG(""); | 1308 | session = hidp_session_find(&req->bdaddr); |
| 1309 | if (!session) | ||
| 1310 | return -ENOENT; | ||
| 1125 | 1311 | ||
| 1126 | down_read(&hidp_session_sem); | 1312 | if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) |
| 1313 | hidp_send_ctrl_message(session, | ||
| 1314 | HIDP_TRANS_HID_CONTROL | | ||
| 1315 | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, | ||
| 1316 | NULL, 0); | ||
| 1317 | else | ||
| 1318 | l2cap_unregister_user(session->conn, &session->user); | ||
| 1127 | 1319 | ||
| 1128 | session = __hidp_get_session(&req->bdaddr); | 1320 | hidp_session_put(session); |
| 1129 | if (session) { | ||
| 1130 | if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) { | ||
| 1131 | hidp_send_ctrl_message(session, | ||
| 1132 | HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0); | ||
| 1133 | } else { | ||
| 1134 | /* Flush the transmit queues */ | ||
| 1135 | skb_queue_purge(&session->ctrl_transmit); | ||
| 1136 | skb_queue_purge(&session->intr_transmit); | ||
| 1137 | |||
| 1138 | atomic_inc(&session->terminate); | ||
| 1139 | wake_up_process(session->task); | ||
| 1140 | } | ||
| 1141 | } else | ||
| 1142 | err = -ENOENT; | ||
| 1143 | 1321 | ||
| 1144 | up_read(&hidp_session_sem); | 1322 | return 0; |
| 1145 | return err; | ||
| 1146 | } | 1323 | } |
| 1147 | 1324 | ||
| 1148 | int hidp_get_connlist(struct hidp_connlist_req *req) | 1325 | int hidp_get_connlist(struct hidp_connlist_req *req) |
| @@ -1157,7 +1334,7 @@ int hidp_get_connlist(struct hidp_connlist_req *req) | |||
| 1157 | list_for_each_entry(session, &hidp_session_list, list) { | 1334 | list_for_each_entry(session, &hidp_session_list, list) { |
| 1158 | struct hidp_conninfo ci; | 1335 | struct hidp_conninfo ci; |
| 1159 | 1336 | ||
| 1160 | __hidp_copy_session(session, &ci); | 1337 | hidp_copy_session(session, &ci); |
| 1161 | 1338 | ||
| 1162 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 1339 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
| 1163 | err = -EFAULT; | 1340 | err = -EFAULT; |
| @@ -1178,18 +1355,14 @@ int hidp_get_connlist(struct hidp_connlist_req *req) | |||
| 1178 | int hidp_get_conninfo(struct hidp_conninfo *ci) | 1355 | int hidp_get_conninfo(struct hidp_conninfo *ci) |
| 1179 | { | 1356 | { |
| 1180 | struct hidp_session *session; | 1357 | struct hidp_session *session; |
| 1181 | int err = 0; | ||
| 1182 | |||
| 1183 | down_read(&hidp_session_sem); | ||
| 1184 | 1358 | ||
| 1185 | session = __hidp_get_session(&ci->bdaddr); | 1359 | session = hidp_session_find(&ci->bdaddr); |
| 1186 | if (session) | 1360 | if (session) { |
| 1187 | __hidp_copy_session(session, ci); | 1361 | hidp_copy_session(session, ci); |
| 1188 | else | 1362 | hidp_session_put(session); |
| 1189 | err = -ENOENT; | 1363 | } |
| 1190 | 1364 | ||
| 1191 | up_read(&hidp_session_sem); | 1365 | return session ? 0 : -ENOENT; |
| 1192 | return err; | ||
| 1193 | } | 1366 | } |
| 1194 | 1367 | ||
| 1195 | static int __init hidp_init(void) | 1368 | static int __init hidp_init(void) |
| @@ -1208,6 +1381,7 @@ module_init(hidp_init); | |||
| 1208 | module_exit(hidp_exit); | 1381 | module_exit(hidp_exit); |
| 1209 | 1382 | ||
| 1210 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 1383 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
| 1384 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); | ||
| 1211 | MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION); | 1385 | MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION); |
| 1212 | MODULE_VERSION(VERSION); | 1386 | MODULE_VERSION(VERSION); |
| 1213 | MODULE_LICENSE("GPL"); | 1387 | MODULE_LICENSE("GPL"); |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index af1bcc823f26..6162ce8606ac 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
| @@ -24,7 +24,9 @@ | |||
| 24 | #define __HIDP_H | 24 | #define __HIDP_H |
| 25 | 25 | ||
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/kref.h> | ||
| 27 | #include <net/bluetooth/bluetooth.h> | 28 | #include <net/bluetooth/bluetooth.h> |
| 29 | #include <net/bluetooth/l2cap.h> | ||
| 28 | 30 | ||
| 29 | /* HIDP header masks */ | 31 | /* HIDP header masks */ |
| 30 | #define HIDP_HEADER_TRANS_MASK 0xf0 | 32 | #define HIDP_HEADER_TRANS_MASK 0xf0 |
| @@ -119,43 +121,52 @@ struct hidp_connlist_req { | |||
| 119 | struct hidp_conninfo __user *ci; | 121 | struct hidp_conninfo __user *ci; |
| 120 | }; | 122 | }; |
| 121 | 123 | ||
| 122 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); | 124 | int hidp_connection_add(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); |
| 123 | int hidp_del_connection(struct hidp_conndel_req *req); | 125 | int hidp_connection_del(struct hidp_conndel_req *req); |
| 124 | int hidp_get_connlist(struct hidp_connlist_req *req); | 126 | int hidp_get_connlist(struct hidp_connlist_req *req); |
| 125 | int hidp_get_conninfo(struct hidp_conninfo *ci); | 127 | int hidp_get_conninfo(struct hidp_conninfo *ci); |
| 126 | 128 | ||
| 129 | enum hidp_session_state { | ||
| 130 | HIDP_SESSION_IDLING, | ||
| 131 | HIDP_SESSION_RUNNING, | ||
| 132 | }; | ||
| 133 | |||
| 127 | /* HIDP session defines */ | 134 | /* HIDP session defines */ |
| 128 | struct hidp_session { | 135 | struct hidp_session { |
| 129 | struct list_head list; | 136 | struct list_head list; |
| 137 | struct kref ref; | ||
| 130 | 138 | ||
| 131 | struct hci_conn *conn; | 139 | /* runtime management */ |
| 140 | atomic_t state; | ||
| 141 | wait_queue_head_t state_queue; | ||
| 142 | atomic_t terminate; | ||
| 143 | struct task_struct *task; | ||
| 144 | unsigned long flags; | ||
| 132 | 145 | ||
| 146 | /* connection management */ | ||
| 147 | bdaddr_t bdaddr; | ||
| 148 | struct l2cap_conn *conn; | ||
| 149 | struct l2cap_user user; | ||
| 133 | struct socket *ctrl_sock; | 150 | struct socket *ctrl_sock; |
| 134 | struct socket *intr_sock; | 151 | struct socket *intr_sock; |
| 135 | 152 | struct sk_buff_head ctrl_transmit; | |
| 136 | bdaddr_t bdaddr; | 153 | struct sk_buff_head intr_transmit; |
| 137 | |||
| 138 | unsigned long state; | ||
| 139 | unsigned long flags; | ||
| 140 | unsigned long idle_to; | ||
| 141 | |||
| 142 | uint ctrl_mtu; | 154 | uint ctrl_mtu; |
| 143 | uint intr_mtu; | 155 | uint intr_mtu; |
| 156 | unsigned long idle_to; | ||
| 144 | 157 | ||
| 145 | atomic_t terminate; | 158 | /* device management */ |
| 146 | struct task_struct *task; | ||
| 147 | |||
| 148 | unsigned char keys[8]; | ||
| 149 | unsigned char leds; | ||
| 150 | |||
| 151 | struct input_dev *input; | 159 | struct input_dev *input; |
| 152 | |||
| 153 | struct hid_device *hid; | 160 | struct hid_device *hid; |
| 154 | |||
| 155 | struct timer_list timer; | 161 | struct timer_list timer; |
| 156 | 162 | ||
| 157 | struct sk_buff_head ctrl_transmit; | 163 | /* Report descriptor */ |
| 158 | struct sk_buff_head intr_transmit; | 164 | __u8 *rd_data; |
| 165 | uint rd_size; | ||
| 166 | |||
| 167 | /* session data */ | ||
| 168 | unsigned char keys[8]; | ||
| 169 | unsigned char leds; | ||
| 159 | 170 | ||
| 160 | /* Used in hidp_get_raw_report() */ | 171 | /* Used in hidp_get_raw_report() */ |
| 161 | int waiting_report_type; /* HIDP_DATA_RTYPE_* */ | 172 | int waiting_report_type; /* HIDP_DATA_RTYPE_* */ |
| @@ -166,24 +177,8 @@ struct hidp_session { | |||
| 166 | 177 | ||
| 167 | /* Used in hidp_output_raw_report() */ | 178 | /* Used in hidp_output_raw_report() */ |
| 168 | int output_report_success; /* boolean */ | 179 | int output_report_success; /* boolean */ |
| 169 | |||
| 170 | /* Report descriptor */ | ||
| 171 | __u8 *rd_data; | ||
| 172 | uint rd_size; | ||
| 173 | |||
| 174 | wait_queue_head_t startup_queue; | ||
| 175 | int waiting_for_startup; | ||
| 176 | }; | 180 | }; |
| 177 | 181 | ||
| 178 | static inline void hidp_schedule(struct hidp_session *session) | ||
| 179 | { | ||
| 180 | struct sock *ctrl_sk = session->ctrl_sock->sk; | ||
| 181 | struct sock *intr_sk = session->intr_sock->sk; | ||
| 182 | |||
| 183 | wake_up_interruptible(sk_sleep(ctrl_sk)); | ||
| 184 | wake_up_interruptible(sk_sleep(intr_sk)); | ||
| 185 | } | ||
| 186 | |||
| 187 | /* HIDP init defines */ | 182 | /* HIDP init defines */ |
| 188 | extern int __init hidp_init_sockets(void); | 183 | extern int __init hidp_init_sockets(void); |
| 189 | extern void __exit hidp_cleanup_sockets(void); | 184 | extern void __exit hidp_cleanup_sockets(void); |
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 5d0f1ca0a314..2f4cbb0865ca 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c | |||
| @@ -77,21 +77,12 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
| 77 | return err; | 77 | return err; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | if (csock->sk->sk_state != BT_CONNECTED || | 80 | err = hidp_connection_add(&ca, csock, isock); |
| 81 | isock->sk->sk_state != BT_CONNECTED) { | 81 | if (!err && copy_to_user(argp, &ca, sizeof(ca))) |
| 82 | sockfd_put(csock); | 82 | err = -EFAULT; |
| 83 | sockfd_put(isock); | ||
| 84 | return -EBADFD; | ||
| 85 | } | ||
| 86 | 83 | ||
| 87 | err = hidp_add_connection(&ca, csock, isock); | 84 | sockfd_put(csock); |
| 88 | if (!err) { | 85 | sockfd_put(isock); |
| 89 | if (copy_to_user(argp, &ca, sizeof(ca))) | ||
| 90 | err = -EFAULT; | ||
| 91 | } else { | ||
| 92 | sockfd_put(csock); | ||
| 93 | sockfd_put(isock); | ||
| 94 | } | ||
| 95 | 86 | ||
| 96 | return err; | 87 | return err; |
| 97 | 88 | ||
| @@ -102,7 +93,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
| 102 | if (copy_from_user(&cd, argp, sizeof(cd))) | 93 | if (copy_from_user(&cd, argp, sizeof(cd))) |
| 103 | return -EFAULT; | 94 | return -EFAULT; |
| 104 | 95 | ||
| 105 | return hidp_del_connection(&cd); | 96 | return hidp_connection_del(&cd); |
| 106 | 97 | ||
| 107 | case HIDPGETCONNLIST: | 98 | case HIDPGETCONNLIST: |
| 108 | if (copy_from_user(&cl, argp, sizeof(cl))) | 99 | if (copy_from_user(&cl, argp, sizeof(cl))) |
| @@ -296,7 +287,6 @@ int __init hidp_init_sockets(void) | |||
| 296 | return 0; | 287 | return 0; |
| 297 | 288 | ||
| 298 | error: | 289 | error: |
| 299 | BT_ERR("Can't register HIDP socket"); | ||
| 300 | proto_unregister(&hidp_proto); | 290 | proto_unregister(&hidp_proto); |
| 301 | return err; | 291 | return err; |
| 302 | } | 292 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 7c7e9321f1ea..eae1d9f90b68 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -571,7 +571,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
| 571 | chan->conn = NULL; | 571 | chan->conn = NULL; |
| 572 | 572 | ||
| 573 | if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) | 573 | if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) |
| 574 | hci_conn_put(conn->hcon); | 574 | hci_conn_drop(conn->hcon); |
| 575 | 575 | ||
| 576 | if (mgr && mgr->bredr_chan == chan) | 576 | if (mgr && mgr->bredr_chan == chan) |
| 577 | mgr->bredr_chan = NULL; | 577 | mgr->bredr_chan = NULL; |
| @@ -1446,6 +1446,89 @@ static void l2cap_info_timeout(struct work_struct *work) | |||
| 1446 | l2cap_conn_start(conn); | 1446 | l2cap_conn_start(conn); |
| 1447 | } | 1447 | } |
| 1448 | 1448 | ||
| 1449 | /* | ||
| 1450 | * l2cap_user | ||
| 1451 | * External modules can register l2cap_user objects on l2cap_conn. The ->probe | ||
| 1452 | * callback is called during registration. The ->remove callback is called | ||
| 1453 | * during unregistration. | ||
| 1454 | * An l2cap_user object can either be explicitly unregistered or when the | ||
| 1455 | * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon, | ||
| 1456 | * l2cap->hchan, .. are valid as long as the remove callback hasn't been called. | ||
| 1457 | * External modules must own a reference to the l2cap_conn object if they intend | ||
| 1458 | * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at | ||
| 1459 | * any time if they don't. | ||
| 1460 | */ | ||
| 1461 | |||
| 1462 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user) | ||
| 1463 | { | ||
| 1464 | struct hci_dev *hdev = conn->hcon->hdev; | ||
| 1465 | int ret; | ||
| 1466 | |||
| 1467 | /* We need to check whether l2cap_conn is registered. If it is not, we | ||
| 1468 | * must not register the l2cap_user. l2cap_conn_del() is unregisters | ||
| 1469 | * l2cap_conn objects, but doesn't provide its own locking. Instead, it | ||
| 1470 | * relies on the parent hci_conn object to be locked. This itself relies | ||
| 1471 | * on the hci_dev object to be locked. So we must lock the hci device | ||
| 1472 | * here, too. */ | ||
| 1473 | |||
| 1474 | hci_dev_lock(hdev); | ||
| 1475 | |||
| 1476 | if (user->list.next || user->list.prev) { | ||
| 1477 | ret = -EINVAL; | ||
| 1478 | goto out_unlock; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | /* conn->hchan is NULL after l2cap_conn_del() was called */ | ||
| 1482 | if (!conn->hchan) { | ||
| 1483 | ret = -ENODEV; | ||
| 1484 | goto out_unlock; | ||
| 1485 | } | ||
| 1486 | |||
| 1487 | ret = user->probe(conn, user); | ||
| 1488 | if (ret) | ||
| 1489 | goto out_unlock; | ||
| 1490 | |||
| 1491 | list_add(&user->list, &conn->users); | ||
| 1492 | ret = 0; | ||
| 1493 | |||
| 1494 | out_unlock: | ||
| 1495 | hci_dev_unlock(hdev); | ||
| 1496 | return ret; | ||
| 1497 | } | ||
| 1498 | EXPORT_SYMBOL(l2cap_register_user); | ||
| 1499 | |||
| 1500 | void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user) | ||
| 1501 | { | ||
| 1502 | struct hci_dev *hdev = conn->hcon->hdev; | ||
| 1503 | |||
| 1504 | hci_dev_lock(hdev); | ||
| 1505 | |||
| 1506 | if (!user->list.next || !user->list.prev) | ||
| 1507 | goto out_unlock; | ||
| 1508 | |||
| 1509 | list_del(&user->list); | ||
| 1510 | user->list.next = NULL; | ||
| 1511 | user->list.prev = NULL; | ||
| 1512 | user->remove(conn, user); | ||
| 1513 | |||
| 1514 | out_unlock: | ||
| 1515 | hci_dev_unlock(hdev); | ||
| 1516 | } | ||
| 1517 | EXPORT_SYMBOL(l2cap_unregister_user); | ||
| 1518 | |||
| 1519 | static void l2cap_unregister_all_users(struct l2cap_conn *conn) | ||
| 1520 | { | ||
| 1521 | struct l2cap_user *user; | ||
| 1522 | |||
| 1523 | while (!list_empty(&conn->users)) { | ||
| 1524 | user = list_first_entry(&conn->users, struct l2cap_user, list); | ||
| 1525 | list_del(&user->list); | ||
| 1526 | user->list.next = NULL; | ||
| 1527 | user->list.prev = NULL; | ||
| 1528 | user->remove(conn, user); | ||
| 1529 | } | ||
| 1530 | } | ||
| 1531 | |||
| 1449 | static void l2cap_conn_del(struct hci_conn *hcon, int err) | 1532 | static void l2cap_conn_del(struct hci_conn *hcon, int err) |
| 1450 | { | 1533 | { |
| 1451 | struct l2cap_conn *conn = hcon->l2cap_data; | 1534 | struct l2cap_conn *conn = hcon->l2cap_data; |
| @@ -1458,6 +1541,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
| 1458 | 1541 | ||
| 1459 | kfree_skb(conn->rx_skb); | 1542 | kfree_skb(conn->rx_skb); |
| 1460 | 1543 | ||
| 1544 | l2cap_unregister_all_users(conn); | ||
| 1545 | |||
| 1461 | mutex_lock(&conn->chan_lock); | 1546 | mutex_lock(&conn->chan_lock); |
| 1462 | 1547 | ||
| 1463 | /* Kill channels */ | 1548 | /* Kill channels */ |
| @@ -1486,7 +1571,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
| 1486 | } | 1571 | } |
| 1487 | 1572 | ||
| 1488 | hcon->l2cap_data = NULL; | 1573 | hcon->l2cap_data = NULL; |
| 1489 | kfree(conn); | 1574 | conn->hchan = NULL; |
| 1575 | l2cap_conn_put(conn); | ||
| 1490 | } | 1576 | } |
| 1491 | 1577 | ||
| 1492 | static void security_timeout(struct work_struct *work) | 1578 | static void security_timeout(struct work_struct *work) |
| @@ -1502,12 +1588,12 @@ static void security_timeout(struct work_struct *work) | |||
| 1502 | } | 1588 | } |
| 1503 | } | 1589 | } |
| 1504 | 1590 | ||
| 1505 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1591 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) |
| 1506 | { | 1592 | { |
| 1507 | struct l2cap_conn *conn = hcon->l2cap_data; | 1593 | struct l2cap_conn *conn = hcon->l2cap_data; |
| 1508 | struct hci_chan *hchan; | 1594 | struct hci_chan *hchan; |
| 1509 | 1595 | ||
| 1510 | if (conn || status) | 1596 | if (conn) |
| 1511 | return conn; | 1597 | return conn; |
| 1512 | 1598 | ||
| 1513 | hchan = hci_chan_create(hcon); | 1599 | hchan = hci_chan_create(hcon); |
| @@ -1520,8 +1606,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
| 1520 | return NULL; | 1606 | return NULL; |
| 1521 | } | 1607 | } |
| 1522 | 1608 | ||
| 1609 | kref_init(&conn->ref); | ||
| 1523 | hcon->l2cap_data = conn; | 1610 | hcon->l2cap_data = conn; |
| 1524 | conn->hcon = hcon; | 1611 | conn->hcon = hcon; |
| 1612 | hci_conn_get(conn->hcon); | ||
| 1525 | conn->hchan = hchan; | 1613 | conn->hchan = hchan; |
| 1526 | 1614 | ||
| 1527 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); | 1615 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); |
| @@ -1547,6 +1635,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
| 1547 | mutex_init(&conn->chan_lock); | 1635 | mutex_init(&conn->chan_lock); |
| 1548 | 1636 | ||
| 1549 | INIT_LIST_HEAD(&conn->chan_l); | 1637 | INIT_LIST_HEAD(&conn->chan_l); |
| 1638 | INIT_LIST_HEAD(&conn->users); | ||
| 1550 | 1639 | ||
| 1551 | if (hcon->type == LE_LINK) | 1640 | if (hcon->type == LE_LINK) |
| 1552 | INIT_DELAYED_WORK(&conn->security_timer, security_timeout); | 1641 | INIT_DELAYED_WORK(&conn->security_timer, security_timeout); |
| @@ -1558,6 +1647,26 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
| 1558 | return conn; | 1647 | return conn; |
| 1559 | } | 1648 | } |
| 1560 | 1649 | ||
| 1650 | static void l2cap_conn_free(struct kref *ref) | ||
| 1651 | { | ||
| 1652 | struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); | ||
| 1653 | |||
| 1654 | hci_conn_put(conn->hcon); | ||
| 1655 | kfree(conn); | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | void l2cap_conn_get(struct l2cap_conn *conn) | ||
| 1659 | { | ||
| 1660 | kref_get(&conn->ref); | ||
| 1661 | } | ||
| 1662 | EXPORT_SYMBOL(l2cap_conn_get); | ||
| 1663 | |||
| 1664 | void l2cap_conn_put(struct l2cap_conn *conn) | ||
| 1665 | { | ||
| 1666 | kref_put(&conn->ref, l2cap_conn_free); | ||
| 1667 | } | ||
| 1668 | EXPORT_SYMBOL(l2cap_conn_put); | ||
| 1669 | |||
| 1561 | /* ---- Socket interface ---- */ | 1670 | /* ---- Socket interface ---- */ |
| 1562 | 1671 | ||
| 1563 | /* Find socket with psm and source / destination bdaddr. | 1672 | /* Find socket with psm and source / destination bdaddr. |
| @@ -1695,9 +1804,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
| 1695 | goto done; | 1804 | goto done; |
| 1696 | } | 1805 | } |
| 1697 | 1806 | ||
| 1698 | conn = l2cap_conn_add(hcon, 0); | 1807 | conn = l2cap_conn_add(hcon); |
| 1699 | if (!conn) { | 1808 | if (!conn) { |
| 1700 | hci_conn_put(hcon); | 1809 | hci_conn_drop(hcon); |
| 1701 | err = -ENOMEM; | 1810 | err = -ENOMEM; |
| 1702 | goto done; | 1811 | goto done; |
| 1703 | } | 1812 | } |
| @@ -1707,7 +1816,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
| 1707 | 1816 | ||
| 1708 | if (!list_empty(&conn->chan_l)) { | 1817 | if (!list_empty(&conn->chan_l)) { |
| 1709 | err = -EBUSY; | 1818 | err = -EBUSY; |
| 1710 | hci_conn_put(hcon); | 1819 | hci_conn_drop(hcon); |
| 1711 | } | 1820 | } |
| 1712 | 1821 | ||
| 1713 | if (err) | 1822 | if (err) |
| @@ -6313,7 +6422,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
| 6313 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); | 6422 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); |
| 6314 | 6423 | ||
| 6315 | if (!status) { | 6424 | if (!status) { |
| 6316 | conn = l2cap_conn_add(hcon, status); | 6425 | conn = l2cap_conn_add(hcon); |
| 6317 | if (conn) | 6426 | if (conn) |
| 6318 | l2cap_conn_ready(conn); | 6427 | l2cap_conn_ready(conn); |
| 6319 | } else { | 6428 | } else { |
| @@ -6482,7 +6591,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) | |||
| 6482 | goto drop; | 6591 | goto drop; |
| 6483 | 6592 | ||
| 6484 | if (!conn) | 6593 | if (!conn) |
| 6485 | conn = l2cap_conn_add(hcon, 0); | 6594 | conn = l2cap_conn_add(hcon); |
| 6486 | 6595 | ||
| 6487 | if (!conn) | 6596 | if (!conn) |
| 6488 | goto drop; | 6597 | goto drop; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 7f9704993b74..141e7b058b7e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
| @@ -43,6 +43,12 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent); | |||
| 43 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | 43 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
| 44 | int proto, gfp_t prio); | 44 | int proto, gfp_t prio); |
| 45 | 45 | ||
| 46 | bool l2cap_is_socket(struct socket *sock) | ||
| 47 | { | ||
| 48 | return sock && sock->ops == &l2cap_sock_ops; | ||
| 49 | } | ||
| 50 | EXPORT_SYMBOL(l2cap_is_socket); | ||
| 51 | |||
| 46 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | 52 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
| 47 | { | 53 | { |
| 48 | struct sock *sk = sock->sk; | 54 | struct sock *sk = sock->sk; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 03e7e732215f..4c830c62ef74 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
| @@ -106,11 +106,10 @@ static const u16 mgmt_events[] = { | |||
| 106 | * These LE scan and inquiry parameters were chosen according to LE General | 106 | * These LE scan and inquiry parameters were chosen according to LE General |
| 107 | * Discovery Procedure specification. | 107 | * Discovery Procedure specification. |
| 108 | */ | 108 | */ |
| 109 | #define LE_SCAN_TYPE 0x01 | ||
| 110 | #define LE_SCAN_WIN 0x12 | 109 | #define LE_SCAN_WIN 0x12 |
| 111 | #define LE_SCAN_INT 0x12 | 110 | #define LE_SCAN_INT 0x12 |
| 112 | #define LE_SCAN_TIMEOUT_LE_ONLY 10240 /* TGAP(gen_disc_scan_min) */ | 111 | #define LE_SCAN_TIMEOUT_LE_ONLY msecs_to_jiffies(10240) |
| 113 | #define LE_SCAN_TIMEOUT_BREDR_LE 5120 /* TGAP(100)/2 */ | 112 | #define LE_SCAN_TIMEOUT_BREDR_LE msecs_to_jiffies(5120) |
| 114 | 113 | ||
| 115 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | 114 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ |
| 116 | #define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */ | 115 | #define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */ |
| @@ -2131,7 +2130,7 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
| 2131 | conn->security_cfm_cb = NULL; | 2130 | conn->security_cfm_cb = NULL; |
| 2132 | conn->disconn_cfm_cb = NULL; | 2131 | conn->disconn_cfm_cb = NULL; |
| 2133 | 2132 | ||
| 2134 | hci_conn_put(conn); | 2133 | hci_conn_drop(conn); |
| 2135 | 2134 | ||
| 2136 | mgmt_pending_remove(cmd); | 2135 | mgmt_pending_remove(cmd); |
| 2137 | } | 2136 | } |
| @@ -2222,7 +2221,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 2222 | } | 2221 | } |
| 2223 | 2222 | ||
| 2224 | if (conn->connect_cfm_cb) { | 2223 | if (conn->connect_cfm_cb) { |
| 2225 | hci_conn_put(conn); | 2224 | hci_conn_drop(conn); |
| 2226 | err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, | 2225 | err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, |
| 2227 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); | 2226 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); |
| 2228 | goto unlock; | 2227 | goto unlock; |
| @@ -2231,7 +2230,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 2231 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len); | 2230 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len); |
| 2232 | if (!cmd) { | 2231 | if (!cmd) { |
| 2233 | err = -ENOMEM; | 2232 | err = -ENOMEM; |
| 2234 | hci_conn_put(conn); | 2233 | hci_conn_drop(conn); |
| 2235 | goto unlock; | 2234 | goto unlock; |
| 2236 | } | 2235 | } |
| 2237 | 2236 | ||
| @@ -2703,7 +2702,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
| 2703 | goto failed; | 2702 | goto failed; |
| 2704 | } | 2703 | } |
| 2705 | 2704 | ||
| 2706 | err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, | 2705 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, |
| 2707 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); | 2706 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); |
| 2708 | break; | 2707 | break; |
| 2709 | 2708 | ||
| @@ -2715,8 +2714,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
| 2715 | goto failed; | 2714 | goto failed; |
| 2716 | } | 2715 | } |
| 2717 | 2716 | ||
| 2718 | err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, LE_SCAN_WIN, | 2717 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, |
| 2719 | LE_SCAN_TIMEOUT_BREDR_LE); | 2718 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_BREDR_LE); |
| 2720 | break; | 2719 | break; |
| 2721 | 2720 | ||
| 2722 | default: | 2721 | default: |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 2c8055350510..373d81e6e8f0 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -83,7 +83,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) | |||
| 83 | if (conn) | 83 | if (conn) |
| 84 | return conn; | 84 | return conn; |
| 85 | 85 | ||
| 86 | conn = kzalloc(sizeof(struct sco_conn), GFP_ATOMIC); | 86 | conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); |
| 87 | if (!conn) | 87 | if (!conn) |
| 88 | return NULL; | 88 | return NULL; |
| 89 | 89 | ||
| @@ -185,7 +185,7 @@ static int sco_connect(struct sock *sk) | |||
| 185 | 185 | ||
| 186 | conn = sco_conn_add(hcon); | 186 | conn = sco_conn_add(hcon); |
| 187 | if (!conn) { | 187 | if (!conn) { |
| 188 | hci_conn_put(hcon); | 188 | hci_conn_drop(hcon); |
| 189 | err = -ENOMEM; | 189 | err = -ENOMEM; |
| 190 | goto done; | 190 | goto done; |
| 191 | } | 191 | } |
| @@ -353,7 +353,7 @@ static void __sco_sock_close(struct sock *sk) | |||
| 353 | if (sco_pi(sk)->conn->hcon) { | 353 | if (sco_pi(sk)->conn->hcon) { |
| 354 | sk->sk_state = BT_DISCONN; | 354 | sk->sk_state = BT_DISCONN; |
| 355 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | 355 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); |
| 356 | hci_conn_put(sco_pi(sk)->conn->hcon); | 356 | hci_conn_drop(sco_pi(sk)->conn->hcon); |
| 357 | sco_pi(sk)->conn->hcon = NULL; | 357 | sco_pi(sk)->conn->hcon = NULL; |
| 358 | } else | 358 | } else |
| 359 | sco_chan_del(sk, ECONNRESET); | 359 | sco_chan_del(sk, ECONNRESET); |
| @@ -481,8 +481,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen | |||
| 481 | { | 481 | { |
| 482 | struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; | 482 | struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; |
| 483 | struct sock *sk = sock->sk; | 483 | struct sock *sk = sock->sk; |
| 484 | int err = 0; | 484 | int err; |
| 485 | |||
| 486 | 485 | ||
| 487 | BT_DBG("sk %p", sk); | 486 | BT_DBG("sk %p", sk); |
| 488 | 487 | ||
| @@ -653,6 +652,42 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 653 | return err; | 652 | return err; |
| 654 | } | 653 | } |
| 655 | 654 | ||
| 655 | static void sco_conn_defer_accept(struct hci_conn *conn, int mask) | ||
| 656 | { | ||
| 657 | struct hci_dev *hdev = conn->hdev; | ||
| 658 | |||
| 659 | BT_DBG("conn %p", conn); | ||
| 660 | |||
| 661 | conn->state = BT_CONFIG; | ||
| 662 | |||
| 663 | if (!lmp_esco_capable(hdev)) { | ||
| 664 | struct hci_cp_accept_conn_req cp; | ||
| 665 | |||
| 666 | bacpy(&cp.bdaddr, &conn->dst); | ||
| 667 | |||
| 668 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | ||
| 669 | cp.role = 0x00; /* Become master */ | ||
| 670 | else | ||
| 671 | cp.role = 0x01; /* Remain slave */ | ||
| 672 | |||
| 673 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
| 674 | } else { | ||
| 675 | struct hci_cp_accept_sync_conn_req cp; | ||
| 676 | |||
| 677 | bacpy(&cp.bdaddr, &conn->dst); | ||
| 678 | cp.pkt_type = cpu_to_le16(conn->pkt_type); | ||
| 679 | |||
| 680 | cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
| 681 | cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); | ||
| 682 | cp.max_latency = __constant_cpu_to_le16(0xffff); | ||
| 683 | cp.content_format = cpu_to_le16(hdev->voice_setting); | ||
| 684 | cp.retrans_effort = 0xff; | ||
| 685 | |||
| 686 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, | ||
| 687 | sizeof(cp), &cp); | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 656 | static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | 691 | static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
| 657 | struct msghdr *msg, size_t len, int flags) | 692 | struct msghdr *msg, size_t len, int flags) |
| 658 | { | 693 | { |
| @@ -663,7 +698,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 663 | 698 | ||
| 664 | if (sk->sk_state == BT_CONNECT2 && | 699 | if (sk->sk_state == BT_CONNECT2 && |
| 665 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { | 700 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
| 666 | hci_conn_accept(pi->conn->hcon, 0); | 701 | sco_conn_defer_accept(pi->conn->hcon, 0); |
| 667 | sk->sk_state = BT_CONFIG; | 702 | sk->sk_state = BT_CONFIG; |
| 668 | msg->msg_namelen = 0; | 703 | msg->msg_namelen = 0; |
| 669 | 704 | ||
| @@ -883,7 +918,7 @@ static void sco_chan_del(struct sock *sk, int err) | |||
| 883 | sco_conn_unlock(conn); | 918 | sco_conn_unlock(conn); |
| 884 | 919 | ||
| 885 | if (conn->hcon) | 920 | if (conn->hcon) |
| 886 | hci_conn_put(conn->hcon); | 921 | hci_conn_drop(conn->hcon); |
| 887 | } | 922 | } |
| 888 | 923 | ||
| 889 | sk->sk_state = BT_CLOSED; | 924 | sk->sk_state = BT_CLOSED; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 5abefb12891d..b2296d3857a0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -522,7 +522,7 @@ void smp_chan_destroy(struct l2cap_conn *conn) | |||
| 522 | kfree(smp); | 522 | kfree(smp); |
| 523 | conn->smp_chan = NULL; | 523 | conn->smp_chan = NULL; |
| 524 | conn->hcon->smp_conn = NULL; | 524 | conn->hcon->smp_conn = NULL; |
| 525 | hci_conn_put(conn->hcon); | 525 | hci_conn_drop(conn->hcon); |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | 528 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c50c19402588..1a89c80e6407 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -805,8 +805,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
| 805 | IEEE80211_CHANCTX_EXCLUSIVE); | 805 | IEEE80211_CHANCTX_EXCLUSIVE); |
| 806 | } | 806 | } |
| 807 | } else if (local->open_count == local->monitors) { | 807 | } else if (local->open_count == local->monitors) { |
| 808 | local->_oper_channel = chandef->chan; | 808 | local->_oper_chandef = *chandef; |
| 809 | local->_oper_channel_type = cfg80211_get_chandef_type(chandef); | ||
| 810 | ieee80211_hw_config(local, 0); | 809 | ieee80211_hw_config(local, 0); |
| 811 | } | 810 | } |
| 812 | 811 | ||
| @@ -965,8 +964,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
| 965 | sdata->vif.bss_conf.hidden_ssid = | 964 | sdata->vif.bss_conf.hidden_ssid = |
| 966 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); | 965 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); |
| 967 | 966 | ||
| 968 | sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow; | 967 | memset(&sdata->vif.bss_conf.p2p_noa_attr, 0, |
| 969 | sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps; | 968 | sizeof(sdata->vif.bss_conf.p2p_noa_attr)); |
| 969 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow = | ||
| 970 | params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK; | ||
| 971 | if (params->p2p_opp_ps) | ||
| 972 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= | ||
| 973 | IEEE80211_P2P_OPPPS_ENABLE_BIT; | ||
| 970 | 974 | ||
| 971 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); | 975 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); |
| 972 | if (err < 0) | 976 | if (err < 0) |
| @@ -1039,6 +1043,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1039 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 1043 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
| 1040 | sta_info_flush_defer(vlan); | 1044 | sta_info_flush_defer(vlan); |
| 1041 | sta_info_flush_defer(sdata); | 1045 | sta_info_flush_defer(sdata); |
| 1046 | synchronize_net(); | ||
| 1042 | rcu_barrier(); | 1047 | rcu_barrier(); |
| 1043 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { | 1048 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { |
| 1044 | sta_info_flush_cleanup(vlan); | 1049 | sta_info_flush_cleanup(vlan); |
| @@ -1048,6 +1053,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1048 | ieee80211_free_keys(sdata); | 1053 | ieee80211_free_keys(sdata); |
| 1049 | 1054 | ||
| 1050 | sdata->vif.bss_conf.enable_beacon = false; | 1055 | sdata->vif.bss_conf.enable_beacon = false; |
| 1056 | sdata->vif.bss_conf.ssid_len = 0; | ||
| 1051 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
| 1052 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
| 1053 | 1059 | ||
| @@ -1536,7 +1542,6 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
| 1536 | struct ieee80211_sub_if_data *sdata; | 1542 | struct ieee80211_sub_if_data *sdata; |
| 1537 | struct mesh_path *mpath; | 1543 | struct mesh_path *mpath; |
| 1538 | struct sta_info *sta; | 1544 | struct sta_info *sta; |
| 1539 | int err; | ||
| 1540 | 1545 | ||
| 1541 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1546 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1542 | 1547 | ||
| @@ -1547,17 +1552,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, | |||
| 1547 | return -ENOENT; | 1552 | return -ENOENT; |
| 1548 | } | 1553 | } |
| 1549 | 1554 | ||
| 1550 | err = mesh_path_add(sdata, dst); | 1555 | mpath = mesh_path_add(sdata, dst); |
| 1551 | if (err) { | 1556 | if (IS_ERR(mpath)) { |
| 1552 | rcu_read_unlock(); | 1557 | rcu_read_unlock(); |
| 1553 | return err; | 1558 | return PTR_ERR(mpath); |
| 1554 | } | 1559 | } |
| 1555 | 1560 | ||
| 1556 | mpath = mesh_path_lookup(sdata, dst); | ||
| 1557 | if (!mpath) { | ||
| 1558 | rcu_read_unlock(); | ||
| 1559 | return -ENXIO; | ||
| 1560 | } | ||
| 1561 | mesh_path_fix_nexthop(mpath, sta); | 1561 | mesh_path_fix_nexthop(mpath, sta); |
| 1562 | 1562 | ||
| 1563 | rcu_read_unlock(); | 1563 | rcu_read_unlock(); |
| @@ -1961,12 +1961,20 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
| 1961 | } | 1961 | } |
| 1962 | 1962 | ||
| 1963 | if (params->p2p_ctwindow >= 0) { | 1963 | if (params->p2p_ctwindow >= 0) { |
| 1964 | sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow; | 1964 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &= |
| 1965 | ~IEEE80211_P2P_OPPPS_CTWINDOW_MASK; | ||
| 1966 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= | ||
| 1967 | params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK; | ||
| 1965 | changed |= BSS_CHANGED_P2P_PS; | 1968 | changed |= BSS_CHANGED_P2P_PS; |
| 1966 | } | 1969 | } |
| 1967 | 1970 | ||
| 1968 | if (params->p2p_opp_ps >= 0) { | 1971 | if (params->p2p_opp_ps > 0) { |
| 1969 | sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps; | 1972 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= |
| 1973 | IEEE80211_P2P_OPPPS_ENABLE_BIT; | ||
| 1974 | changed |= BSS_CHANGED_P2P_PS; | ||
| 1975 | } else if (params->p2p_opp_ps == 0) { | ||
| 1976 | sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &= | ||
| 1977 | ~IEEE80211_P2P_OPPPS_ENABLE_BIT; | ||
| 1970 | changed |= BSS_CHANGED_P2P_PS; | 1978 | changed |= BSS_CHANGED_P2P_PS; |
| 1971 | } | 1979 | } |
| 1972 | 1980 | ||
| @@ -2410,9 +2418,22 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
| 2410 | } | 2418 | } |
| 2411 | 2419 | ||
| 2412 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 2420 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
| 2421 | struct ieee80211_supported_band *sband = wiphy->bands[i]; | ||
| 2422 | int j; | ||
| 2423 | |||
| 2413 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; | 2424 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; |
| 2414 | memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, | 2425 | memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, |
| 2415 | sizeof(mask->control[i].mcs)); | 2426 | sizeof(mask->control[i].mcs)); |
| 2427 | |||
| 2428 | sdata->rc_has_mcs_mask[i] = false; | ||
| 2429 | if (!sband) | ||
| 2430 | continue; | ||
| 2431 | |||
| 2432 | for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++) | ||
| 2433 | if (~sdata->rc_rateidx_mcs_mask[i][j]) { | ||
| 2434 | sdata->rc_has_mcs_mask[i] = true; | ||
| 2435 | break; | ||
| 2436 | } | ||
| 2416 | } | 2437 | } |
| 2417 | 2438 | ||
| 2418 | return 0; | 2439 | return 0; |
| @@ -3362,9 +3383,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, | |||
| 3362 | if (local->use_chanctx) | 3383 | if (local->use_chanctx) |
| 3363 | *chandef = local->monitor_chandef; | 3384 | *chandef = local->monitor_chandef; |
| 3364 | else | 3385 | else |
| 3365 | cfg80211_chandef_create(chandef, | 3386 | *chandef = local->_oper_chandef; |
| 3366 | local->_oper_channel, | ||
| 3367 | local->_oper_channel_type); | ||
| 3368 | ret = 0; | 3387 | ret = 0; |
| 3369 | } | 3388 | } |
| 3370 | rcu_read_unlock(); | 3389 | rcu_read_unlock(); |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 931be419ab5a..03e8d2e3270e 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
| @@ -22,7 +22,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local, | |||
| 22 | drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); | 22 | drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); |
| 23 | 23 | ||
| 24 | if (!local->use_chanctx) { | 24 | if (!local->use_chanctx) { |
| 25 | local->_oper_channel_type = cfg80211_get_chandef_type(chandef); | 25 | local->_oper_chandef = *chandef; |
| 26 | ieee80211_hw_config(local, 0); | 26 | ieee80211_hw_config(local, 0); |
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| @@ -57,6 +57,22 @@ ieee80211_find_chanctx(struct ieee80211_local *local, | |||
| 57 | return NULL; | 57 | return NULL; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static bool ieee80211_is_radar_required(struct ieee80211_local *local) | ||
| 61 | { | ||
| 62 | struct ieee80211_sub_if_data *sdata; | ||
| 63 | |||
| 64 | rcu_read_lock(); | ||
| 65 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
| 66 | if (sdata->radar_required) { | ||
| 67 | rcu_read_unlock(); | ||
| 68 | return true; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | rcu_read_unlock(); | ||
| 72 | |||
| 73 | return false; | ||
| 74 | } | ||
| 75 | |||
| 60 | static struct ieee80211_chanctx * | 76 | static struct ieee80211_chanctx * |
| 61 | ieee80211_new_chanctx(struct ieee80211_local *local, | 77 | ieee80211_new_chanctx(struct ieee80211_local *local, |
| 62 | const struct cfg80211_chan_def *chandef, | 78 | const struct cfg80211_chan_def *chandef, |
| @@ -76,6 +92,9 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
| 76 | ctx->conf.rx_chains_static = 1; | 92 | ctx->conf.rx_chains_static = 1; |
| 77 | ctx->conf.rx_chains_dynamic = 1; | 93 | ctx->conf.rx_chains_dynamic = 1; |
| 78 | ctx->mode = mode; | 94 | ctx->mode = mode; |
| 95 | ctx->conf.radar_enabled = ieee80211_is_radar_required(local); | ||
| 96 | if (!local->use_chanctx) | ||
| 97 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; | ||
| 79 | 98 | ||
| 80 | /* acquire mutex to prevent idle from changing */ | 99 | /* acquire mutex to prevent idle from changing */ |
| 81 | mutex_lock(&local->mtx); | 100 | mutex_lock(&local->mtx); |
| @@ -85,9 +104,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
| 85 | ieee80211_hw_config(local, changed); | 104 | ieee80211_hw_config(local, changed); |
| 86 | 105 | ||
| 87 | if (!local->use_chanctx) { | 106 | if (!local->use_chanctx) { |
| 88 | local->_oper_channel_type = | 107 | local->_oper_chandef = *chandef; |
| 89 | cfg80211_get_chandef_type(chandef); | ||
| 90 | local->_oper_channel = chandef->chan; | ||
| 91 | ieee80211_hw_config(local, 0); | 108 | ieee80211_hw_config(local, 0); |
| 92 | } else { | 109 | } else { |
| 93 | err = drv_add_chanctx(local, ctx); | 110 | err = drv_add_chanctx(local, ctx); |
| @@ -112,12 +129,24 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
| 112 | static void ieee80211_free_chanctx(struct ieee80211_local *local, | 129 | static void ieee80211_free_chanctx(struct ieee80211_local *local, |
| 113 | struct ieee80211_chanctx *ctx) | 130 | struct ieee80211_chanctx *ctx) |
| 114 | { | 131 | { |
| 132 | bool check_single_channel = false; | ||
| 115 | lockdep_assert_held(&local->chanctx_mtx); | 133 | lockdep_assert_held(&local->chanctx_mtx); |
| 116 | 134 | ||
| 117 | WARN_ON_ONCE(ctx->refcount != 0); | 135 | WARN_ON_ONCE(ctx->refcount != 0); |
| 118 | 136 | ||
| 119 | if (!local->use_chanctx) { | 137 | if (!local->use_chanctx) { |
| 120 | local->_oper_channel_type = NL80211_CHAN_NO_HT; | 138 | struct cfg80211_chan_def *chandef = &local->_oper_chandef; |
| 139 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; | ||
| 140 | chandef->center_freq1 = chandef->chan->center_freq; | ||
| 141 | chandef->center_freq2 = 0; | ||
| 142 | |||
| 143 | /* NOTE: Disabling radar is only valid here for | ||
| 144 | * single channel context. To be sure, check it ... | ||
| 145 | */ | ||
| 146 | if (local->hw.conf.radar_enabled) | ||
| 147 | check_single_channel = true; | ||
| 148 | local->hw.conf.radar_enabled = false; | ||
| 149 | |||
| 121 | ieee80211_hw_config(local, 0); | 150 | ieee80211_hw_config(local, 0); |
| 122 | } else { | 151 | } else { |
| 123 | drv_remove_chanctx(local, ctx); | 152 | drv_remove_chanctx(local, ctx); |
| @@ -126,6 +155,9 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, | |||
| 126 | list_del_rcu(&ctx->list); | 155 | list_del_rcu(&ctx->list); |
| 127 | kfree_rcu(ctx, rcu_head); | 156 | kfree_rcu(ctx, rcu_head); |
| 128 | 157 | ||
| 158 | /* throw a warning if this wasn't the only channel context. */ | ||
| 159 | WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); | ||
| 160 | |||
| 129 | mutex_lock(&local->mtx); | 161 | mutex_lock(&local->mtx); |
| 130 | ieee80211_recalc_idle(local); | 162 | ieee80211_recalc_idle(local); |
| 131 | mutex_unlock(&local->mtx); | 163 | mutex_unlock(&local->mtx); |
| @@ -237,19 +269,11 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
| 237 | void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | 269 | void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, |
| 238 | struct ieee80211_chanctx *chanctx) | 270 | struct ieee80211_chanctx *chanctx) |
| 239 | { | 271 | { |
| 240 | struct ieee80211_sub_if_data *sdata; | 272 | bool radar_enabled; |
| 241 | bool radar_enabled = false; | ||
| 242 | 273 | ||
| 243 | lockdep_assert_held(&local->chanctx_mtx); | 274 | lockdep_assert_held(&local->chanctx_mtx); |
| 244 | 275 | ||
| 245 | rcu_read_lock(); | 276 | radar_enabled = ieee80211_is_radar_required(local); |
| 246 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
| 247 | if (sdata->radar_required) { | ||
| 248 | radar_enabled = true; | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | rcu_read_unlock(); | ||
| 253 | 277 | ||
| 254 | if (radar_enabled == chanctx->conf.radar_enabled) | 278 | if (radar_enabled == chanctx->conf.radar_enabled) |
| 255 | return; | 279 | return; |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ddb426867904..14abcf44f974 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
| @@ -124,6 +124,15 @@ static ssize_t ieee80211_if_fmt_##name( \ | |||
| 124 | return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \ | 124 | return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \ |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | #define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field) \ | ||
| 128 | static ssize_t ieee80211_if_fmt_##name( \ | ||
| 129 | const struct ieee80211_sub_if_data *sdata, \ | ||
| 130 | char *buf, int buflen) \ | ||
| 131 | { \ | ||
| 132 | return scnprintf(buf, buflen, "%d\n", \ | ||
| 133 | jiffies_to_msecs(sdata->field)); \ | ||
| 134 | } | ||
| 135 | |||
| 127 | #define __IEEE80211_IF_FILE(name, _write) \ | 136 | #define __IEEE80211_IF_FILE(name, _write) \ |
| 128 | static ssize_t ieee80211_if_read_##name(struct file *file, \ | 137 | static ssize_t ieee80211_if_read_##name(struct file *file, \ |
| 129 | char __user *userbuf, \ | 138 | char __user *userbuf, \ |
| @@ -197,6 +206,7 @@ IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); | |||
| 197 | IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); | 206 | IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); |
| 198 | IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC); | 207 | IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC); |
| 199 | IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16); | 208 | IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16); |
| 209 | IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS); | ||
| 200 | 210 | ||
| 201 | static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, | 211 | static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, |
| 202 | enum ieee80211_smps_mode smps_mode) | 212 | enum ieee80211_smps_mode smps_mode) |
| @@ -542,6 +552,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
| 542 | DEBUGFS_ADD(aid); | 552 | DEBUGFS_ADD(aid); |
| 543 | DEBUGFS_ADD(last_beacon); | 553 | DEBUGFS_ADD(last_beacon); |
| 544 | DEBUGFS_ADD(ave_beacon); | 554 | DEBUGFS_ADD(ave_beacon); |
| 555 | DEBUGFS_ADD(beacon_timeout); | ||
| 545 | DEBUGFS_ADD_MODE(smps, 0600); | 556 | DEBUGFS_ADD_MODE(smps, 0600); |
| 546 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); | 557 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); |
| 547 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); | 558 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 4f841fe559df..44e201d60a13 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
| @@ -54,6 +54,7 @@ STA_FILE(aid, sta.aid, D); | |||
| 54 | STA_FILE(dev, sdata->name, S); | 54 | STA_FILE(dev, sdata->name, S); |
| 55 | STA_FILE(last_signal, last_signal, D); | 55 | STA_FILE(last_signal, last_signal, D); |
| 56 | STA_FILE(last_ack_signal, last_ack_signal, D); | 56 | STA_FILE(last_ack_signal, last_ack_signal, D); |
| 57 | STA_FILE(beacon_loss_count, beacon_loss_count, D); | ||
| 57 | 58 | ||
| 58 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 59 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
| 59 | size_t count, loff_t *ppos) | 60 | size_t count, loff_t *ppos) |
| @@ -434,6 +435,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
| 434 | DEBUGFS_ADD(agg_status); | 435 | DEBUGFS_ADD(agg_status); |
| 435 | DEBUGFS_ADD(dev); | 436 | DEBUGFS_ADD(dev); |
| 436 | DEBUGFS_ADD(last_signal); | 437 | DEBUGFS_ADD(last_signal); |
| 438 | DEBUGFS_ADD(beacon_loss_count); | ||
| 437 | DEBUGFS_ADD(ht_capa); | 439 | DEBUGFS_ADD(ht_capa); |
| 438 | DEBUGFS_ADD(vht_capa); | 440 | DEBUGFS_ADD(vht_capa); |
| 439 | DEBUGFS_ADD(last_ack_signal); | 441 | DEBUGFS_ADD(last_ack_signal); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 539d4a11b47b..170f9a7fa319 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -44,7 +44,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
| 45 | struct ieee80211_local *local = sdata->local; | 45 | struct ieee80211_local *local = sdata->local; |
| 46 | int rates, i; | 46 | int rates, i; |
| 47 | struct sk_buff *skb; | ||
| 48 | struct ieee80211_mgmt *mgmt; | 47 | struct ieee80211_mgmt *mgmt; |
| 49 | u8 *pos; | 48 | u8 *pos; |
| 50 | struct ieee80211_supported_band *sband; | 49 | struct ieee80211_supported_band *sband; |
| @@ -52,20 +51,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 52 | u32 bss_change; | 51 | u32 bss_change; |
| 53 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 52 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
| 54 | struct cfg80211_chan_def chandef; | 53 | struct cfg80211_chan_def chandef; |
| 54 | struct beacon_data *presp; | ||
| 55 | int frame_len; | ||
| 55 | 56 | ||
| 56 | lockdep_assert_held(&ifibss->mtx); | 57 | lockdep_assert_held(&ifibss->mtx); |
| 57 | 58 | ||
| 58 | /* Reset own TSF to allow time synchronization work. */ | 59 | /* Reset own TSF to allow time synchronization work. */ |
| 59 | drv_reset_tsf(local, sdata); | 60 | drv_reset_tsf(local, sdata); |
| 60 | 61 | ||
| 61 | skb = ifibss->skb; | ||
| 62 | RCU_INIT_POINTER(ifibss->presp, NULL); | ||
| 63 | synchronize_rcu(); | ||
| 64 | skb->data = skb->head; | ||
| 65 | skb->len = 0; | ||
| 66 | skb_reset_tail_pointer(skb); | ||
| 67 | skb_reserve(skb, sdata->local->hw.extra_tx_headroom); | ||
| 68 | |||
| 69 | if (!ether_addr_equal(ifibss->bssid, bssid)) | 62 | if (!ether_addr_equal(ifibss->bssid, bssid)) |
| 70 | sta_info_flush(sdata); | 63 | sta_info_flush(sdata); |
| 71 | 64 | ||
| @@ -73,10 +66,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 73 | if (sdata->vif.bss_conf.ibss_joined) { | 66 | if (sdata->vif.bss_conf.ibss_joined) { |
| 74 | sdata->vif.bss_conf.ibss_joined = false; | 67 | sdata->vif.bss_conf.ibss_joined = false; |
| 75 | sdata->vif.bss_conf.ibss_creator = false; | 68 | sdata->vif.bss_conf.ibss_creator = false; |
| 69 | sdata->vif.bss_conf.enable_beacon = false; | ||
| 76 | netif_carrier_off(sdata->dev); | 70 | netif_carrier_off(sdata->dev); |
| 77 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | 71 | ieee80211_bss_info_change_notify(sdata, |
| 72 | BSS_CHANGED_IBSS | | ||
| 73 | BSS_CHANGED_BEACON_ENABLED); | ||
| 78 | } | 74 | } |
| 79 | 75 | ||
| 76 | presp = rcu_dereference_protected(ifibss->presp, | ||
| 77 | lockdep_is_held(&ifibss->mtx)); | ||
| 78 | rcu_assign_pointer(ifibss->presp, NULL); | ||
| 79 | if (presp) | ||
| 80 | kfree_rcu(presp, rcu_head); | ||
| 81 | |||
| 80 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 82 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
| 81 | 83 | ||
| 82 | cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); | 84 | cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); |
| @@ -98,19 +100,24 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 98 | 100 | ||
| 99 | sband = local->hw.wiphy->bands[chan->band]; | 101 | sband = local->hw.wiphy->bands[chan->band]; |
| 100 | 102 | ||
| 101 | /* build supported rates array */ | ||
| 102 | pos = supp_rates; | ||
| 103 | for (i = 0; i < sband->n_bitrates; i++) { | ||
| 104 | int rate = sband->bitrates[i].bitrate; | ||
| 105 | u8 basic = 0; | ||
| 106 | if (basic_rates & BIT(i)) | ||
| 107 | basic = 0x80; | ||
| 108 | *pos++ = basic | (u8) (rate / 5); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* Build IBSS probe response */ | 103 | /* Build IBSS probe response */ |
| 112 | mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 104 | frame_len = sizeof(struct ieee80211_hdr_3addr) + |
| 113 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 105 | 12 /* struct ieee80211_mgmt.u.beacon */ + |
| 106 | 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ + | ||
| 107 | 2 + 8 /* max Supported Rates */ + | ||
| 108 | 3 /* max DS params */ + | ||
| 109 | 4 /* IBSS params */ + | ||
| 110 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
| 111 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
| 112 | 2 + sizeof(struct ieee80211_ht_operation) + | ||
| 113 | ifibss->ie_len; | ||
| 114 | presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); | ||
| 115 | if (!presp) | ||
| 116 | return; | ||
| 117 | |||
| 118 | presp->head = (void *)(presp + 1); | ||
| 119 | |||
| 120 | mgmt = (void *) presp->head; | ||
| 114 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 121 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
| 115 | IEEE80211_STYPE_PROBE_RESP); | 122 | IEEE80211_STYPE_PROBE_RESP); |
| 116 | eth_broadcast_addr(mgmt->da); | 123 | eth_broadcast_addr(mgmt->da); |
| @@ -120,27 +127,30 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 120 | mgmt->u.beacon.timestamp = cpu_to_le64(tsf); | 127 | mgmt->u.beacon.timestamp = cpu_to_le64(tsf); |
| 121 | mgmt->u.beacon.capab_info = cpu_to_le16(capability); | 128 | mgmt->u.beacon.capab_info = cpu_to_le16(capability); |
| 122 | 129 | ||
| 123 | pos = skb_put(skb, 2 + ifibss->ssid_len); | 130 | pos = (u8 *)mgmt + offsetof(struct ieee80211_mgmt, u.beacon.variable); |
| 131 | |||
| 124 | *pos++ = WLAN_EID_SSID; | 132 | *pos++ = WLAN_EID_SSID; |
| 125 | *pos++ = ifibss->ssid_len; | 133 | *pos++ = ifibss->ssid_len; |
| 126 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); | 134 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); |
| 135 | pos += ifibss->ssid_len; | ||
| 127 | 136 | ||
| 128 | rates = sband->n_bitrates; | 137 | rates = min_t(int, 8, sband->n_bitrates); |
| 129 | if (rates > 8) | ||
| 130 | rates = 8; | ||
| 131 | pos = skb_put(skb, 2 + rates); | ||
| 132 | *pos++ = WLAN_EID_SUPP_RATES; | 138 | *pos++ = WLAN_EID_SUPP_RATES; |
| 133 | *pos++ = rates; | 139 | *pos++ = rates; |
| 134 | memcpy(pos, supp_rates, rates); | 140 | for (i = 0; i < rates; i++) { |
| 141 | int rate = sband->bitrates[i].bitrate; | ||
| 142 | u8 basic = 0; | ||
| 143 | if (basic_rates & BIT(i)) | ||
| 144 | basic = 0x80; | ||
| 145 | *pos++ = basic | (u8) (rate / 5); | ||
| 146 | } | ||
| 135 | 147 | ||
| 136 | if (sband->band == IEEE80211_BAND_2GHZ) { | 148 | if (sband->band == IEEE80211_BAND_2GHZ) { |
| 137 | pos = skb_put(skb, 2 + 1); | ||
| 138 | *pos++ = WLAN_EID_DS_PARAMS; | 149 | *pos++ = WLAN_EID_DS_PARAMS; |
| 139 | *pos++ = 1; | 150 | *pos++ = 1; |
| 140 | *pos++ = ieee80211_frequency_to_channel(chan->center_freq); | 151 | *pos++ = ieee80211_frequency_to_channel(chan->center_freq); |
| 141 | } | 152 | } |
| 142 | 153 | ||
| 143 | pos = skb_put(skb, 2 + 2); | ||
| 144 | *pos++ = WLAN_EID_IBSS_PARAMS; | 154 | *pos++ = WLAN_EID_IBSS_PARAMS; |
| 145 | *pos++ = 2; | 155 | *pos++ = 2; |
| 146 | /* FIX: set ATIM window based on scan results */ | 156 | /* FIX: set ATIM window based on scan results */ |
| @@ -148,23 +158,25 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 148 | *pos++ = 0; | 158 | *pos++ = 0; |
| 149 | 159 | ||
| 150 | if (sband->n_bitrates > 8) { | 160 | if (sband->n_bitrates > 8) { |
| 151 | rates = sband->n_bitrates - 8; | ||
| 152 | pos = skb_put(skb, 2 + rates); | ||
| 153 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 161 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
| 154 | *pos++ = rates; | 162 | *pos++ = sband->n_bitrates - 8; |
| 155 | memcpy(pos, &supp_rates[8], rates); | 163 | for (i = 8; i < sband->n_bitrates; i++) { |
| 164 | int rate = sband->bitrates[i].bitrate; | ||
| 165 | u8 basic = 0; | ||
| 166 | if (basic_rates & BIT(i)) | ||
| 167 | basic = 0x80; | ||
| 168 | *pos++ = basic | (u8) (rate / 5); | ||
| 169 | } | ||
| 156 | } | 170 | } |
| 157 | 171 | ||
| 158 | if (ifibss->ie_len) | 172 | if (ifibss->ie_len) { |
| 159 | memcpy(skb_put(skb, ifibss->ie_len), | 173 | memcpy(pos, ifibss->ie, ifibss->ie_len); |
| 160 | ifibss->ie, ifibss->ie_len); | 174 | pos += ifibss->ie_len; |
| 175 | } | ||
| 161 | 176 | ||
| 162 | /* add HT capability and information IEs */ | 177 | /* add HT capability and information IEs */ |
| 163 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 178 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
| 164 | sband->ht_cap.ht_supported) { | 179 | sband->ht_cap.ht_supported) { |
| 165 | pos = skb_put(skb, 4 + | ||
| 166 | sizeof(struct ieee80211_ht_cap) + | ||
| 167 | sizeof(struct ieee80211_ht_operation)); | ||
| 168 | pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, | 180 | pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, |
| 169 | sband->ht_cap.cap); | 181 | sband->ht_cap.cap); |
| 170 | /* | 182 | /* |
| @@ -177,7 +189,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 177 | } | 189 | } |
| 178 | 190 | ||
| 179 | if (local->hw.queues >= IEEE80211_NUM_ACS) { | 191 | if (local->hw.queues >= IEEE80211_NUM_ACS) { |
| 180 | pos = skb_put(skb, 9); | ||
| 181 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; | 192 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; |
| 182 | *pos++ = 7; /* len */ | 193 | *pos++ = 7; /* len */ |
| 183 | *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ | 194 | *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ |
| @@ -189,11 +200,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 189 | *pos++ = 0; /* U-APSD no in use */ | 200 | *pos++ = 0; /* U-APSD no in use */ |
| 190 | } | 201 | } |
| 191 | 202 | ||
| 192 | rcu_assign_pointer(ifibss->presp, skb); | 203 | presp->head_len = pos - presp->head; |
| 204 | if (WARN_ON(presp->head_len > frame_len)) | ||
| 205 | return; | ||
| 206 | |||
| 207 | rcu_assign_pointer(ifibss->presp, presp); | ||
| 193 | 208 | ||
| 194 | sdata->vif.bss_conf.enable_beacon = true; | 209 | sdata->vif.bss_conf.enable_beacon = true; |
| 195 | sdata->vif.bss_conf.beacon_int = beacon_int; | 210 | sdata->vif.bss_conf.beacon_int = beacon_int; |
| 196 | sdata->vif.bss_conf.basic_rates = basic_rates; | 211 | sdata->vif.bss_conf.basic_rates = basic_rates; |
| 212 | sdata->vif.bss_conf.ssid_len = ifibss->ssid_len; | ||
| 213 | memcpy(sdata->vif.bss_conf.ssid, ifibss->ssid, ifibss->ssid_len); | ||
| 197 | bss_change = BSS_CHANGED_BEACON_INT; | 214 | bss_change = BSS_CHANGED_BEACON_INT; |
| 198 | bss_change |= ieee80211_reset_erp_info(sdata); | 215 | bss_change |= ieee80211_reset_erp_info(sdata); |
| 199 | bss_change |= BSS_CHANGED_BSSID; | 216 | bss_change |= BSS_CHANGED_BSSID; |
| @@ -202,6 +219,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 202 | bss_change |= BSS_CHANGED_BASIC_RATES; | 219 | bss_change |= BSS_CHANGED_BASIC_RATES; |
| 203 | bss_change |= BSS_CHANGED_HT; | 220 | bss_change |= BSS_CHANGED_HT; |
| 204 | bss_change |= BSS_CHANGED_IBSS; | 221 | bss_change |= BSS_CHANGED_IBSS; |
| 222 | bss_change |= BSS_CHANGED_SSID; | ||
| 205 | 223 | ||
| 206 | /* | 224 | /* |
| 207 | * In 5 GHz/802.11a, we can always use short slot time. | 225 | * In 5 GHz/802.11a, we can always use short slot time. |
| @@ -227,7 +245,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 227 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); | 245 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); |
| 228 | 246 | ||
| 229 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, | 247 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, |
| 230 | mgmt, skb->len, 0, GFP_KERNEL); | 248 | mgmt, presp->head_len, 0, GFP_KERNEL); |
| 231 | cfg80211_put_bss(local->hw.wiphy, bss); | 249 | cfg80211_put_bss(local->hw.wiphy, bss); |
| 232 | netif_carrier_on(sdata->dev); | 250 | netif_carrier_on(sdata->dev); |
| 233 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); | 251 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); |
| @@ -448,7 +466,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 448 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; | 466 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; |
| 449 | bool rates_updated = false; | 467 | bool rates_updated = false; |
| 450 | 468 | ||
| 451 | if (elems->ds_params && elems->ds_params_len == 1) | 469 | if (elems->ds_params) |
| 452 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], | 470 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], |
| 453 | band); | 471 | band); |
| 454 | else | 472 | else |
| @@ -822,8 +840,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
| 822 | struct ieee80211_local *local = sdata->local; | 840 | struct ieee80211_local *local = sdata->local; |
| 823 | int tx_last_beacon, len = req->len; | 841 | int tx_last_beacon, len = req->len; |
| 824 | struct sk_buff *skb; | 842 | struct sk_buff *skb; |
| 825 | struct ieee80211_mgmt *resp; | 843 | struct beacon_data *presp; |
| 826 | struct sk_buff *presp; | ||
| 827 | u8 *pos, *end; | 844 | u8 *pos, *end; |
| 828 | 845 | ||
| 829 | lockdep_assert_held(&ifibss->mtx); | 846 | lockdep_assert_held(&ifibss->mtx); |
| @@ -864,13 +881,15 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
| 864 | } | 881 | } |
| 865 | 882 | ||
| 866 | /* Reply with ProbeResp */ | 883 | /* Reply with ProbeResp */ |
| 867 | skb = skb_copy(presp, GFP_KERNEL); | 884 | skb = dev_alloc_skb(local->tx_headroom + presp->head_len); |
| 868 | if (!skb) | 885 | if (!skb) |
| 869 | return; | 886 | return; |
| 870 | 887 | ||
| 871 | resp = (struct ieee80211_mgmt *) skb->data; | 888 | skb_reserve(skb, local->tx_headroom); |
| 872 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 889 | memcpy(skb_put(skb, presp->head_len), presp->head, presp->head_len); |
| 873 | ibss_dbg(sdata, "Sending ProbeResp to %pM\n", resp->da); | 890 | |
| 891 | memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN); | ||
| 892 | ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa); | ||
| 874 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 893 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
| 875 | ieee80211_tx_skb(sdata, skb); | 894 | ieee80211_tx_skb(sdata, skb); |
| 876 | } | 895 | } |
| @@ -895,7 +914,7 @@ void ieee80211_rx_mgmt_probe_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 895 | return; | 914 | return; |
| 896 | 915 | ||
| 897 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 916 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
| 898 | &elems); | 917 | false, &elems); |
| 899 | 918 | ||
| 900 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 919 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
| 901 | } | 920 | } |
| @@ -1020,23 +1039,8 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) | |||
| 1020 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | 1039 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, |
| 1021 | struct cfg80211_ibss_params *params) | 1040 | struct cfg80211_ibss_params *params) |
| 1022 | { | 1041 | { |
| 1023 | struct sk_buff *skb; | ||
| 1024 | u32 changed = 0; | 1042 | u32 changed = 0; |
| 1025 | 1043 | ||
| 1026 | skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + | ||
| 1027 | sizeof(struct ieee80211_hdr_3addr) + | ||
| 1028 | 12 /* struct ieee80211_mgmt.u.beacon */ + | ||
| 1029 | 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ + | ||
| 1030 | 2 + 8 /* max Supported Rates */ + | ||
| 1031 | 3 /* max DS params */ + | ||
| 1032 | 4 /* IBSS params */ + | ||
| 1033 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
| 1034 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
| 1035 | 2 + sizeof(struct ieee80211_ht_operation) + | ||
| 1036 | params->ie_len); | ||
| 1037 | if (!skb) | ||
| 1038 | return -ENOMEM; | ||
| 1039 | |||
| 1040 | mutex_lock(&sdata->u.ibss.mtx); | 1044 | mutex_lock(&sdata->u.ibss.mtx); |
| 1041 | 1045 | ||
| 1042 | if (params->bssid) { | 1046 | if (params->bssid) { |
| @@ -1065,7 +1069,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
| 1065 | sdata->u.ibss.ie_len = params->ie_len; | 1069 | sdata->u.ibss.ie_len = params->ie_len; |
| 1066 | } | 1070 | } |
| 1067 | 1071 | ||
| 1068 | sdata->u.ibss.skb = skb; | ||
| 1069 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | 1072 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; |
| 1070 | sdata->u.ibss.ibss_join_req = jiffies; | 1073 | sdata->u.ibss.ibss_join_req = jiffies; |
| 1071 | 1074 | ||
| @@ -1101,13 +1104,13 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
| 1101 | 1104 | ||
| 1102 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | 1105 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) |
| 1103 | { | 1106 | { |
| 1104 | struct sk_buff *skb; | ||
| 1105 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 1107 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
| 1106 | struct ieee80211_local *local = sdata->local; | 1108 | struct ieee80211_local *local = sdata->local; |
| 1107 | struct cfg80211_bss *cbss; | 1109 | struct cfg80211_bss *cbss; |
| 1108 | u16 capability; | 1110 | u16 capability; |
| 1109 | int active_ibss; | 1111 | int active_ibss; |
| 1110 | struct sta_info *sta; | 1112 | struct sta_info *sta; |
| 1113 | struct beacon_data *presp; | ||
| 1111 | 1114 | ||
| 1112 | mutex_lock(&sdata->u.ibss.mtx); | 1115 | mutex_lock(&sdata->u.ibss.mtx); |
| 1113 | 1116 | ||
| @@ -1153,17 +1156,18 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
| 1153 | 1156 | ||
| 1154 | /* remove beacon */ | 1157 | /* remove beacon */ |
| 1155 | kfree(sdata->u.ibss.ie); | 1158 | kfree(sdata->u.ibss.ie); |
| 1156 | skb = rcu_dereference_protected(sdata->u.ibss.presp, | 1159 | presp = rcu_dereference_protected(ifibss->presp, |
| 1157 | lockdep_is_held(&sdata->u.ibss.mtx)); | 1160 | lockdep_is_held(&sdata->u.ibss.mtx)); |
| 1158 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); | 1161 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); |
| 1159 | sdata->vif.bss_conf.ibss_joined = false; | 1162 | sdata->vif.bss_conf.ibss_joined = false; |
| 1160 | sdata->vif.bss_conf.ibss_creator = false; | 1163 | sdata->vif.bss_conf.ibss_creator = false; |
| 1161 | sdata->vif.bss_conf.enable_beacon = false; | 1164 | sdata->vif.bss_conf.enable_beacon = false; |
| 1165 | sdata->vif.bss_conf.ssid_len = 0; | ||
| 1162 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1166 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
| 1163 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 1167 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
| 1164 | BSS_CHANGED_IBSS); | 1168 | BSS_CHANGED_IBSS); |
| 1165 | synchronize_rcu(); | 1169 | synchronize_rcu(); |
| 1166 | kfree_skb(skb); | 1170 | kfree(presp); |
| 1167 | 1171 | ||
| 1168 | skb_queue_purge(&sdata->skb_queue); | 1172 | skb_queue_purge(&sdata->skb_queue); |
| 1169 | 1173 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0b09716d22ad..158e6eb188d3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -156,6 +156,7 @@ struct ieee80211_tx_data { | |||
| 156 | struct ieee80211_sub_if_data *sdata; | 156 | struct ieee80211_sub_if_data *sdata; |
| 157 | struct sta_info *sta; | 157 | struct sta_info *sta; |
| 158 | struct ieee80211_key *key; | 158 | struct ieee80211_key *key; |
| 159 | struct ieee80211_tx_rate rate; | ||
| 159 | 160 | ||
| 160 | unsigned int flags; | 161 | unsigned int flags; |
| 161 | }; | 162 | }; |
| @@ -443,7 +444,7 @@ struct ieee80211_if_managed { | |||
| 443 | 444 | ||
| 444 | u8 use_4addr; | 445 | u8 use_4addr; |
| 445 | 446 | ||
| 446 | u8 p2p_noa_index; | 447 | s16 p2p_noa_index; |
| 447 | 448 | ||
| 448 | /* Signal strength from the last Beacon frame in the current BSS. */ | 449 | /* Signal strength from the last Beacon frame in the current BSS. */ |
| 449 | int last_beacon_signal; | 450 | int last_beacon_signal; |
| @@ -509,8 +510,7 @@ struct ieee80211_if_ibss { | |||
| 509 | 510 | ||
| 510 | unsigned long ibss_join_req; | 511 | unsigned long ibss_join_req; |
| 511 | /* probe response/beacon for IBSS */ | 512 | /* probe response/beacon for IBSS */ |
| 512 | struct sk_buff __rcu *presp; | 513 | struct beacon_data __rcu *presp; |
| 513 | struct sk_buff *skb; | ||
| 514 | 514 | ||
| 515 | spinlock_t incomplete_lock; | 515 | spinlock_t incomplete_lock; |
| 516 | struct list_head incomplete_stations; | 516 | struct list_head incomplete_stations; |
| @@ -741,6 +741,8 @@ struct ieee80211_sub_if_data { | |||
| 741 | 741 | ||
| 742 | /* bitmap of allowed (non-MCS) rate indexes for rate control */ | 742 | /* bitmap of allowed (non-MCS) rate indexes for rate control */ |
| 743 | u32 rc_rateidx_mask[IEEE80211_NUM_BANDS]; | 743 | u32 rc_rateidx_mask[IEEE80211_NUM_BANDS]; |
| 744 | |||
| 745 | bool rc_has_mcs_mask[IEEE80211_NUM_BANDS]; | ||
| 744 | u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN]; | 746 | u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN]; |
| 745 | 747 | ||
| 746 | union { | 748 | union { |
| @@ -1021,10 +1023,9 @@ struct ieee80211_local { | |||
| 1021 | enum mac80211_scan_state next_scan_state; | 1023 | enum mac80211_scan_state next_scan_state; |
| 1022 | struct delayed_work scan_work; | 1024 | struct delayed_work scan_work; |
| 1023 | struct ieee80211_sub_if_data __rcu *scan_sdata; | 1025 | struct ieee80211_sub_if_data __rcu *scan_sdata; |
| 1024 | struct ieee80211_channel *csa_channel; | 1026 | struct cfg80211_chan_def csa_chandef; |
| 1025 | /* For backward compatibility only -- do not use */ | 1027 | /* For backward compatibility only -- do not use */ |
| 1026 | struct ieee80211_channel *_oper_channel; | 1028 | struct cfg80211_chan_def _oper_chandef; |
| 1027 | enum nl80211_channel_type _oper_channel_type; | ||
| 1028 | 1029 | ||
| 1029 | /* Temporary remain-on-channel for off-channel operations */ | 1030 | /* Temporary remain-on-channel for off-channel operations */ |
| 1030 | struct ieee80211_channel *tmp_channel; | 1031 | struct ieee80211_channel *tmp_channel; |
| @@ -1160,11 +1161,8 @@ struct ieee802_11_elems { | |||
| 1160 | /* pointers to IEs */ | 1161 | /* pointers to IEs */ |
| 1161 | const u8 *ssid; | 1162 | const u8 *ssid; |
| 1162 | const u8 *supp_rates; | 1163 | const u8 *supp_rates; |
| 1163 | const u8 *fh_params; | ||
| 1164 | const u8 *ds_params; | 1164 | const u8 *ds_params; |
| 1165 | const u8 *cf_params; | ||
| 1166 | const struct ieee80211_tim_ie *tim; | 1165 | const struct ieee80211_tim_ie *tim; |
| 1167 | const u8 *ibss_params; | ||
| 1168 | const u8 *challenge; | 1166 | const u8 *challenge; |
| 1169 | const u8 *rsn; | 1167 | const u8 *rsn; |
| 1170 | const u8 *erp_info; | 1168 | const u8 *erp_info; |
| @@ -1184,23 +1182,20 @@ struct ieee802_11_elems { | |||
| 1184 | const u8 *perr; | 1182 | const u8 *perr; |
| 1185 | const struct ieee80211_rann_ie *rann; | 1183 | const struct ieee80211_rann_ie *rann; |
| 1186 | const struct ieee80211_channel_sw_ie *ch_switch_ie; | 1184 | const struct ieee80211_channel_sw_ie *ch_switch_ie; |
| 1185 | const struct ieee80211_ext_chansw_ie *ext_chansw_ie; | ||
| 1186 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; | ||
| 1187 | const u8 *country_elem; | 1187 | const u8 *country_elem; |
| 1188 | const u8 *pwr_constr_elem; | 1188 | const u8 *pwr_constr_elem; |
| 1189 | const u8 *quiet_elem; /* first quite element */ | 1189 | const struct ieee80211_timeout_interval_ie *timeout_int; |
| 1190 | const u8 *timeout_int; | ||
| 1191 | const u8 *opmode_notif; | 1190 | const u8 *opmode_notif; |
| 1191 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | ||
| 1192 | 1192 | ||
| 1193 | /* length of them, respectively */ | 1193 | /* length of them, respectively */ |
| 1194 | u8 ssid_len; | 1194 | u8 ssid_len; |
| 1195 | u8 supp_rates_len; | 1195 | u8 supp_rates_len; |
| 1196 | u8 fh_params_len; | ||
| 1197 | u8 ds_params_len; | ||
| 1198 | u8 cf_params_len; | ||
| 1199 | u8 tim_len; | 1196 | u8 tim_len; |
| 1200 | u8 ibss_params_len; | ||
| 1201 | u8 challenge_len; | 1197 | u8 challenge_len; |
| 1202 | u8 rsn_len; | 1198 | u8 rsn_len; |
| 1203 | u8 erp_info_len; | ||
| 1204 | u8 ext_supp_rates_len; | 1199 | u8 ext_supp_rates_len; |
| 1205 | u8 wmm_info_len; | 1200 | u8 wmm_info_len; |
| 1206 | u8 wmm_param_len; | 1201 | u8 wmm_param_len; |
| @@ -1210,9 +1205,6 @@ struct ieee802_11_elems { | |||
| 1210 | u8 prep_len; | 1205 | u8 prep_len; |
| 1211 | u8 perr_len; | 1206 | u8 perr_len; |
| 1212 | u8 country_elem_len; | 1207 | u8 country_elem_len; |
| 1213 | u8 quiet_elem_len; | ||
| 1214 | u8 num_of_quiet_elem; /* can be more the one */ | ||
| 1215 | u8 timeout_int_len; | ||
| 1216 | 1208 | ||
| 1217 | /* whether a parse error occurred while retrieving these elements */ | 1209 | /* whether a parse error occurred while retrieving these elements */ |
| 1218 | bool parse_error; | 1210 | bool parse_error; |
| @@ -1267,10 +1259,6 @@ void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata); | |||
| 1267 | int ieee80211_max_network_latency(struct notifier_block *nb, | 1259 | int ieee80211_max_network_latency(struct notifier_block *nb, |
| 1268 | unsigned long data, void *dummy); | 1260 | unsigned long data, void *dummy); |
| 1269 | int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata); | 1261 | int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata); |
| 1270 | void | ||
| 1271 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | ||
| 1272 | const struct ieee80211_channel_sw_ie *sw_elem, | ||
| 1273 | struct ieee80211_bss *bss, u64 timestamp); | ||
| 1274 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); | 1262 | void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); |
| 1275 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 1263 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
| 1276 | struct sk_buff *skb); | 1264 | struct sk_buff *skb); |
| @@ -1330,7 +1318,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); | |||
| 1330 | void ieee80211_offchannel_return(struct ieee80211_local *local); | 1318 | void ieee80211_offchannel_return(struct ieee80211_local *local); |
| 1331 | void ieee80211_roc_setup(struct ieee80211_local *local); | 1319 | void ieee80211_roc_setup(struct ieee80211_local *local); |
| 1332 | void ieee80211_start_next_roc(struct ieee80211_local *local); | 1320 | void ieee80211_start_next_roc(struct ieee80211_local *local); |
| 1333 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | 1321 | void ieee80211_roc_purge(struct ieee80211_local *local, |
| 1322 | struct ieee80211_sub_if_data *sdata); | ||
| 1334 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free); | 1323 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free); |
| 1335 | void ieee80211_sw_roc_work(struct work_struct *work); | 1324 | void ieee80211_sw_roc_work(struct work_struct *work); |
| 1336 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | 1325 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); |
| @@ -1351,6 +1340,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | |||
| 1351 | const int offset); | 1340 | const int offset); |
| 1352 | int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); | 1341 | int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); |
| 1353 | void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); | 1342 | void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); |
| 1343 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local); | ||
| 1344 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local); | ||
| 1354 | 1345 | ||
| 1355 | bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); | 1346 | bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); |
| 1356 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); | 1347 | void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); |
| @@ -1505,11 +1496,15 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | |||
| 1505 | ieee80211_tx_skb_tid(sdata, skb, 7); | 1496 | ieee80211_tx_skb_tid(sdata, skb, 7); |
| 1506 | } | 1497 | } |
| 1507 | 1498 | ||
| 1508 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1499 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, |
| 1509 | struct ieee802_11_elems *elems); | ||
| 1510 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | ||
| 1511 | struct ieee802_11_elems *elems, | 1500 | struct ieee802_11_elems *elems, |
| 1512 | u64 filter, u32 crc); | 1501 | u64 filter, u32 crc); |
| 1502 | static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | ||
| 1503 | struct ieee802_11_elems *elems) | ||
| 1504 | { | ||
| 1505 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); | ||
| 1506 | } | ||
| 1507 | |||
| 1513 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 1508 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
| 1514 | enum ieee80211_band band); | 1509 | enum ieee80211_band band); |
| 1515 | 1510 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e8a260f53c16..60f1ce5e5e52 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Interface handling (except master interface) | 2 | * Interface handling |
| 3 | * | 3 | * |
| 4 | * Copyright 2002-2005, Instant802 Networks, Inc. | 4 | * Copyright 2002-2005, Instant802 Networks, Inc. |
| 5 | * Copyright 2005-2006, Devicescape Software, Inc. | 5 | * Copyright 2005-2006, Devicescape Software, Inc. |
| @@ -357,7 +357,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) | |||
| 357 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; | 357 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 360 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local) |
| 361 | { | 361 | { |
| 362 | struct ieee80211_sub_if_data *sdata; | 362 | struct ieee80211_sub_if_data *sdata; |
| 363 | int ret; | 363 | int ret; |
| @@ -410,7 +410,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
| 410 | return 0; | 410 | return 0; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 413 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local) |
| 414 | { | 414 | { |
| 415 | struct ieee80211_sub_if_data *sdata; | 415 | struct ieee80211_sub_if_data *sdata; |
| 416 | 416 | ||
| @@ -595,7 +595,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
| 595 | case NL80211_IFTYPE_P2P_DEVICE: | 595 | case NL80211_IFTYPE_P2P_DEVICE: |
| 596 | break; | 596 | break; |
| 597 | default: | 597 | default: |
| 598 | netif_carrier_on(dev); | 598 | /* not reached */ |
| 599 | WARN_ON(1); | ||
| 599 | } | 600 | } |
| 600 | 601 | ||
| 601 | /* | 602 | /* |
| @@ -652,8 +653,28 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
| 652 | 653 | ||
| 653 | ieee80211_recalc_ps(local, -1); | 654 | ieee80211_recalc_ps(local, -1); |
| 654 | 655 | ||
| 655 | if (dev) | 656 | if (dev) { |
| 656 | netif_tx_start_all_queues(dev); | 657 | unsigned long flags; |
| 658 | int n_acs = IEEE80211_NUM_ACS; | ||
| 659 | int ac; | ||
| 660 | |||
| 661 | if (local->hw.queues < IEEE80211_NUM_ACS) | ||
| 662 | n_acs = 1; | ||
| 663 | |||
| 664 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
| 665 | if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE || | ||
| 666 | (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 && | ||
| 667 | skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) { | ||
| 668 | for (ac = 0; ac < n_acs; ac++) { | ||
| 669 | int ac_queue = sdata->vif.hw_queue[ac]; | ||
| 670 | |||
| 671 | if (local->queue_stop_reasons[ac_queue] == 0 && | ||
| 672 | skb_queue_empty(&local->pending[ac_queue])) | ||
| 673 | netif_start_subqueue(dev, ac); | ||
| 674 | } | ||
| 675 | } | ||
| 676 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
| 677 | } | ||
| 657 | 678 | ||
| 658 | return 0; | 679 | return 0; |
| 659 | err_del_interface: | 680 | err_del_interface: |
| @@ -707,7 +728,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 707 | if (sdata->dev) | 728 | if (sdata->dev) |
| 708 | netif_tx_stop_all_queues(sdata->dev); | 729 | netif_tx_stop_all_queues(sdata->dev); |
| 709 | 730 | ||
| 710 | ieee80211_roc_purge(sdata); | 731 | ieee80211_roc_purge(local, sdata); |
| 711 | 732 | ||
| 712 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 733 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
| 713 | ieee80211_mgd_stop(sdata); | 734 | ieee80211_mgd_stop(sdata); |
| @@ -732,12 +753,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 732 | WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || | 753 | WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) || |
| 733 | (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); | 754 | (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)); |
| 734 | 755 | ||
| 735 | /* | 756 | /* don't count this interface for promisc/allmulti while it is down */ |
| 736 | * Don't count this interface for promisc/allmulti while it | ||
| 737 | * is down. dev_mc_unsync() will invoke set_multicast_list | ||
| 738 | * on the master interface which will sync these down to the | ||
| 739 | * hardware as filter flags. | ||
| 740 | */ | ||
| 741 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | 757 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) |
| 742 | atomic_dec(&local->iff_allmultis); | 758 | atomic_dec(&local->iff_allmultis); |
| 743 | 759 | ||
| @@ -758,8 +774,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 758 | sdata->dev->addr_len); | 774 | sdata->dev->addr_len); |
| 759 | spin_unlock_bh(&local->filter_lock); | 775 | spin_unlock_bh(&local->filter_lock); |
| 760 | netif_addr_unlock_bh(sdata->dev); | 776 | netif_addr_unlock_bh(sdata->dev); |
| 761 | |||
| 762 | ieee80211_configure_filter(local); | ||
| 763 | } | 777 | } |
| 764 | 778 | ||
| 765 | del_timer_sync(&local->dynamic_ps_timer); | 779 | del_timer_sync(&local->dynamic_ps_timer); |
| @@ -770,6 +784,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 770 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | 784 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); |
| 771 | 785 | ||
| 772 | if (sdata->wdev.cac_started) { | 786 | if (sdata->wdev.cac_started) { |
| 787 | WARN_ON(local->suspended); | ||
| 773 | mutex_lock(&local->iflist_mtx); | 788 | mutex_lock(&local->iflist_mtx); |
| 774 | ieee80211_vif_release_channel(sdata); | 789 | ieee80211_vif_release_channel(sdata); |
| 775 | mutex_unlock(&local->iflist_mtx); | 790 | mutex_unlock(&local->iflist_mtx); |
| @@ -820,14 +835,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 820 | if (local->monitors == 0) { | 835 | if (local->monitors == 0) { |
| 821 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; | 836 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; |
| 822 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; | 837 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
| 823 | ieee80211_del_virtual_monitor(local); | ||
| 824 | } | 838 | } |
| 825 | 839 | ||
| 826 | ieee80211_adjust_monitor_flags(sdata, -1); | 840 | ieee80211_adjust_monitor_flags(sdata, -1); |
| 827 | ieee80211_configure_filter(local); | ||
| 828 | mutex_lock(&local->mtx); | ||
| 829 | ieee80211_recalc_idle(local); | ||
| 830 | mutex_unlock(&local->mtx); | ||
| 831 | break; | 841 | break; |
| 832 | case NL80211_IFTYPE_P2P_DEVICE: | 842 | case NL80211_IFTYPE_P2P_DEVICE: |
| 833 | /* relies on synchronize_rcu() below */ | 843 | /* relies on synchronize_rcu() below */ |
| @@ -840,11 +850,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 840 | * | 850 | * |
| 841 | * sta_info_flush_cleanup() requires rcu_barrier() | 851 | * sta_info_flush_cleanup() requires rcu_barrier() |
| 842 | * first to wait for the station call_rcu() calls | 852 | * first to wait for the station call_rcu() calls |
| 843 | * to complete, here we need at least sychronize_rcu() | 853 | * to complete, and we also need synchronize_rcu() |
| 844 | * it to wait for the RX path in case it is using the | 854 | * to wait for the RX path in case it is using the |
| 845 | * interface and enqueuing frames at this very time on | 855 | * interface and enqueuing frames at this very time on |
| 846 | * another CPU. | 856 | * another CPU. |
| 847 | */ | 857 | */ |
| 858 | synchronize_rcu(); | ||
| 848 | rcu_barrier(); | 859 | rcu_barrier(); |
| 849 | sta_info_flush_cleanup(sdata); | 860 | sta_info_flush_cleanup(sdata); |
| 850 | 861 | ||
| @@ -857,27 +868,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 857 | /* fall through */ | 868 | /* fall through */ |
| 858 | case NL80211_IFTYPE_AP: | 869 | case NL80211_IFTYPE_AP: |
| 859 | skb_queue_purge(&sdata->skb_queue); | 870 | skb_queue_purge(&sdata->skb_queue); |
| 860 | |||
| 861 | if (going_down) | ||
| 862 | drv_remove_interface(local, sdata); | ||
| 863 | } | 871 | } |
| 864 | 872 | ||
| 865 | sdata->bss = NULL; | 873 | sdata->bss = NULL; |
| 866 | 874 | ||
| 867 | ieee80211_recalc_ps(local, -1); | ||
| 868 | |||
| 869 | if (local->open_count == 0) { | ||
| 870 | ieee80211_clear_tx_pending(local); | ||
| 871 | ieee80211_stop_device(local); | ||
| 872 | |||
| 873 | /* no reconfiguring after stop! */ | ||
| 874 | hw_reconf_flags = 0; | ||
| 875 | } | ||
| 876 | |||
| 877 | /* do after stop to avoid reconfiguring when we stop anyway */ | ||
| 878 | if (hw_reconf_flags) | ||
| 879 | ieee80211_hw_config(local, hw_reconf_flags); | ||
| 880 | |||
| 881 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 875 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
| 882 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | 876 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { |
| 883 | skb_queue_walk_safe(&local->pending[i], skb, tmp) { | 877 | skb_queue_walk_safe(&local->pending[i], skb, tmp) { |
| @@ -890,7 +884,54 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 890 | } | 884 | } |
| 891 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 885 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
| 892 | 886 | ||
| 893 | if (local->monitors == local->open_count && local->monitors > 0) | 887 | if (local->open_count == 0) |
| 888 | ieee80211_clear_tx_pending(local); | ||
| 889 | |||
| 890 | /* | ||
| 891 | * If the interface goes down while suspended, presumably because | ||
| 892 | * the device was unplugged and that happens before our resume, | ||
| 893 | * then the driver is already unconfigured and the remainder of | ||
| 894 | * this function isn't needed. | ||
| 895 | * XXX: what about WoWLAN? If the device has software state, e.g. | ||
| 896 | * memory allocated, it might expect teardown commands from | ||
| 897 | * mac80211 here? | ||
| 898 | */ | ||
| 899 | if (local->suspended) { | ||
| 900 | WARN_ON(local->wowlan); | ||
| 901 | WARN_ON(rtnl_dereference(local->monitor_sdata)); | ||
| 902 | return; | ||
| 903 | } | ||
| 904 | |||
| 905 | switch (sdata->vif.type) { | ||
| 906 | case NL80211_IFTYPE_AP_VLAN: | ||
| 907 | break; | ||
| 908 | case NL80211_IFTYPE_MONITOR: | ||
| 909 | if (local->monitors == 0) | ||
| 910 | ieee80211_del_virtual_monitor(local); | ||
| 911 | |||
| 912 | mutex_lock(&local->mtx); | ||
| 913 | ieee80211_recalc_idle(local); | ||
| 914 | mutex_unlock(&local->mtx); | ||
| 915 | break; | ||
| 916 | default: | ||
| 917 | if (going_down) | ||
| 918 | drv_remove_interface(local, sdata); | ||
| 919 | } | ||
| 920 | |||
| 921 | ieee80211_recalc_ps(local, -1); | ||
| 922 | |||
| 923 | if (local->open_count == 0) { | ||
| 924 | ieee80211_stop_device(local); | ||
| 925 | |||
| 926 | /* no reconfiguring after stop! */ | ||
| 927 | return; | ||
| 928 | } | ||
| 929 | |||
| 930 | /* do after stop to avoid reconfiguring when we stop anyway */ | ||
| 931 | ieee80211_configure_filter(local); | ||
| 932 | ieee80211_hw_config(local, hw_reconf_flags); | ||
| 933 | |||
| 934 | if (local->monitors == local->open_count) | ||
| 894 | ieee80211_add_virtual_monitor(local); | 935 | ieee80211_add_virtual_monitor(local); |
| 895 | } | 936 | } |
| 896 | 937 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c6f81ecc36a1..8a7bfc47d577 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -95,42 +95,47 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
| 95 | static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | 95 | static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) |
| 96 | { | 96 | { |
| 97 | struct ieee80211_sub_if_data *sdata; | 97 | struct ieee80211_sub_if_data *sdata; |
| 98 | struct ieee80211_channel *chan; | 98 | struct cfg80211_chan_def chandef = {}; |
| 99 | u32 changed = 0; | 99 | u32 changed = 0; |
| 100 | int power; | 100 | int power; |
| 101 | enum nl80211_channel_type channel_type; | ||
| 102 | u32 offchannel_flag; | 101 | u32 offchannel_flag; |
| 103 | 102 | ||
| 104 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 103 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
| 104 | |||
| 105 | if (local->scan_channel) { | 105 | if (local->scan_channel) { |
| 106 | chan = local->scan_channel; | 106 | chandef.chan = local->scan_channel; |
| 107 | /* If scanning on oper channel, use whatever channel-type | 107 | /* If scanning on oper channel, use whatever channel-type |
| 108 | * is currently in use. | 108 | * is currently in use. |
| 109 | */ | 109 | */ |
| 110 | if (chan == local->_oper_channel) | 110 | if (chandef.chan == local->_oper_chandef.chan) { |
| 111 | channel_type = local->_oper_channel_type; | 111 | chandef = local->_oper_chandef; |
| 112 | else | 112 | } else { |
| 113 | channel_type = NL80211_CHAN_NO_HT; | 113 | chandef.width = NL80211_CHAN_WIDTH_20_NOHT; |
| 114 | chandef.center_freq1 = chandef.chan->center_freq; | ||
| 115 | } | ||
| 114 | } else if (local->tmp_channel) { | 116 | } else if (local->tmp_channel) { |
| 115 | chan = local->tmp_channel; | 117 | chandef.chan = local->tmp_channel; |
| 116 | channel_type = NL80211_CHAN_NO_HT; | 118 | chandef.width = NL80211_CHAN_WIDTH_20_NOHT; |
| 117 | } else { | 119 | chandef.center_freq1 = chandef.chan->center_freq; |
| 118 | chan = local->_oper_channel; | 120 | } else |
| 119 | channel_type = local->_oper_channel_type; | 121 | chandef = local->_oper_chandef; |
| 120 | } | 122 | |
| 121 | 123 | WARN(!cfg80211_chandef_valid(&chandef), | |
| 122 | if (chan != local->_oper_channel || | 124 | "control:%d MHz width:%d center: %d/%d MHz", |
| 123 | channel_type != local->_oper_channel_type) | 125 | chandef.chan->center_freq, chandef.width, |
| 126 | chandef.center_freq1, chandef.center_freq2); | ||
| 127 | |||
| 128 | if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef)) | ||
| 124 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 129 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; |
| 125 | else | 130 | else |
| 126 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | 131 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; |
| 127 | 132 | ||
| 128 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 133 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
| 129 | 134 | ||
| 130 | if (offchannel_flag || chan != local->hw.conf.channel || | 135 | if (offchannel_flag || |
| 131 | channel_type != local->hw.conf.channel_type) { | 136 | !cfg80211_chandef_identical(&local->hw.conf.chandef, |
| 132 | local->hw.conf.channel = chan; | 137 | &local->_oper_chandef)) { |
| 133 | local->hw.conf.channel_type = channel_type; | 138 | local->hw.conf.chandef = chandef; |
| 134 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | 139 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; |
| 135 | } | 140 | } |
| 136 | 141 | ||
| @@ -146,7 +151,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | |||
| 146 | changed |= IEEE80211_CONF_CHANGE_SMPS; | 151 | changed |= IEEE80211_CONF_CHANGE_SMPS; |
| 147 | } | 152 | } |
| 148 | 153 | ||
| 149 | power = chan->max_power; | 154 | power = chandef.chan->max_power; |
| 150 | 155 | ||
| 151 | rcu_read_lock(); | 156 | rcu_read_lock(); |
| 152 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 157 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
| @@ -587,6 +592,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
| 587 | IEEE80211_RADIOTAP_MCS_HAVE_BW; | 592 | IEEE80211_RADIOTAP_MCS_HAVE_BW; |
| 588 | local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | | 593 | local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | |
| 589 | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; | 594 | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; |
| 595 | local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
| 596 | local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
| 590 | local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; | 597 | local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; |
| 591 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; | 598 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; |
| 592 | wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; | 599 | wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; |
| @@ -661,6 +668,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 661 | int channels, max_bitrates; | 668 | int channels, max_bitrates; |
| 662 | bool supp_ht, supp_vht; | 669 | bool supp_ht, supp_vht; |
| 663 | netdev_features_t feature_whitelist; | 670 | netdev_features_t feature_whitelist; |
| 671 | struct cfg80211_chan_def dflt_chandef = {}; | ||
| 664 | static const u32 cipher_suites[] = { | 672 | static const u32 cipher_suites[] = { |
| 665 | /* keep WEP first, it may be removed below */ | 673 | /* keep WEP first, it may be removed below */ |
| 666 | WLAN_CIPHER_SUITE_WEP40, | 674 | WLAN_CIPHER_SUITE_WEP40, |
| @@ -738,15 +746,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 738 | sband = local->hw.wiphy->bands[band]; | 746 | sband = local->hw.wiphy->bands[band]; |
| 739 | if (!sband) | 747 | if (!sband) |
| 740 | continue; | 748 | continue; |
| 741 | if (!local->use_chanctx && !local->_oper_channel) { | 749 | |
| 750 | if (!dflt_chandef.chan) { | ||
| 751 | cfg80211_chandef_create(&dflt_chandef, | ||
| 752 | &sband->channels[0], | ||
| 753 | NL80211_CHAN_NO_HT); | ||
| 742 | /* init channel we're on */ | 754 | /* init channel we're on */ |
| 743 | local->hw.conf.channel = | 755 | if (!local->use_chanctx && !local->_oper_chandef.chan) { |
| 744 | local->_oper_channel = &sband->channels[0]; | 756 | local->hw.conf.chandef = dflt_chandef; |
| 745 | local->hw.conf.channel_type = NL80211_CHAN_NO_HT; | 757 | local->_oper_chandef = dflt_chandef; |
| 758 | } | ||
| 759 | local->monitor_chandef = dflt_chandef; | ||
| 746 | } | 760 | } |
| 747 | cfg80211_chandef_create(&local->monitor_chandef, | 761 | |
| 748 | &sband->channels[0], | ||
| 749 | NL80211_CHAN_NO_HT); | ||
| 750 | channels += sband->n_channels; | 762 | channels += sband->n_channels; |
| 751 | 763 | ||
| 752 | if (max_bitrates < sband->n_bitrates) | 764 | if (max_bitrates < sband->n_bitrates) |
| @@ -829,22 +841,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 829 | if (supp_ht) | 841 | if (supp_ht) |
| 830 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); | 842 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); |
| 831 | 843 | ||
| 832 | if (supp_vht) { | 844 | if (supp_vht) |
| 833 | local->scan_ies_len += | 845 | local->scan_ies_len += |
| 834 | 2 + sizeof(struct ieee80211_vht_cap); | 846 | 2 + sizeof(struct ieee80211_vht_cap); |
| 835 | 847 | ||
| 836 | /* | ||
| 837 | * (for now at least), drivers wanting to use VHT must | ||
| 838 | * support channel contexts, as they contain all the | ||
| 839 | * necessary VHT information and the global hw config | ||
| 840 | * doesn't (yet) | ||
| 841 | */ | ||
| 842 | if (WARN_ON(!local->use_chanctx)) { | ||
| 843 | result = -EINVAL; | ||
| 844 | goto fail_wiphy_register; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | |||
| 848 | if (!local->ops->hw_scan) { | 848 | if (!local->ops->hw_scan) { |
| 849 | /* For hw_scan, driver needs to set these up. */ | 849 | /* For hw_scan, driver needs to set these up. */ |
| 850 | local->hw.wiphy->max_scan_ssids = 4; | 850 | local->hw.wiphy->max_scan_ssids = 4; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 123a300cef57..6952760881c8 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -838,7 +838,7 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata, | |||
| 838 | if (baselen > len) | 838 | if (baselen > len) |
| 839 | return; | 839 | return; |
| 840 | 840 | ||
| 841 | ieee802_11_parse_elems(pos, len - baselen, &elems); | 841 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); |
| 842 | 842 | ||
| 843 | /* 802.11-2012 10.1.4.3.2 */ | 843 | /* 802.11-2012 10.1.4.3.2 */ |
| 844 | if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && | 844 | if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && |
| @@ -899,7 +899,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
| 899 | return; | 899 | return; |
| 900 | 900 | ||
| 901 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 901 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
| 902 | &elems); | 902 | false, &elems); |
| 903 | 903 | ||
| 904 | /* ignore non-mesh or secure / unsecure mismatch */ | 904 | /* ignore non-mesh or secure / unsecure mismatch */ |
| 905 | if ((!elems.mesh_id || !elems.mesh_config) || | 905 | if ((!elems.mesh_id || !elems.mesh_config) || |
| @@ -907,7 +907,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
| 907 | (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) | 907 | (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) |
| 908 | return; | 908 | return; |
| 909 | 909 | ||
| 910 | if (elems.ds_params && elems.ds_params_len == 1) | 910 | if (elems.ds_params) |
| 911 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); | 911 | freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); |
| 912 | else | 912 | else |
| 913 | freq = rx_status->freq; | 913 | freq = rx_status->freq; |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 6ffabbe99c46..da158774eebb 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
| @@ -275,7 +275,8 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); | |||
| 275 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata); | 275 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata); |
| 276 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | 276 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, |
| 277 | struct ieee80211_mgmt *mgmt, size_t len); | 277 | struct ieee80211_mgmt *mgmt, size_t len); |
| 278 | int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); | 278 | struct mesh_path * |
| 279 | mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); | ||
| 279 | 280 | ||
| 280 | int mesh_path_add_gate(struct mesh_path *mpath); | 281 | int mesh_path_add_gate(struct mesh_path *mpath); |
| 281 | int mesh_path_send_to_gates(struct mesh_path *mpath); | 282 | int mesh_path_send_to_gates(struct mesh_path *mpath); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index bdb8d3b14587..486819cd02cd 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -144,7 +144,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
| 144 | *pos++ = WLAN_EID_PREQ; | 144 | *pos++ = WLAN_EID_PREQ; |
| 145 | break; | 145 | break; |
| 146 | case MPATH_PREP: | 146 | case MPATH_PREP: |
| 147 | mhwmp_dbg(sdata, "sending PREP to %pM\n", target); | 147 | mhwmp_dbg(sdata, "sending PREP to %pM\n", orig_addr); |
| 148 | ie_len = 31; | 148 | ie_len = 31; |
| 149 | pos = skb_put(skb, 2 + ie_len); | 149 | pos = skb_put(skb, 2 + ie_len); |
| 150 | *pos++ = WLAN_EID_PREP; | 150 | *pos++ = WLAN_EID_PREP; |
| @@ -445,9 +445,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | |||
| 445 | } | 445 | } |
| 446 | } | 446 | } |
| 447 | } else { | 447 | } else { |
| 448 | mesh_path_add(sdata, orig_addr); | 448 | mpath = mesh_path_add(sdata, orig_addr); |
| 449 | mpath = mesh_path_lookup(sdata, orig_addr); | 449 | if (IS_ERR(mpath)) { |
| 450 | if (!mpath) { | ||
| 451 | rcu_read_unlock(); | 450 | rcu_read_unlock(); |
| 452 | return 0; | 451 | return 0; |
| 453 | } | 452 | } |
| @@ -486,9 +485,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | |||
| 486 | (last_hop_metric > mpath->metric))) | 485 | (last_hop_metric > mpath->metric))) |
| 487 | fresh_info = false; | 486 | fresh_info = false; |
| 488 | } else { | 487 | } else { |
| 489 | mesh_path_add(sdata, ta); | 488 | mpath = mesh_path_add(sdata, ta); |
| 490 | mpath = mesh_path_lookup(sdata, ta); | 489 | if (IS_ERR(mpath)) { |
| 491 | if (!mpath) { | ||
| 492 | rcu_read_unlock(); | 490 | rcu_read_unlock(); |
| 493 | return 0; | 491 | return 0; |
| 494 | } | 492 | } |
| @@ -661,7 +659,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 661 | u32 target_sn, orig_sn, lifetime; | 659 | u32 target_sn, orig_sn, lifetime; |
| 662 | 660 | ||
| 663 | mhwmp_dbg(sdata, "received PREP from %pM\n", | 661 | mhwmp_dbg(sdata, "received PREP from %pM\n", |
| 664 | PREP_IE_ORIG_ADDR(prep_elem)); | 662 | PREP_IE_TARGET_ADDR(prep_elem)); |
| 665 | 663 | ||
| 666 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); | 664 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); |
| 667 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) | 665 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) |
| @@ -804,9 +802,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 804 | 802 | ||
| 805 | mpath = mesh_path_lookup(sdata, orig_addr); | 803 | mpath = mesh_path_lookup(sdata, orig_addr); |
| 806 | if (!mpath) { | 804 | if (!mpath) { |
| 807 | mesh_path_add(sdata, orig_addr); | 805 | mpath = mesh_path_add(sdata, orig_addr); |
| 808 | mpath = mesh_path_lookup(sdata, orig_addr); | 806 | if (IS_ERR(mpath)) { |
| 809 | if (!mpath) { | ||
| 810 | rcu_read_unlock(); | 807 | rcu_read_unlock(); |
| 811 | sdata->u.mesh.mshstats.dropped_frames_no_route++; | 808 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
| 812 | return; | 809 | return; |
| @@ -883,7 +880,7 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | |||
| 883 | 880 | ||
| 884 | baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; | 881 | baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; |
| 885 | ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, | 882 | ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, |
| 886 | len - baselen, &elems); | 883 | len - baselen, false, &elems); |
| 887 | 884 | ||
| 888 | if (elems.preq) { | 885 | if (elems.preq) { |
| 889 | if (elems.preq_len != 37) | 886 | if (elems.preq_len != 37) |
| @@ -1098,11 +1095,10 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata, | |||
| 1098 | /* no nexthop found, start resolving */ | 1095 | /* no nexthop found, start resolving */ |
| 1099 | mpath = mesh_path_lookup(sdata, target_addr); | 1096 | mpath = mesh_path_lookup(sdata, target_addr); |
| 1100 | if (!mpath) { | 1097 | if (!mpath) { |
| 1101 | mesh_path_add(sdata, target_addr); | 1098 | mpath = mesh_path_add(sdata, target_addr); |
| 1102 | mpath = mesh_path_lookup(sdata, target_addr); | 1099 | if (IS_ERR(mpath)) { |
| 1103 | if (!mpath) { | ||
| 1104 | mesh_path_discard_frame(sdata, skb); | 1100 | mesh_path_discard_frame(sdata, skb); |
| 1105 | err = -ENOSPC; | 1101 | err = PTR_ERR(mpath); |
| 1106 | goto endlookup; | 1102 | goto endlookup; |
| 1107 | } | 1103 | } |
| 1108 | } | 1104 | } |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index dc7c8df40c2c..89aacfd2756d 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
| @@ -493,7 +493,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata) | |||
| 493 | * | 493 | * |
| 494 | * State: the initial state of the new path is set to 0 | 494 | * State: the initial state of the new path is set to 0 |
| 495 | */ | 495 | */ |
| 496 | int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst) | 496 | struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, |
| 497 | const u8 *dst) | ||
| 497 | { | 498 | { |
| 498 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 499 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
| 499 | struct ieee80211_local *local = sdata->local; | 500 | struct ieee80211_local *local = sdata->local; |
| @@ -502,18 +503,33 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst) | |||
| 502 | struct mpath_node *node, *new_node; | 503 | struct mpath_node *node, *new_node; |
| 503 | struct hlist_head *bucket; | 504 | struct hlist_head *bucket; |
| 504 | int grow = 0; | 505 | int grow = 0; |
| 505 | int err = 0; | 506 | int err; |
| 506 | u32 hash_idx; | 507 | u32 hash_idx; |
| 507 | 508 | ||
| 508 | if (ether_addr_equal(dst, sdata->vif.addr)) | 509 | if (ether_addr_equal(dst, sdata->vif.addr)) |
| 509 | /* never add ourselves as neighbours */ | 510 | /* never add ourselves as neighbours */ |
| 510 | return -ENOTSUPP; | 511 | return ERR_PTR(-ENOTSUPP); |
| 511 | 512 | ||
| 512 | if (is_multicast_ether_addr(dst)) | 513 | if (is_multicast_ether_addr(dst)) |
| 513 | return -ENOTSUPP; | 514 | return ERR_PTR(-ENOTSUPP); |
| 514 | 515 | ||
| 515 | if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0) | 516 | if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0) |
| 516 | return -ENOSPC; | 517 | return ERR_PTR(-ENOSPC); |
| 518 | |||
| 519 | read_lock_bh(&pathtbl_resize_lock); | ||
| 520 | tbl = resize_dereference_mesh_paths(); | ||
| 521 | |||
| 522 | hash_idx = mesh_table_hash(dst, sdata, tbl); | ||
| 523 | bucket = &tbl->hash_buckets[hash_idx]; | ||
| 524 | |||
| 525 | spin_lock(&tbl->hashwlock[hash_idx]); | ||
| 526 | |||
| 527 | hlist_for_each_entry(node, bucket, list) { | ||
| 528 | mpath = node->mpath; | ||
| 529 | if (mpath->sdata == sdata && | ||
| 530 | ether_addr_equal(dst, mpath->dst)) | ||
| 531 | goto found; | ||
| 532 | } | ||
| 517 | 533 | ||
| 518 | err = -ENOMEM; | 534 | err = -ENOMEM; |
| 519 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC); | 535 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC); |
| @@ -524,7 +540,6 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst) | |||
| 524 | if (!new_node) | 540 | if (!new_node) |
| 525 | goto err_node_alloc; | 541 | goto err_node_alloc; |
| 526 | 542 | ||
| 527 | read_lock_bh(&pathtbl_resize_lock); | ||
| 528 | memcpy(new_mpath->dst, dst, ETH_ALEN); | 543 | memcpy(new_mpath->dst, dst, ETH_ALEN); |
| 529 | eth_broadcast_addr(new_mpath->rann_snd_addr); | 544 | eth_broadcast_addr(new_mpath->rann_snd_addr); |
| 530 | new_mpath->is_root = false; | 545 | new_mpath->is_root = false; |
| @@ -538,21 +553,6 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst) | |||
| 538 | spin_lock_init(&new_mpath->state_lock); | 553 | spin_lock_init(&new_mpath->state_lock); |
| 539 | init_timer(&new_mpath->timer); | 554 | init_timer(&new_mpath->timer); |
| 540 | 555 | ||
| 541 | tbl = resize_dereference_mesh_paths(); | ||
| 542 | |||
| 543 | hash_idx = mesh_table_hash(dst, sdata, tbl); | ||
| 544 | bucket = &tbl->hash_buckets[hash_idx]; | ||
| 545 | |||
| 546 | spin_lock(&tbl->hashwlock[hash_idx]); | ||
| 547 | |||
| 548 | err = -EEXIST; | ||
| 549 | hlist_for_each_entry(node, bucket, list) { | ||
| 550 | mpath = node->mpath; | ||
| 551 | if (mpath->sdata == sdata && | ||
| 552 | ether_addr_equal(dst, mpath->dst)) | ||
| 553 | goto err_exists; | ||
| 554 | } | ||
| 555 | |||
| 556 | hlist_add_head_rcu(&new_node->list, bucket); | 556 | hlist_add_head_rcu(&new_node->list, bucket); |
| 557 | if (atomic_inc_return(&tbl->entries) >= | 557 | if (atomic_inc_return(&tbl->entries) >= |
| 558 | tbl->mean_chain_len * (tbl->hash_mask + 1)) | 558 | tbl->mean_chain_len * (tbl->hash_mask + 1)) |
| @@ -560,23 +560,23 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst) | |||
| 560 | 560 | ||
| 561 | mesh_paths_generation++; | 561 | mesh_paths_generation++; |
| 562 | 562 | ||
| 563 | spin_unlock(&tbl->hashwlock[hash_idx]); | ||
| 564 | read_unlock_bh(&pathtbl_resize_lock); | ||
| 565 | if (grow) { | 563 | if (grow) { |
| 566 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); | 564 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); |
| 567 | ieee80211_queue_work(&local->hw, &sdata->work); | 565 | ieee80211_queue_work(&local->hw, &sdata->work); |
| 568 | } | 566 | } |
| 569 | return 0; | 567 | mpath = new_mpath; |
| 570 | 568 | found: | |
| 571 | err_exists: | ||
| 572 | spin_unlock(&tbl->hashwlock[hash_idx]); | 569 | spin_unlock(&tbl->hashwlock[hash_idx]); |
| 573 | read_unlock_bh(&pathtbl_resize_lock); | 570 | read_unlock_bh(&pathtbl_resize_lock); |
| 574 | kfree(new_node); | 571 | return mpath; |
| 572 | |||
| 575 | err_node_alloc: | 573 | err_node_alloc: |
| 576 | kfree(new_mpath); | 574 | kfree(new_mpath); |
| 577 | err_path_alloc: | 575 | err_path_alloc: |
| 578 | atomic_dec(&sdata->u.mesh.mpaths); | 576 | atomic_dec(&sdata->u.mesh.mpaths); |
| 579 | return err; | 577 | spin_unlock(&tbl->hashwlock[hash_idx]); |
| 578 | read_unlock_bh(&pathtbl_resize_lock); | ||
| 579 | return ERR_PTR(err); | ||
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | static void mesh_table_free_rcu(struct rcu_head *rcu) | 582 | static void mesh_table_free_rcu(struct rcu_head *rcu) |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 937e06fe8f2a..09bebed99416 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
| @@ -544,8 +544,8 @@ static void mesh_plink_timer(unsigned long data) | |||
| 544 | return; | 544 | return; |
| 545 | } | 545 | } |
| 546 | mpl_dbg(sta->sdata, | 546 | mpl_dbg(sta->sdata, |
| 547 | "Mesh plink timer for %pM fired on state %d\n", | 547 | "Mesh plink timer for %pM fired on state %s\n", |
| 548 | sta->sta.addr, sta->plink_state); | 548 | sta->sta.addr, mplstates[sta->plink_state]); |
| 549 | reason = 0; | 549 | reason = 0; |
| 550 | llid = sta->llid; | 550 | llid = sta->llid; |
| 551 | plid = sta->plid; | 551 | plid = sta->plid; |
| @@ -687,7 +687,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
| 687 | baseaddr += 4; | 687 | baseaddr += 4; |
| 688 | baselen += 4; | 688 | baselen += 4; |
| 689 | } | 689 | } |
| 690 | ieee802_11_parse_elems(baseaddr, len - baselen, &elems); | 690 | ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems); |
| 691 | 691 | ||
| 692 | if (!elems.peering) { | 692 | if (!elems.peering) { |
| 693 | mpl_dbg(sdata, | 693 | mpl_dbg(sdata, |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dec42ab1fa91..29620bfc7a69 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -56,7 +56,10 @@ MODULE_PARM_DESC(max_probe_tries, | |||
| 56 | * probe on beacon miss before declaring the connection lost | 56 | * probe on beacon miss before declaring the connection lost |
| 57 | * default to what we want. | 57 | * default to what we want. |
| 58 | */ | 58 | */ |
| 59 | #define IEEE80211_BEACON_LOSS_COUNT 7 | 59 | static int beacon_loss_count = 7; |
| 60 | module_param(beacon_loss_count, int, 0644); | ||
| 61 | MODULE_PARM_DESC(beacon_loss_count, | ||
| 62 | "Number of beacon intervals before we decide beacon was lost."); | ||
| 60 | 63 | ||
| 61 | /* | 64 | /* |
| 62 | * Time the connection can be idle before we probe | 65 | * Time the connection can be idle before we probe |
| @@ -286,6 +289,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
| 286 | } else { | 289 | } else { |
| 287 | /* 40 MHz (and 80 MHz) must be supported for VHT */ | 290 | /* 40 MHz (and 80 MHz) must be supported for VHT */ |
| 288 | ret = IEEE80211_STA_DISABLE_VHT; | 291 | ret = IEEE80211_STA_DISABLE_VHT; |
| 292 | /* also mark 40 MHz disabled */ | ||
| 293 | ret |= IEEE80211_STA_DISABLE_40MHZ; | ||
| 289 | goto out; | 294 | goto out; |
| 290 | } | 295 | } |
| 291 | 296 | ||
| @@ -300,12 +305,6 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
| 300 | channel->band); | 305 | channel->band); |
| 301 | vht_chandef.center_freq2 = 0; | 306 | vht_chandef.center_freq2 = 0; |
| 302 | 307 | ||
| 303 | if (vht_oper->center_freq_seg2_idx) | ||
| 304 | vht_chandef.center_freq2 = | ||
| 305 | ieee80211_channel_to_frequency( | ||
| 306 | vht_oper->center_freq_seg2_idx, | ||
| 307 | channel->band); | ||
| 308 | |||
| 309 | switch (vht_oper->chan_width) { | 308 | switch (vht_oper->chan_width) { |
| 310 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | 309 | case IEEE80211_VHT_CHANWIDTH_USE_HT: |
| 311 | vht_chandef.width = chandef->width; | 310 | vht_chandef.width = chandef->width; |
| @@ -318,6 +317,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
| 318 | break; | 317 | break; |
| 319 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: | 318 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: |
| 320 | vht_chandef.width = NL80211_CHAN_WIDTH_80P80; | 319 | vht_chandef.width = NL80211_CHAN_WIDTH_80P80; |
| 320 | vht_chandef.center_freq2 = | ||
| 321 | ieee80211_channel_to_frequency( | ||
| 322 | vht_oper->center_freq_seg2_idx, | ||
| 323 | channel->band); | ||
| 321 | break; | 324 | break; |
| 322 | default: | 325 | default: |
| 323 | if (verbose) | 326 | if (verbose) |
| @@ -601,7 +604,6 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, | |||
| 601 | u8 *pos; | 604 | u8 *pos; |
| 602 | u32 cap; | 605 | u32 cap; |
| 603 | struct ieee80211_sta_vht_cap vht_cap; | 606 | struct ieee80211_sta_vht_cap vht_cap; |
| 604 | int i; | ||
| 605 | 607 | ||
| 606 | BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); | 608 | BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); |
| 607 | 609 | ||
| @@ -629,37 +631,6 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, | |||
| 629 | cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE))) | 631 | cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE))) |
| 630 | cap &= ~IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; | 632 | cap &= ~IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; |
| 631 | 633 | ||
| 632 | if (!(ap_vht_cap->vht_cap_info & | ||
| 633 | cpu_to_le32(IEEE80211_VHT_CAP_TXSTBC))) | ||
| 634 | cap &= ~(IEEE80211_VHT_CAP_RXSTBC_1 | | ||
| 635 | IEEE80211_VHT_CAP_RXSTBC_3 | | ||
| 636 | IEEE80211_VHT_CAP_RXSTBC_4); | ||
| 637 | |||
| 638 | for (i = 0; i < 8; i++) { | ||
| 639 | int shift = i * 2; | ||
| 640 | u16 mask = IEEE80211_VHT_MCS_NOT_SUPPORTED << shift; | ||
| 641 | u16 ap_mcs, our_mcs; | ||
| 642 | |||
| 643 | ap_mcs = (le16_to_cpu(ap_vht_cap->supp_mcs.tx_mcs_map) & | ||
| 644 | mask) >> shift; | ||
| 645 | our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) & | ||
| 646 | mask) >> shift; | ||
| 647 | |||
| 648 | if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED) | ||
| 649 | continue; | ||
| 650 | |||
| 651 | switch (ap_mcs) { | ||
| 652 | default: | ||
| 653 | if (our_mcs <= ap_mcs) | ||
| 654 | break; | ||
| 655 | /* fall through */ | ||
| 656 | case IEEE80211_VHT_MCS_NOT_SUPPORTED: | ||
| 657 | vht_cap.vht_mcs.rx_mcs_map &= cpu_to_le16(~mask); | ||
| 658 | vht_cap.vht_mcs.rx_mcs_map |= | ||
| 659 | cpu_to_le16(ap_mcs << shift); | ||
| 660 | } | ||
| 661 | } | ||
| 662 | |||
| 663 | /* reserve and fill IE */ | 634 | /* reserve and fill IE */ |
| 664 | pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); | 635 | pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); |
| 665 | ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); | 636 | ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); |
| @@ -985,6 +956,7 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
| 985 | { | 956 | { |
| 986 | struct ieee80211_sub_if_data *sdata = | 957 | struct ieee80211_sub_if_data *sdata = |
| 987 | container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); | 958 | container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); |
| 959 | struct ieee80211_local *local = sdata->local; | ||
| 988 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 960 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 989 | 961 | ||
| 990 | if (!ieee80211_sdata_running(sdata)) | 962 | if (!ieee80211_sdata_running(sdata)) |
| @@ -994,21 +966,21 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
| 994 | if (!ifmgd->associated) | 966 | if (!ifmgd->associated) |
| 995 | goto out; | 967 | goto out; |
| 996 | 968 | ||
| 997 | sdata->local->_oper_channel = sdata->local->csa_channel; | 969 | local->_oper_chandef = local->csa_chandef; |
| 998 | if (!sdata->local->ops->channel_switch) { | 970 | |
| 971 | if (!local->ops->channel_switch) { | ||
| 999 | /* call "hw_config" only if doing sw channel switch */ | 972 | /* call "hw_config" only if doing sw channel switch */ |
| 1000 | ieee80211_hw_config(sdata->local, | 973 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
| 1001 | IEEE80211_CONF_CHANGE_CHANNEL); | ||
| 1002 | } else { | 974 | } else { |
| 1003 | /* update the device channel directly */ | 975 | /* update the device channel directly */ |
| 1004 | sdata->local->hw.conf.channel = sdata->local->_oper_channel; | 976 | local->hw.conf.chandef = local->_oper_chandef; |
| 1005 | } | 977 | } |
| 1006 | 978 | ||
| 1007 | /* XXX: shouldn't really modify cfg80211-owned data! */ | 979 | /* XXX: shouldn't really modify cfg80211-owned data! */ |
| 1008 | ifmgd->associated->channel = sdata->local->_oper_channel; | 980 | ifmgd->associated->channel = local->_oper_chandef.chan; |
| 1009 | 981 | ||
| 1010 | /* XXX: wait for a beacon first? */ | 982 | /* XXX: wait for a beacon first? */ |
| 1011 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 983 | ieee80211_wake_queues_by_reason(&local->hw, |
| 1012 | IEEE80211_MAX_QUEUE_MAP, | 984 | IEEE80211_MAX_QUEUE_MAP, |
| 1013 | IEEE80211_QUEUE_STOP_REASON_CSA); | 985 | IEEE80211_QUEUE_STOP_REASON_CSA); |
| 1014 | out: | 986 | out: |
| @@ -1041,56 +1013,193 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
| 1041 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); | 1013 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); |
| 1042 | } | 1014 | } |
| 1043 | 1015 | ||
| 1044 | void | 1016 | static void |
| 1045 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 1017 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
| 1046 | const struct ieee80211_channel_sw_ie *sw_elem, | 1018 | u64 timestamp, struct ieee802_11_elems *elems) |
| 1047 | struct ieee80211_bss *bss, u64 timestamp) | ||
| 1048 | { | 1019 | { |
| 1049 | struct cfg80211_bss *cbss = | 1020 | struct ieee80211_local *local = sdata->local; |
| 1050 | container_of((void *)bss, struct cfg80211_bss, priv); | ||
| 1051 | struct ieee80211_channel *new_ch; | ||
| 1052 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1021 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 1053 | int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, | 1022 | struct cfg80211_bss *cbss = ifmgd->associated; |
| 1054 | cbss->channel->band); | 1023 | struct ieee80211_bss *bss; |
| 1055 | struct ieee80211_chanctx *chanctx; | 1024 | struct ieee80211_chanctx *chanctx; |
| 1025 | enum ieee80211_band new_band; | ||
| 1026 | int new_freq; | ||
| 1027 | u8 new_chan_no; | ||
| 1028 | u8 count; | ||
| 1029 | u8 mode; | ||
| 1030 | struct ieee80211_channel *new_chan; | ||
| 1031 | struct cfg80211_chan_def new_chandef = {}; | ||
| 1032 | struct cfg80211_chan_def new_vht_chandef = {}; | ||
| 1033 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | ||
| 1034 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; | ||
| 1035 | int secondary_channel_offset = -1; | ||
| 1056 | 1036 | ||
| 1057 | ASSERT_MGD_MTX(ifmgd); | 1037 | ASSERT_MGD_MTX(ifmgd); |
| 1058 | 1038 | ||
| 1059 | if (!ifmgd->associated) | 1039 | if (!cbss) |
| 1060 | return; | 1040 | return; |
| 1061 | 1041 | ||
| 1062 | if (sdata->local->scanning) | 1042 | if (local->scanning) |
| 1063 | return; | 1043 | return; |
| 1064 | 1044 | ||
| 1065 | /* Disregard subsequent beacons if we are already running a timer | 1045 | /* disregard subsequent announcements if we are already processing */ |
| 1066 | processing a CSA */ | ||
| 1067 | |||
| 1068 | if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED) | 1046 | if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED) |
| 1069 | return; | 1047 | return; |
| 1070 | 1048 | ||
| 1071 | new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq); | 1049 | sec_chan_offs = elems->sec_chan_offs; |
| 1072 | if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED) { | 1050 | wide_bw_chansw_ie = elems->wide_bw_chansw_ie; |
| 1051 | |||
| 1052 | if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | | ||
| 1053 | IEEE80211_STA_DISABLE_40MHZ)) { | ||
| 1054 | sec_chan_offs = NULL; | ||
| 1055 | wide_bw_chansw_ie = NULL; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT) | ||
| 1059 | wide_bw_chansw_ie = NULL; | ||
| 1060 | |||
| 1061 | if (elems->ext_chansw_ie) { | ||
| 1062 | if (!ieee80211_operating_class_to_band( | ||
| 1063 | elems->ext_chansw_ie->new_operating_class, | ||
| 1064 | &new_band)) { | ||
| 1065 | sdata_info(sdata, | ||
| 1066 | "cannot understand ECSA IE operating class %d, disconnecting\n", | ||
| 1067 | elems->ext_chansw_ie->new_operating_class); | ||
| 1068 | ieee80211_queue_work(&local->hw, | ||
| 1069 | &ifmgd->csa_connection_drop_work); | ||
| 1070 | } | ||
| 1071 | new_chan_no = elems->ext_chansw_ie->new_ch_num; | ||
| 1072 | count = elems->ext_chansw_ie->count; | ||
| 1073 | mode = elems->ext_chansw_ie->mode; | ||
| 1074 | } else if (elems->ch_switch_ie) { | ||
| 1075 | new_band = cbss->channel->band; | ||
| 1076 | new_chan_no = elems->ch_switch_ie->new_ch_num; | ||
| 1077 | count = elems->ch_switch_ie->count; | ||
| 1078 | mode = elems->ch_switch_ie->mode; | ||
| 1079 | } else { | ||
| 1080 | /* nothing here we understand */ | ||
| 1081 | return; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | bss = (void *)cbss->priv; | ||
| 1085 | |||
| 1086 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); | ||
| 1087 | new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq); | ||
| 1088 | if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) { | ||
| 1073 | sdata_info(sdata, | 1089 | sdata_info(sdata, |
| 1074 | "AP %pM switches to unsupported channel (%d MHz), disconnecting\n", | 1090 | "AP %pM switches to unsupported channel (%d MHz), disconnecting\n", |
| 1075 | ifmgd->associated->bssid, new_freq); | 1091 | ifmgd->associated->bssid, new_freq); |
| 1076 | ieee80211_queue_work(&sdata->local->hw, | 1092 | ieee80211_queue_work(&local->hw, |
| 1093 | &ifmgd->csa_connection_drop_work); | ||
| 1094 | return; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | if (sec_chan_offs) { | ||
| 1098 | secondary_channel_offset = sec_chan_offs->sec_chan_offs; | ||
| 1099 | } else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
| 1100 | /* if HT is enabled and the IE not present, it's still HT */ | ||
| 1101 | secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | switch (secondary_channel_offset) { | ||
| 1105 | default: | ||
| 1106 | /* secondary_channel_offset was present but is invalid */ | ||
| 1107 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
| 1108 | cfg80211_chandef_create(&new_chandef, new_chan, | ||
| 1109 | NL80211_CHAN_HT20); | ||
| 1110 | break; | ||
| 1111 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
| 1112 | cfg80211_chandef_create(&new_chandef, new_chan, | ||
| 1113 | NL80211_CHAN_HT40PLUS); | ||
| 1114 | break; | ||
| 1115 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
| 1116 | cfg80211_chandef_create(&new_chandef, new_chan, | ||
| 1117 | NL80211_CHAN_HT40MINUS); | ||
| 1118 | break; | ||
| 1119 | case -1: | ||
| 1120 | cfg80211_chandef_create(&new_chandef, new_chan, | ||
| 1121 | NL80211_CHAN_NO_HT); | ||
| 1122 | break; | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | if (wide_bw_chansw_ie) { | ||
| 1126 | new_vht_chandef.chan = new_chan; | ||
| 1127 | new_vht_chandef.center_freq1 = | ||
| 1128 | ieee80211_channel_to_frequency( | ||
| 1129 | wide_bw_chansw_ie->new_center_freq_seg0, | ||
| 1130 | new_band); | ||
| 1131 | |||
| 1132 | switch (wide_bw_chansw_ie->new_channel_width) { | ||
| 1133 | default: | ||
| 1134 | /* hmmm, ignore VHT and use HT if present */ | ||
| 1135 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | ||
| 1136 | new_vht_chandef.chan = NULL; | ||
| 1137 | break; | ||
| 1138 | case IEEE80211_VHT_CHANWIDTH_80MHZ: | ||
| 1139 | new_vht_chandef.width = NL80211_CHAN_WIDTH_80; | ||
| 1140 | break; | ||
| 1141 | case IEEE80211_VHT_CHANWIDTH_160MHZ: | ||
| 1142 | new_vht_chandef.width = NL80211_CHAN_WIDTH_160; | ||
| 1143 | break; | ||
| 1144 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: | ||
| 1145 | /* field is otherwise reserved */ | ||
| 1146 | new_vht_chandef.center_freq2 = | ||
| 1147 | ieee80211_channel_to_frequency( | ||
| 1148 | wide_bw_chansw_ie->new_center_freq_seg1, | ||
| 1149 | new_band); | ||
| 1150 | new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80; | ||
| 1151 | break; | ||
| 1152 | } | ||
| 1153 | if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ && | ||
| 1154 | new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80) | ||
| 1155 | chandef_downgrade(&new_vht_chandef); | ||
| 1156 | if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ && | ||
| 1157 | new_vht_chandef.width == NL80211_CHAN_WIDTH_160) | ||
| 1158 | chandef_downgrade(&new_vht_chandef); | ||
| 1159 | if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ && | ||
| 1160 | new_vht_chandef.width > NL80211_CHAN_WIDTH_20) | ||
| 1161 | chandef_downgrade(&new_vht_chandef); | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | /* if VHT data is there validate & use it */ | ||
| 1165 | if (new_vht_chandef.chan) { | ||
| 1166 | if (!cfg80211_chandef_compatible(&new_vht_chandef, | ||
| 1167 | &new_chandef)) { | ||
| 1168 | sdata_info(sdata, | ||
| 1169 | "AP %pM CSA has inconsistent channel data, disconnecting\n", | ||
| 1170 | ifmgd->associated->bssid); | ||
| 1171 | ieee80211_queue_work(&local->hw, | ||
| 1172 | &ifmgd->csa_connection_drop_work); | ||
| 1173 | return; | ||
| 1174 | } | ||
| 1175 | new_chandef = new_vht_chandef; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef, | ||
| 1179 | IEEE80211_CHAN_DISABLED)) { | ||
| 1180 | sdata_info(sdata, | ||
| 1181 | "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", | ||
| 1182 | ifmgd->associated->bssid, new_freq, | ||
| 1183 | new_chandef.width, new_chandef.center_freq1, | ||
| 1184 | new_chandef.center_freq2); | ||
| 1185 | ieee80211_queue_work(&local->hw, | ||
| 1077 | &ifmgd->csa_connection_drop_work); | 1186 | &ifmgd->csa_connection_drop_work); |
| 1078 | return; | 1187 | return; |
| 1079 | } | 1188 | } |
| 1080 | 1189 | ||
| 1081 | ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; | 1190 | ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; |
| 1082 | 1191 | ||
| 1083 | if (sdata->local->use_chanctx) { | 1192 | if (local->use_chanctx) { |
| 1084 | sdata_info(sdata, | 1193 | sdata_info(sdata, |
| 1085 | "not handling channel switch with channel contexts\n"); | 1194 | "not handling channel switch with channel contexts\n"); |
| 1086 | ieee80211_queue_work(&sdata->local->hw, | 1195 | ieee80211_queue_work(&local->hw, |
| 1087 | &ifmgd->csa_connection_drop_work); | 1196 | &ifmgd->csa_connection_drop_work); |
| 1088 | return; | 1197 | return; |
| 1089 | } | 1198 | } |
| 1090 | 1199 | ||
| 1091 | mutex_lock(&sdata->local->chanctx_mtx); | 1200 | mutex_lock(&local->chanctx_mtx); |
| 1092 | if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { | 1201 | if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { |
| 1093 | mutex_unlock(&sdata->local->chanctx_mtx); | 1202 | mutex_unlock(&local->chanctx_mtx); |
| 1094 | return; | 1203 | return; |
| 1095 | } | 1204 | } |
| 1096 | chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf), | 1205 | chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf), |
| @@ -1098,40 +1207,39 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
| 1098 | if (chanctx->refcount > 1) { | 1207 | if (chanctx->refcount > 1) { |
| 1099 | sdata_info(sdata, | 1208 | sdata_info(sdata, |
| 1100 | "channel switch with multiple interfaces on the same channel, disconnecting\n"); | 1209 | "channel switch with multiple interfaces on the same channel, disconnecting\n"); |
| 1101 | ieee80211_queue_work(&sdata->local->hw, | 1210 | ieee80211_queue_work(&local->hw, |
| 1102 | &ifmgd->csa_connection_drop_work); | 1211 | &ifmgd->csa_connection_drop_work); |
| 1103 | mutex_unlock(&sdata->local->chanctx_mtx); | 1212 | mutex_unlock(&local->chanctx_mtx); |
| 1104 | return; | 1213 | return; |
| 1105 | } | 1214 | } |
| 1106 | mutex_unlock(&sdata->local->chanctx_mtx); | 1215 | mutex_unlock(&local->chanctx_mtx); |
| 1107 | 1216 | ||
| 1108 | sdata->local->csa_channel = new_ch; | 1217 | local->csa_chandef = new_chandef; |
| 1109 | 1218 | ||
| 1110 | if (sw_elem->mode) | 1219 | if (mode) |
| 1111 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 1220 | ieee80211_stop_queues_by_reason(&local->hw, |
| 1112 | IEEE80211_MAX_QUEUE_MAP, | 1221 | IEEE80211_MAX_QUEUE_MAP, |
| 1113 | IEEE80211_QUEUE_STOP_REASON_CSA); | 1222 | IEEE80211_QUEUE_STOP_REASON_CSA); |
| 1114 | 1223 | ||
| 1115 | if (sdata->local->ops->channel_switch) { | 1224 | if (local->ops->channel_switch) { |
| 1116 | /* use driver's channel switch callback */ | 1225 | /* use driver's channel switch callback */ |
| 1117 | struct ieee80211_channel_switch ch_switch = { | 1226 | struct ieee80211_channel_switch ch_switch = { |
| 1118 | .timestamp = timestamp, | 1227 | .timestamp = timestamp, |
| 1119 | .block_tx = sw_elem->mode, | 1228 | .block_tx = mode, |
| 1120 | .channel = new_ch, | 1229 | .chandef = new_chandef, |
| 1121 | .count = sw_elem->count, | 1230 | .count = count, |
| 1122 | }; | 1231 | }; |
| 1123 | 1232 | ||
| 1124 | drv_channel_switch(sdata->local, &ch_switch); | 1233 | drv_channel_switch(local, &ch_switch); |
| 1125 | return; | 1234 | return; |
| 1126 | } | 1235 | } |
| 1127 | 1236 | ||
| 1128 | /* channel switch handled in software */ | 1237 | /* channel switch handled in software */ |
| 1129 | if (sw_elem->count <= 1) | 1238 | if (count <= 1) |
| 1130 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); | 1239 | ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); |
| 1131 | else | 1240 | else |
| 1132 | mod_timer(&ifmgd->chswitch_timer, | 1241 | mod_timer(&ifmgd->chswitch_timer, |
| 1133 | TU_TO_EXP_TIME(sw_elem->count * | 1242 | TU_TO_EXP_TIME(count * cbss->beacon_interval)); |
| 1134 | cbss->beacon_interval)); | ||
| 1135 | } | 1243 | } |
| 1136 | 1244 | ||
| 1137 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | 1245 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, |
| @@ -1430,13 +1538,11 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
| 1430 | 1538 | ||
| 1431 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 1539 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
| 1432 | !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { | 1540 | !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { |
| 1433 | netif_tx_stop_all_queues(sdata->dev); | 1541 | if (drv_tx_frames_pending(local)) { |
| 1434 | |||
| 1435 | if (drv_tx_frames_pending(local)) | ||
| 1436 | mod_timer(&local->dynamic_ps_timer, jiffies + | 1542 | mod_timer(&local->dynamic_ps_timer, jiffies + |
| 1437 | msecs_to_jiffies( | 1543 | msecs_to_jiffies( |
| 1438 | local->hw.conf.dynamic_ps_timeout)); | 1544 | local->hw.conf.dynamic_ps_timeout)); |
| 1439 | else { | 1545 | } else { |
| 1440 | ieee80211_send_nullfunc(local, sdata, 1); | 1546 | ieee80211_send_nullfunc(local, sdata, 1); |
| 1441 | /* Flush to get the tx status of nullfunc frame */ | 1547 | /* Flush to get the tx status of nullfunc frame */ |
| 1442 | ieee80211_flush_queues(local, sdata); | 1548 | ieee80211_flush_queues(local, sdata); |
| @@ -1450,9 +1556,6 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
| 1450 | local->hw.conf.flags |= IEEE80211_CONF_PS; | 1556 | local->hw.conf.flags |= IEEE80211_CONF_PS; |
| 1451 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 1557 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
| 1452 | } | 1558 | } |
| 1453 | |||
| 1454 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) | ||
| 1455 | netif_tx_wake_all_queues(sdata->dev); | ||
| 1456 | } | 1559 | } |
| 1457 | 1560 | ||
| 1458 | void ieee80211_dynamic_ps_timer(unsigned long data) | 1561 | void ieee80211_dynamic_ps_timer(unsigned long data) |
| @@ -1558,6 +1661,7 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 1558 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 1661 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
| 1559 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 1662 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
| 1560 | params.txop = get_unaligned_le16(pos + 2); | 1663 | params.txop = get_unaligned_le16(pos + 2); |
| 1664 | params.acm = acm; | ||
| 1561 | params.uapsd = uapsd; | 1665 | params.uapsd = uapsd; |
| 1562 | 1666 | ||
| 1563 | mlme_dbg(sdata, | 1667 | mlme_dbg(sdata, |
| @@ -1645,7 +1749,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
| 1645 | bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); | 1749 | bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); |
| 1646 | 1750 | ||
| 1647 | sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( | 1751 | sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( |
| 1648 | IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); | 1752 | beacon_loss_count * bss_conf->beacon_int)); |
| 1649 | 1753 | ||
| 1650 | sdata->u.mgd.associated = cbss; | 1754 | sdata->u.mgd.associated = cbss; |
| 1651 | memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); | 1755 | memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); |
| @@ -1658,18 +1762,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
| 1658 | rcu_read_lock(); | 1762 | rcu_read_lock(); |
| 1659 | ies = rcu_dereference(cbss->ies); | 1763 | ies = rcu_dereference(cbss->ies); |
| 1660 | if (ies) { | 1764 | if (ies) { |
| 1661 | u8 noa[2]; | ||
| 1662 | int ret; | 1765 | int ret; |
| 1663 | 1766 | ||
| 1664 | ret = cfg80211_get_p2p_attr( | 1767 | ret = cfg80211_get_p2p_attr( |
| 1665 | ies->data, ies->len, | 1768 | ies->data, ies->len, |
| 1666 | IEEE80211_P2P_ATTR_ABSENCE_NOTICE, | 1769 | IEEE80211_P2P_ATTR_ABSENCE_NOTICE, |
| 1667 | noa, sizeof(noa)); | 1770 | (u8 *) &bss_conf->p2p_noa_attr, |
| 1771 | sizeof(bss_conf->p2p_noa_attr)); | ||
| 1668 | if (ret >= 2) { | 1772 | if (ret >= 2) { |
| 1669 | bss_conf->p2p_oppps = noa[1] & 0x80; | 1773 | sdata->u.mgd.p2p_noa_index = |
| 1670 | bss_conf->p2p_ctwindow = noa[1] & 0x7f; | 1774 | bss_conf->p2p_noa_attr.index; |
| 1671 | bss_info_changed |= BSS_CHANGED_P2P_PS; | 1775 | bss_info_changed |= BSS_CHANGED_P2P_PS; |
| 1672 | sdata->u.mgd.p2p_noa_index = noa[0]; | ||
| 1673 | } | 1776 | } |
| 1674 | } | 1777 | } |
| 1675 | rcu_read_unlock(); | 1778 | rcu_read_unlock(); |
| @@ -1713,7 +1816,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
| 1713 | ieee80211_recalc_smps(sdata); | 1816 | ieee80211_recalc_smps(sdata); |
| 1714 | ieee80211_recalc_ps_vif(sdata); | 1817 | ieee80211_recalc_ps_vif(sdata); |
| 1715 | 1818 | ||
| 1716 | netif_tx_start_all_queues(sdata->dev); | ||
| 1717 | netif_carrier_on(sdata->dev); | 1819 | netif_carrier_on(sdata->dev); |
| 1718 | } | 1820 | } |
| 1719 | 1821 | ||
| @@ -1736,22 +1838,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1736 | ieee80211_stop_poll(sdata); | 1838 | ieee80211_stop_poll(sdata); |
| 1737 | 1839 | ||
| 1738 | ifmgd->associated = NULL; | 1840 | ifmgd->associated = NULL; |
| 1739 | |||
| 1740 | /* | ||
| 1741 | * we need to commit the associated = NULL change because the | ||
| 1742 | * scan code uses that to determine whether this iface should | ||
| 1743 | * go to/wake up from powersave or not -- and could otherwise | ||
| 1744 | * wake the queues erroneously. | ||
| 1745 | */ | ||
| 1746 | smp_mb(); | ||
| 1747 | |||
| 1748 | /* | ||
| 1749 | * Thus, we can only afterwards stop the queues -- to account | ||
| 1750 | * for the case where another CPU is finishing a scan at this | ||
| 1751 | * time -- we don't want the scan code to enable queues. | ||
| 1752 | */ | ||
| 1753 | |||
| 1754 | netif_tx_stop_all_queues(sdata->dev); | ||
| 1755 | netif_carrier_off(sdata->dev); | 1841 | netif_carrier_off(sdata->dev); |
| 1756 | 1842 | ||
| 1757 | /* | 1843 | /* |
| @@ -1794,8 +1880,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1794 | changed |= BSS_CHANGED_ASSOC; | 1880 | changed |= BSS_CHANGED_ASSOC; |
| 1795 | sdata->vif.bss_conf.assoc = false; | 1881 | sdata->vif.bss_conf.assoc = false; |
| 1796 | 1882 | ||
| 1797 | sdata->vif.bss_conf.p2p_ctwindow = 0; | 1883 | ifmgd->p2p_noa_index = -1; |
| 1798 | sdata->vif.bss_conf.p2p_oppps = false; | 1884 | memset(&sdata->vif.bss_conf.p2p_noa_attr, 0, |
| 1885 | sizeof(sdata->vif.bss_conf.p2p_noa_attr)); | ||
| 1799 | 1886 | ||
| 1800 | /* on the next assoc, re-program HT/VHT parameters */ | 1887 | /* on the next assoc, re-program HT/VHT parameters */ |
| 1801 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); | 1888 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); |
| @@ -1975,12 +2062,15 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
| 1975 | goto out; | 2062 | goto out; |
| 1976 | } | 2063 | } |
| 1977 | 2064 | ||
| 1978 | if (beacon) | 2065 | if (beacon) { |
| 1979 | mlme_dbg_ratelimited(sdata, | 2066 | mlme_dbg_ratelimited(sdata, |
| 1980 | "detected beacon loss from AP - probing\n"); | 2067 | "detected beacon loss from AP (missed %d beacons) - probing\n", |
| 2068 | beacon_loss_count); | ||
| 1981 | 2069 | ||
| 1982 | ieee80211_cqm_rssi_notify(&sdata->vif, | 2070 | ieee80211_cqm_rssi_notify(&sdata->vif, |
| 1983 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); | 2071 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, |
| 2072 | GFP_KERNEL); | ||
| 2073 | } | ||
| 1984 | 2074 | ||
| 1985 | /* | 2075 | /* |
| 1986 | * The driver/our work has already reported this event or the | 2076 | * The driver/our work has already reported this event or the |
| @@ -2126,7 +2216,6 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
| 2126 | 2216 | ||
| 2127 | trace_api_beacon_loss(sdata); | 2217 | trace_api_beacon_loss(sdata); |
| 2128 | 2218 | ||
| 2129 | WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR); | ||
| 2130 | sdata->u.mgd.connection_loss = false; | 2219 | sdata->u.mgd.connection_loss = false; |
| 2131 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); | 2220 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); |
| 2132 | } | 2221 | } |
| @@ -2176,7 +2265,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
| 2176 | u32 tx_flags = 0; | 2265 | u32 tx_flags = 0; |
| 2177 | 2266 | ||
| 2178 | pos = mgmt->u.auth.variable; | 2267 | pos = mgmt->u.auth.variable; |
| 2179 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2268 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems); |
| 2180 | if (!elems.challenge) | 2269 | if (!elems.challenge) |
| 2181 | return; | 2270 | return; |
| 2182 | auth_data->expected_transaction = 4; | 2271 | auth_data->expected_transaction = 4; |
| @@ -2441,7 +2530,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2441 | } | 2530 | } |
| 2442 | 2531 | ||
| 2443 | pos = mgmt->u.assoc_resp.variable; | 2532 | pos = mgmt->u.assoc_resp.variable; |
| 2444 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2533 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems); |
| 2445 | 2534 | ||
| 2446 | if (!elems.supp_rates) { | 2535 | if (!elems.supp_rates) { |
| 2447 | sdata_info(sdata, "no SuppRates element in AssocResp\n"); | 2536 | sdata_info(sdata, "no SuppRates element in AssocResp\n"); |
| @@ -2610,13 +2699,13 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2610 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | 2699 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
| 2611 | 2700 | ||
| 2612 | pos = mgmt->u.assoc_resp.variable; | 2701 | pos = mgmt->u.assoc_resp.variable; |
| 2613 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2702 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems); |
| 2614 | 2703 | ||
| 2615 | if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && | 2704 | if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && |
| 2616 | elems.timeout_int && elems.timeout_int_len == 5 && | 2705 | elems.timeout_int && |
| 2617 | elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) { | 2706 | elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { |
| 2618 | u32 tu, ms; | 2707 | u32 tu, ms; |
| 2619 | tu = get_unaligned_le32(elems.timeout_int + 1); | 2708 | tu = le32_to_cpu(elems.timeout_int->value); |
| 2620 | ms = tu * 1024 / 1000; | 2709 | ms = tu * 1024 / 1000; |
| 2621 | sdata_info(sdata, | 2710 | sdata_info(sdata, |
| 2622 | "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", | 2711 | "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", |
| @@ -2665,6 +2754,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 2665 | struct ieee80211_channel *channel; | 2754 | struct ieee80211_channel *channel; |
| 2666 | bool need_ps = false; | 2755 | bool need_ps = false; |
| 2667 | 2756 | ||
| 2757 | lockdep_assert_held(&sdata->u.mgd.mtx); | ||
| 2758 | |||
| 2668 | if ((sdata->u.mgd.associated && | 2759 | if ((sdata->u.mgd.associated && |
| 2669 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || | 2760 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || |
| 2670 | (sdata->u.mgd.assoc_data && | 2761 | (sdata->u.mgd.assoc_data && |
| @@ -2679,7 +2770,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 2679 | } | 2770 | } |
| 2680 | } | 2771 | } |
| 2681 | 2772 | ||
| 2682 | if (elems->ds_params && elems->ds_params_len == 1) | 2773 | if (elems->ds_params) |
| 2683 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], | 2774 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], |
| 2684 | rx_status->band); | 2775 | rx_status->band); |
| 2685 | else | 2776 | else |
| @@ -2695,7 +2786,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 2695 | if (bss) | 2786 | if (bss) |
| 2696 | ieee80211_rx_bss_put(local, bss); | 2787 | ieee80211_rx_bss_put(local, bss); |
| 2697 | 2788 | ||
| 2698 | if (!sdata->u.mgd.associated) | 2789 | if (!sdata->u.mgd.associated || |
| 2790 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) | ||
| 2699 | return; | 2791 | return; |
| 2700 | 2792 | ||
| 2701 | if (need_ps) { | 2793 | if (need_ps) { |
| @@ -2704,10 +2796,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
| 2704 | mutex_unlock(&local->iflist_mtx); | 2796 | mutex_unlock(&local->iflist_mtx); |
| 2705 | } | 2797 | } |
| 2706 | 2798 | ||
| 2707 | if (elems->ch_switch_ie && | 2799 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, elems); |
| 2708 | memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN) == 0) | 2800 | |
| 2709 | ieee80211_sta_process_chanswitch(sdata, elems->ch_switch_ie, | ||
| 2710 | bss, rx_status->mactime); | ||
| 2711 | } | 2801 | } |
| 2712 | 2802 | ||
| 2713 | 2803 | ||
| @@ -2732,7 +2822,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2732 | return; | 2822 | return; |
| 2733 | 2823 | ||
| 2734 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 2824 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
| 2735 | &elems); | 2825 | false, &elems); |
| 2736 | 2826 | ||
| 2737 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 2827 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
| 2738 | 2828 | ||
| @@ -2815,7 +2905,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 2815 | if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && | 2905 | if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && |
| 2816 | ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { | 2906 | ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { |
| 2817 | ieee802_11_parse_elems(mgmt->u.beacon.variable, | 2907 | ieee802_11_parse_elems(mgmt->u.beacon.variable, |
| 2818 | len - baselen, &elems); | 2908 | len - baselen, false, &elems); |
| 2819 | 2909 | ||
| 2820 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 2910 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
| 2821 | ifmgd->assoc_data->have_beacon = true; | 2911 | ifmgd->assoc_data->have_beacon = true; |
| @@ -2925,7 +3015,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 2925 | 3015 | ||
| 2926 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 3016 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |
| 2927 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, | 3017 | ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, |
| 2928 | len - baselen, &elems, | 3018 | len - baselen, false, &elems, |
| 2929 | care_about_ies, ncrc); | 3019 | care_about_ies, ncrc); |
| 2930 | 3020 | ||
| 2931 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { | 3021 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { |
| @@ -2957,22 +3047,30 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 2957 | } | 3047 | } |
| 2958 | 3048 | ||
| 2959 | if (sdata->vif.p2p) { | 3049 | if (sdata->vif.p2p) { |
| 2960 | u8 noa[2]; | 3050 | struct ieee80211_p2p_noa_attr noa = {}; |
| 2961 | int ret; | 3051 | int ret; |
| 2962 | 3052 | ||
| 2963 | ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable, | 3053 | ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable, |
| 2964 | len - baselen, | 3054 | len - baselen, |
| 2965 | IEEE80211_P2P_ATTR_ABSENCE_NOTICE, | 3055 | IEEE80211_P2P_ATTR_ABSENCE_NOTICE, |
| 2966 | noa, sizeof(noa)); | 3056 | (u8 *) &noa, sizeof(noa)); |
| 2967 | if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) { | 3057 | if (ret >= 2) { |
| 2968 | bss_conf->p2p_oppps = noa[1] & 0x80; | 3058 | if (sdata->u.mgd.p2p_noa_index != noa.index) { |
| 2969 | bss_conf->p2p_ctwindow = noa[1] & 0x7f; | 3059 | /* valid noa_attr and index changed */ |
| 3060 | sdata->u.mgd.p2p_noa_index = noa.index; | ||
| 3061 | memcpy(&bss_conf->p2p_noa_attr, &noa, sizeof(noa)); | ||
| 3062 | changed |= BSS_CHANGED_P2P_PS; | ||
| 3063 | /* | ||
| 3064 | * make sure we update all information, the CRC | ||
| 3065 | * mechanism doesn't look at P2P attributes. | ||
| 3066 | */ | ||
| 3067 | ifmgd->beacon_crc_valid = false; | ||
| 3068 | } | ||
| 3069 | } else if (sdata->u.mgd.p2p_noa_index != -1) { | ||
| 3070 | /* noa_attr not found and we had valid noa_attr before */ | ||
| 3071 | sdata->u.mgd.p2p_noa_index = -1; | ||
| 3072 | memset(&bss_conf->p2p_noa_attr, 0, sizeof(bss_conf->p2p_noa_attr)); | ||
| 2970 | changed |= BSS_CHANGED_P2P_PS; | 3073 | changed |= BSS_CHANGED_P2P_PS; |
| 2971 | sdata->u.mgd.p2p_noa_index = noa[0]; | ||
| 2972 | /* | ||
| 2973 | * make sure we update all information, the CRC | ||
| 2974 | * mechanism doesn't look at P2P attributes. | ||
| 2975 | */ | ||
| 2976 | ifmgd->beacon_crc_valid = false; | 3074 | ifmgd->beacon_crc_valid = false; |
| 2977 | } | 3075 | } |
| 2978 | } | 3076 | } |
| @@ -3014,7 +3112,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 3014 | changed |= BSS_CHANGED_DTIM_PERIOD; | 3112 | changed |= BSS_CHANGED_DTIM_PERIOD; |
| 3015 | } | 3113 | } |
| 3016 | 3114 | ||
| 3017 | if (elems.erp_info && elems.erp_info_len >= 1) { | 3115 | if (elems.erp_info) { |
| 3018 | erp_valid = true; | 3116 | erp_valid = true; |
| 3019 | erp_value = elems.erp_info[0]; | 3117 | erp_value = elems.erp_info[0]; |
| 3020 | } else { | 3118 | } else { |
| @@ -3064,6 +3162,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 3064 | enum rx_mgmt_action rma = RX_MGMT_NONE; | 3162 | enum rx_mgmt_action rma = RX_MGMT_NONE; |
| 3065 | u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 3163 | u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
| 3066 | u16 fc; | 3164 | u16 fc; |
| 3165 | struct ieee802_11_elems elems; | ||
| 3166 | int ies_len; | ||
| 3067 | 3167 | ||
| 3068 | rx_status = (struct ieee80211_rx_status *) skb->cb; | 3168 | rx_status = (struct ieee80211_rx_status *) skb->cb; |
| 3069 | mgmt = (struct ieee80211_mgmt *) skb->data; | 3169 | mgmt = (struct ieee80211_mgmt *) skb->data; |
| @@ -3093,14 +3193,48 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 3093 | rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss); | 3193 | rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss); |
| 3094 | break; | 3194 | break; |
| 3095 | case IEEE80211_STYPE_ACTION: | 3195 | case IEEE80211_STYPE_ACTION: |
| 3096 | switch (mgmt->u.action.category) { | 3196 | if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { |
| 3097 | case WLAN_CATEGORY_SPECTRUM_MGMT: | 3197 | ies_len = skb->len - |
| 3198 | offsetof(struct ieee80211_mgmt, | ||
| 3199 | u.action.u.chan_switch.variable); | ||
| 3200 | |||
| 3201 | if (ies_len < 0) | ||
| 3202 | break; | ||
| 3203 | |||
| 3204 | ieee802_11_parse_elems( | ||
| 3205 | mgmt->u.action.u.chan_switch.variable, | ||
| 3206 | ies_len, true, &elems); | ||
| 3207 | |||
| 3208 | if (elems.parse_error) | ||
| 3209 | break; | ||
| 3210 | |||
| 3098 | ieee80211_sta_process_chanswitch(sdata, | 3211 | ieee80211_sta_process_chanswitch(sdata, |
| 3099 | &mgmt->u.action.u.chan_switch.sw_elem, | 3212 | rx_status->mactime, |
| 3100 | (void *)ifmgd->associated->priv, | 3213 | &elems); |
| 3101 | rx_status->mactime); | 3214 | } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { |
| 3102 | break; | 3215 | ies_len = skb->len - |
| 3216 | offsetof(struct ieee80211_mgmt, | ||
| 3217 | u.action.u.ext_chan_switch.variable); | ||
| 3218 | |||
| 3219 | if (ies_len < 0) | ||
| 3220 | break; | ||
| 3221 | |||
| 3222 | ieee802_11_parse_elems( | ||
| 3223 | mgmt->u.action.u.ext_chan_switch.variable, | ||
| 3224 | ies_len, true, &elems); | ||
| 3225 | |||
| 3226 | if (elems.parse_error) | ||
| 3227 | break; | ||
| 3228 | |||
| 3229 | /* for the handling code pretend this was also an IE */ | ||
| 3230 | elems.ext_chansw_ie = | ||
| 3231 | &mgmt->u.action.u.ext_chan_switch.data; | ||
| 3232 | |||
| 3233 | ieee80211_sta_process_chanswitch(sdata, | ||
| 3234 | rx_status->mactime, | ||
| 3235 | &elems); | ||
| 3103 | } | 3236 | } |
| 3237 | break; | ||
| 3104 | } | 3238 | } |
| 3105 | mutex_unlock(&ifmgd->mtx); | 3239 | mutex_unlock(&ifmgd->mtx); |
| 3106 | 3240 | ||
| @@ -3513,8 +3647,9 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
| 3513 | 3647 | ||
| 3514 | ifmgd->flags = 0; | 3648 | ifmgd->flags = 0; |
| 3515 | ifmgd->powersave = sdata->wdev.ps; | 3649 | ifmgd->powersave = sdata->wdev.ps; |
| 3516 | ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | 3650 | ifmgd->uapsd_queues = sdata->local->hw.uapsd_queues; |
| 3517 | ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | 3651 | ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; |
| 3652 | ifmgd->p2p_noa_index = -1; | ||
| 3518 | 3653 | ||
| 3519 | mutex_init(&ifmgd->mtx); | 3654 | mutex_init(&ifmgd->mtx); |
| 3520 | 3655 | ||
| @@ -4079,7 +4214,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
| 4079 | rcu_read_unlock(); | 4214 | rcu_read_unlock(); |
| 4080 | 4215 | ||
| 4081 | if (bss->wmm_used && bss->uapsd_supported && | 4216 | if (bss->wmm_used && bss->uapsd_supported && |
| 4082 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 4217 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) && |
| 4218 | sdata->wmm_acm != 0xff) { | ||
| 4083 | assoc_data->uapsd = true; | 4219 | assoc_data->uapsd = true; |
| 4084 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; | 4220 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; |
| 4085 | } else { | 4221 | } else { |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index cce795871ab1..acd1f71adc03 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
| @@ -445,15 +445,15 @@ void ieee80211_roc_setup(struct ieee80211_local *local) | |||
| 445 | INIT_LIST_HEAD(&local->roc_list); | 445 | INIT_LIST_HEAD(&local->roc_list); |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) | 448 | void ieee80211_roc_purge(struct ieee80211_local *local, |
| 449 | struct ieee80211_sub_if_data *sdata) | ||
| 449 | { | 450 | { |
| 450 | struct ieee80211_local *local = sdata->local; | ||
| 451 | struct ieee80211_roc_work *roc, *tmp; | 451 | struct ieee80211_roc_work *roc, *tmp; |
| 452 | LIST_HEAD(tmp_list); | 452 | LIST_HEAD(tmp_list); |
| 453 | 453 | ||
| 454 | mutex_lock(&local->mtx); | 454 | mutex_lock(&local->mtx); |
| 455 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { | 455 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { |
| 456 | if (roc->sdata != sdata) | 456 | if (sdata && roc->sdata != sdata) |
| 457 | continue; | 457 | continue; |
| 458 | 458 | ||
| 459 | if (roc->started && local->ops->remain_on_channel) { | 459 | if (roc->started && local->ops->remain_on_channel) { |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 3d16f4e61743..7fc5d0d8149a 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
| @@ -19,6 +19,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 19 | 19 | ||
| 20 | ieee80211_dfs_cac_cancel(local); | 20 | ieee80211_dfs_cac_cancel(local); |
| 21 | 21 | ||
| 22 | ieee80211_roc_purge(local, NULL); | ||
| 23 | |||
| 24 | ieee80211_del_virtual_monitor(local); | ||
| 25 | |||
| 22 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 26 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
| 23 | mutex_lock(&local->sta_mtx); | 27 | mutex_lock(&local->sta_mtx); |
| 24 | list_for_each_entry(sta, &local->sta_list, list) { | 28 | list_for_each_entry(sta, &local->sta_list, list) { |
| @@ -33,8 +37,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 33 | IEEE80211_MAX_QUEUE_MAP, | 37 | IEEE80211_MAX_QUEUE_MAP, |
| 34 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 38 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
| 35 | 39 | ||
| 36 | /* flush out all packets */ | 40 | /* flush out all packets and station cleanup call_rcu()s */ |
| 37 | synchronize_net(); | 41 | synchronize_net(); |
| 42 | rcu_barrier(); | ||
| 38 | 43 | ||
| 39 | ieee80211_flush_queues(local, NULL); | 44 | ieee80211_flush_queues(local, NULL); |
| 40 | 45 | ||
| @@ -101,10 +106,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 101 | drv_remove_interface(local, sdata); | 106 | drv_remove_interface(local, sdata); |
| 102 | } | 107 | } |
| 103 | 108 | ||
| 104 | sdata = rtnl_dereference(local->monitor_sdata); | ||
| 105 | if (sdata) | ||
| 106 | drv_remove_interface(local, sdata); | ||
| 107 | |||
| 108 | /* | 109 | /* |
| 109 | * We disconnected on all interfaces before suspend, all channel | 110 | * We disconnected on all interfaces before suspend, all channel |
| 110 | * contexts should be released. | 111 | * contexts should be released. |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index dd88381c53b7..0d51877efdb7 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
| @@ -252,6 +252,25 @@ rate_lowest_non_cck_index(struct ieee80211_supported_band *sband, | |||
| 252 | return 0; | 252 | return 0; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | static void __rate_control_send_low(struct ieee80211_hw *hw, | ||
| 256 | struct ieee80211_supported_band *sband, | ||
| 257 | struct ieee80211_sta *sta, | ||
| 258 | struct ieee80211_tx_info *info) | ||
| 259 | { | ||
| 260 | if ((sband->band != IEEE80211_BAND_2GHZ) || | ||
| 261 | !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)) | ||
| 262 | info->control.rates[0].idx = rate_lowest_index(sband, sta); | ||
| 263 | else | ||
| 264 | info->control.rates[0].idx = | ||
| 265 | rate_lowest_non_cck_index(sband, sta); | ||
| 266 | |||
| 267 | info->control.rates[0].count = | ||
| 268 | (info->flags & IEEE80211_TX_CTL_NO_ACK) ? | ||
| 269 | 1 : hw->max_rate_tries; | ||
| 270 | |||
| 271 | info->control.skip_table = 1; | ||
| 272 | } | ||
| 273 | |||
| 255 | 274 | ||
| 256 | bool rate_control_send_low(struct ieee80211_sta *sta, | 275 | bool rate_control_send_low(struct ieee80211_sta *sta, |
| 257 | void *priv_sta, | 276 | void *priv_sta, |
| @@ -262,16 +281,8 @@ bool rate_control_send_low(struct ieee80211_sta *sta, | |||
| 262 | int mcast_rate; | 281 | int mcast_rate; |
| 263 | 282 | ||
| 264 | if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { | 283 | if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { |
| 265 | if ((sband->band != IEEE80211_BAND_2GHZ) || | 284 | __rate_control_send_low(txrc->hw, sband, sta, info); |
| 266 | !(info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)) | 285 | |
| 267 | info->control.rates[0].idx = | ||
| 268 | rate_lowest_index(txrc->sband, sta); | ||
| 269 | else | ||
| 270 | info->control.rates[0].idx = | ||
| 271 | rate_lowest_non_cck_index(txrc->sband, sta); | ||
| 272 | info->control.rates[0].count = | ||
| 273 | (info->flags & IEEE80211_TX_CTL_NO_ACK) ? | ||
| 274 | 1 : txrc->hw->max_rate_tries; | ||
| 275 | if (!sta && txrc->bss) { | 286 | if (!sta && txrc->bss) { |
| 276 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; | 287 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; |
| 277 | if (mcast_rate > 0) { | 288 | if (mcast_rate > 0) { |
| @@ -355,7 +366,8 @@ static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate, | |||
| 355 | 366 | ||
| 356 | 367 | ||
| 357 | static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, | 368 | static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, |
| 358 | struct ieee80211_tx_rate_control *txrc, | 369 | struct ieee80211_supported_band *sband, |
| 370 | enum nl80211_chan_width chan_width, | ||
| 359 | u32 mask, | 371 | u32 mask, |
| 360 | u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) | 372 | u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) |
| 361 | { | 373 | { |
| @@ -375,27 +387,17 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, | |||
| 375 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE); | 387 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE); |
| 376 | alt_rate.count = rate->count; | 388 | alt_rate.count = rate->count; |
| 377 | if (rate_idx_match_legacy_mask(&alt_rate, | 389 | if (rate_idx_match_legacy_mask(&alt_rate, |
| 378 | txrc->sband->n_bitrates, | 390 | sband->n_bitrates, mask)) { |
| 379 | mask)) { | ||
| 380 | *rate = alt_rate; | 391 | *rate = alt_rate; |
| 381 | return; | 392 | return; |
| 382 | } | 393 | } |
| 383 | } else { | 394 | } else { |
| 384 | struct sk_buff *skb = txrc->skb; | ||
| 385 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 386 | __le16 fc; | ||
| 387 | |||
| 388 | /* handle legacy rates */ | 395 | /* handle legacy rates */ |
| 389 | if (rate_idx_match_legacy_mask(rate, txrc->sband->n_bitrates, | 396 | if (rate_idx_match_legacy_mask(rate, sband->n_bitrates, mask)) |
| 390 | mask)) | ||
| 391 | return; | 397 | return; |
| 392 | 398 | ||
| 393 | /* if HT BSS, and we handle a data frame, also try HT rates */ | 399 | /* if HT BSS, and we handle a data frame, also try HT rates */ |
| 394 | if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) | 400 | if (chan_width == NL80211_CHAN_WIDTH_20_NOHT) |
| 395 | return; | ||
| 396 | |||
| 397 | fc = hdr->frame_control; | ||
| 398 | if (!ieee80211_is_data(fc)) | ||
| 399 | return; | 401 | return; |
| 400 | 402 | ||
| 401 | alt_rate.idx = 0; | 403 | alt_rate.idx = 0; |
| @@ -408,7 +410,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, | |||
| 408 | 410 | ||
| 409 | alt_rate.flags |= IEEE80211_TX_RC_MCS; | 411 | alt_rate.flags |= IEEE80211_TX_RC_MCS; |
| 410 | 412 | ||
| 411 | if (txrc->bss_conf->chandef.width == NL80211_CHAN_WIDTH_40) | 413 | if (chan_width == NL80211_CHAN_WIDTH_40) |
| 412 | alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | 414 | alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
| 413 | 415 | ||
| 414 | if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) { | 416 | if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) { |
| @@ -426,6 +428,228 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate, | |||
| 426 | */ | 428 | */ |
| 427 | } | 429 | } |
| 428 | 430 | ||
| 431 | static void rate_fixup_ratelist(struct ieee80211_vif *vif, | ||
| 432 | struct ieee80211_supported_band *sband, | ||
| 433 | struct ieee80211_tx_info *info, | ||
| 434 | struct ieee80211_tx_rate *rates, | ||
| 435 | int max_rates) | ||
| 436 | { | ||
| 437 | struct ieee80211_rate *rate; | ||
| 438 | bool inval = false; | ||
| 439 | int i; | ||
| 440 | |||
| 441 | /* | ||
| 442 | * Set up the RTS/CTS rate as the fastest basic rate | ||
| 443 | * that is not faster than the data rate unless there | ||
| 444 | * is no basic rate slower than the data rate, in which | ||
| 445 | * case we pick the slowest basic rate | ||
| 446 | * | ||
| 447 | * XXX: Should this check all retry rates? | ||
| 448 | */ | ||
| 449 | if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) { | ||
| 450 | u32 basic_rates = vif->bss_conf.basic_rates; | ||
| 451 | s8 baserate = basic_rates ? ffs(basic_rates - 1) : 0; | ||
| 452 | |||
| 453 | rate = &sband->bitrates[rates[0].idx]; | ||
| 454 | |||
| 455 | for (i = 0; i < sband->n_bitrates; i++) { | ||
| 456 | /* must be a basic rate */ | ||
| 457 | if (!(basic_rates & BIT(i))) | ||
| 458 | continue; | ||
| 459 | /* must not be faster than the data rate */ | ||
| 460 | if (sband->bitrates[i].bitrate > rate->bitrate) | ||
| 461 | continue; | ||
| 462 | /* maximum */ | ||
| 463 | if (sband->bitrates[baserate].bitrate < | ||
| 464 | sband->bitrates[i].bitrate) | ||
| 465 | baserate = i; | ||
| 466 | } | ||
| 467 | |||
| 468 | info->control.rts_cts_rate_idx = baserate; | ||
| 469 | } | ||
| 470 | |||
| 471 | for (i = 0; i < max_rates; i++) { | ||
| 472 | /* | ||
| 473 | * make sure there's no valid rate following | ||
| 474 | * an invalid one, just in case drivers don't | ||
| 475 | * take the API seriously to stop at -1. | ||
| 476 | */ | ||
| 477 | if (inval) { | ||
| 478 | rates[i].idx = -1; | ||
| 479 | continue; | ||
| 480 | } | ||
| 481 | if (rates[i].idx < 0) { | ||
| 482 | inval = true; | ||
| 483 | continue; | ||
| 484 | } | ||
| 485 | |||
| 486 | /* | ||
| 487 | * For now assume MCS is already set up correctly, this | ||
| 488 | * needs to be fixed. | ||
| 489 | */ | ||
| 490 | if (rates[i].flags & IEEE80211_TX_RC_MCS) { | ||
| 491 | WARN_ON(rates[i].idx > 76); | ||
| 492 | |||
| 493 | if (!(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) && | ||
| 494 | info->control.use_cts_prot) | ||
| 495 | rates[i].flags |= | ||
| 496 | IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
| 497 | continue; | ||
| 498 | } | ||
| 499 | |||
| 500 | if (rates[i].flags & IEEE80211_TX_RC_VHT_MCS) { | ||
| 501 | WARN_ON(ieee80211_rate_get_vht_mcs(&rates[i]) > 9); | ||
| 502 | continue; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* set up RTS protection if desired */ | ||
| 506 | if (info->control.use_rts) { | ||
| 507 | rates[i].flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
| 508 | info->control.use_cts_prot = false; | ||
| 509 | } | ||
| 510 | |||
| 511 | /* RC is busted */ | ||
| 512 | if (WARN_ON_ONCE(rates[i].idx >= sband->n_bitrates)) { | ||
| 513 | rates[i].idx = -1; | ||
| 514 | continue; | ||
| 515 | } | ||
| 516 | |||
| 517 | rate = &sband->bitrates[rates[i].idx]; | ||
| 518 | |||
| 519 | /* set up short preamble */ | ||
| 520 | if (info->control.short_preamble && | ||
| 521 | rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
| 522 | rates[i].flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
| 523 | |||
| 524 | /* set up G protection */ | ||
| 525 | if (!(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) && | ||
| 526 | info->control.use_cts_prot && | ||
| 527 | rate->flags & IEEE80211_RATE_ERP_G) | ||
| 528 | rates[i].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
| 529 | } | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | static void rate_control_fill_sta_table(struct ieee80211_sta *sta, | ||
| 534 | struct ieee80211_tx_info *info, | ||
| 535 | struct ieee80211_tx_rate *rates, | ||
| 536 | int max_rates) | ||
| 537 | { | ||
| 538 | struct ieee80211_sta_rates *ratetbl = NULL; | ||
| 539 | int i; | ||
| 540 | |||
| 541 | if (sta && !info->control.skip_table) | ||
| 542 | ratetbl = rcu_dereference(sta->rates); | ||
| 543 | |||
| 544 | /* Fill remaining rate slots with data from the sta rate table. */ | ||
| 545 | max_rates = min_t(int, max_rates, IEEE80211_TX_RATE_TABLE_SIZE); | ||
| 546 | for (i = 0; i < max_rates; i++) { | ||
| 547 | if (i < ARRAY_SIZE(info->control.rates) && | ||
| 548 | info->control.rates[i].idx >= 0 && | ||
| 549 | info->control.rates[i].count) { | ||
| 550 | if (rates != info->control.rates) | ||
| 551 | rates[i] = info->control.rates[i]; | ||
| 552 | } else if (ratetbl) { | ||
| 553 | rates[i].idx = ratetbl->rate[i].idx; | ||
| 554 | rates[i].flags = ratetbl->rate[i].flags; | ||
| 555 | if (info->control.use_rts) | ||
| 556 | rates[i].count = ratetbl->rate[i].count_rts; | ||
| 557 | else if (info->control.use_cts_prot) | ||
| 558 | rates[i].count = ratetbl->rate[i].count_cts; | ||
| 559 | else | ||
| 560 | rates[i].count = ratetbl->rate[i].count; | ||
| 561 | } else { | ||
| 562 | rates[i].idx = -1; | ||
| 563 | rates[i].count = 0; | ||
| 564 | } | ||
| 565 | |||
| 566 | if (rates[i].idx < 0 || !rates[i].count) | ||
| 567 | break; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | |||
| 571 | static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata, | ||
| 572 | struct ieee80211_sta *sta, | ||
| 573 | struct ieee80211_supported_band *sband, | ||
| 574 | struct ieee80211_tx_info *info, | ||
| 575 | struct ieee80211_tx_rate *rates, | ||
| 576 | int max_rates) | ||
| 577 | { | ||
| 578 | enum nl80211_chan_width chan_width; | ||
| 579 | u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; | ||
| 580 | bool has_mcs_mask; | ||
| 581 | u32 mask; | ||
| 582 | int i; | ||
| 583 | |||
| 584 | /* | ||
| 585 | * Try to enforce the rateidx mask the user wanted. skip this if the | ||
| 586 | * default mask (allow all rates) is used to save some processing for | ||
| 587 | * the common case. | ||
| 588 | */ | ||
| 589 | mask = sdata->rc_rateidx_mask[info->band]; | ||
| 590 | has_mcs_mask = sdata->rc_has_mcs_mask[info->band]; | ||
| 591 | if (mask == (1 << sband->n_bitrates) - 1 && !has_mcs_mask) | ||
| 592 | return; | ||
| 593 | |||
| 594 | if (has_mcs_mask) | ||
| 595 | memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band], | ||
| 596 | sizeof(mcs_mask)); | ||
| 597 | else | ||
| 598 | memset(mcs_mask, 0xff, sizeof(mcs_mask)); | ||
| 599 | |||
| 600 | if (sta) { | ||
| 601 | /* Filter out rates that the STA does not support */ | ||
| 602 | mask &= sta->supp_rates[info->band]; | ||
| 603 | for (i = 0; i < sizeof(mcs_mask); i++) | ||
| 604 | mcs_mask[i] &= sta->ht_cap.mcs.rx_mask[i]; | ||
| 605 | } | ||
| 606 | |||
| 607 | /* | ||
| 608 | * Make sure the rate index selected for each TX rate is | ||
| 609 | * included in the configured mask and change the rate indexes | ||
| 610 | * if needed. | ||
| 611 | */ | ||
| 612 | chan_width = sdata->vif.bss_conf.chandef.width; | ||
| 613 | for (i = 0; i < max_rates; i++) { | ||
| 614 | /* Skip invalid rates */ | ||
| 615 | if (rates[i].idx < 0) | ||
| 616 | break; | ||
| 617 | |||
| 618 | rate_idx_match_mask(&rates[i], sband, mask, chan_width, | ||
| 619 | mcs_mask); | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 623 | void ieee80211_get_tx_rates(struct ieee80211_vif *vif, | ||
| 624 | struct ieee80211_sta *sta, | ||
| 625 | struct sk_buff *skb, | ||
| 626 | struct ieee80211_tx_rate *dest, | ||
| 627 | int max_rates) | ||
| 628 | { | ||
| 629 | struct ieee80211_sub_if_data *sdata; | ||
| 630 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 631 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 632 | struct ieee80211_supported_band *sband; | ||
| 633 | |||
| 634 | rate_control_fill_sta_table(sta, info, dest, max_rates); | ||
| 635 | |||
| 636 | if (!vif) | ||
| 637 | return; | ||
| 638 | |||
| 639 | sdata = vif_to_sdata(vif); | ||
| 640 | sband = sdata->local->hw.wiphy->bands[info->band]; | ||
| 641 | |||
| 642 | if (ieee80211_is_data(hdr->frame_control)) | ||
| 643 | rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates); | ||
| 644 | |||
| 645 | if (dest[0].idx < 0) | ||
| 646 | __rate_control_send_low(&sdata->local->hw, sband, sta, info); | ||
| 647 | |||
| 648 | if (sta) | ||
| 649 | rate_fixup_ratelist(vif, sband, info, dest, max_rates); | ||
| 650 | } | ||
| 651 | EXPORT_SYMBOL(ieee80211_get_tx_rates); | ||
| 652 | |||
| 429 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 653 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
| 430 | struct sta_info *sta, | 654 | struct sta_info *sta, |
| 431 | struct ieee80211_tx_rate_control *txrc) | 655 | struct ieee80211_tx_rate_control *txrc) |
| @@ -435,8 +659,6 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | |||
| 435 | struct ieee80211_sta *ista = NULL; | 659 | struct ieee80211_sta *ista = NULL; |
| 436 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | 660 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); |
| 437 | int i; | 661 | int i; |
| 438 | u32 mask; | ||
| 439 | u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; | ||
| 440 | 662 | ||
| 441 | if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) { | 663 | if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) { |
| 442 | ista = &sta->sta; | 664 | ista = &sta->sta; |
| @@ -454,37 +676,27 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | |||
| 454 | 676 | ||
| 455 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); | 677 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); |
| 456 | 678 | ||
| 457 | /* | 679 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE) |
| 458 | * Try to enforce the rateidx mask the user wanted. skip this if the | 680 | return; |
| 459 | * default mask (allow all rates) is used to save some processing for | 681 | |
| 460 | * the common case. | 682 | ieee80211_get_tx_rates(&sdata->vif, ista, txrc->skb, |
| 461 | */ | 683 | info->control.rates, |
| 462 | mask = sdata->rc_rateidx_mask[info->band]; | 684 | ARRAY_SIZE(info->control.rates)); |
| 463 | memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band], | 685 | } |
| 464 | sizeof(mcs_mask)); | ||
| 465 | if (mask != (1 << txrc->sband->n_bitrates) - 1) { | ||
| 466 | if (sta) { | ||
| 467 | /* Filter out rates that the STA does not support */ | ||
| 468 | mask &= sta->sta.supp_rates[info->band]; | ||
| 469 | for (i = 0; i < sizeof(mcs_mask); i++) | ||
| 470 | mcs_mask[i] &= sta->sta.ht_cap.mcs.rx_mask[i]; | ||
| 471 | } | ||
| 472 | /* | ||
| 473 | * Make sure the rate index selected for each TX rate is | ||
| 474 | * included in the configured mask and change the rate indexes | ||
| 475 | * if needed. | ||
| 476 | */ | ||
| 477 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
| 478 | /* Skip invalid rates */ | ||
| 479 | if (info->control.rates[i].idx < 0) | ||
| 480 | break; | ||
| 481 | rate_idx_match_mask(&info->control.rates[i], txrc, | ||
| 482 | mask, mcs_mask); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | 686 | ||
| 486 | BUG_ON(info->control.rates[0].idx < 0); | 687 | int rate_control_set_rates(struct ieee80211_hw *hw, |
| 688 | struct ieee80211_sta *pubsta, | ||
| 689 | struct ieee80211_sta_rates *rates) | ||
| 690 | { | ||
| 691 | struct ieee80211_sta_rates *old = rcu_dereference(pubsta->rates); | ||
| 692 | |||
| 693 | rcu_assign_pointer(pubsta->rates, rates); | ||
| 694 | if (old) | ||
| 695 | kfree_rcu(old, rcu_head); | ||
| 696 | |||
| 697 | return 0; | ||
| 487 | } | 698 | } |
| 699 | EXPORT_SYMBOL(rate_control_set_rates); | ||
| 488 | 700 | ||
| 489 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | 701 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, |
| 490 | const char *name) | 702 | const char *name) |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 1c36c9b4fa4a..ac7ef5414bde 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
| @@ -84,6 +84,50 @@ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static void | 86 | static void |
| 87 | minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *ratetbl, | ||
| 88 | int offset, int idx) | ||
| 89 | { | ||
| 90 | struct minstrel_rate *r = &mi->r[idx]; | ||
| 91 | |||
| 92 | ratetbl->rate[offset].idx = r->rix; | ||
| 93 | ratetbl->rate[offset].count = r->adjusted_retry_count; | ||
| 94 | ratetbl->rate[offset].count_cts = r->retry_count_cts; | ||
| 95 | ratetbl->rate[offset].count_rts = r->retry_count_rtscts; | ||
| 96 | } | ||
| 97 | |||
| 98 | static void | ||
| 99 | minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | ||
| 100 | { | ||
| 101 | struct ieee80211_sta_rates *ratetbl; | ||
| 102 | int i = 0; | ||
| 103 | |||
| 104 | ratetbl = kzalloc(sizeof(*ratetbl), GFP_ATOMIC); | ||
| 105 | if (!ratetbl) | ||
| 106 | return; | ||
| 107 | |||
| 108 | /* Start with max_tp_rate */ | ||
| 109 | minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[0]); | ||
| 110 | |||
| 111 | if (mp->hw->max_rates >= 3) { | ||
| 112 | /* At least 3 tx rates supported, use max_tp_rate2 next */ | ||
| 113 | minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[1]); | ||
| 114 | } | ||
| 115 | |||
| 116 | if (mp->hw->max_rates >= 2) { | ||
| 117 | /* At least 2 tx rates supported, use max_prob_rate next */ | ||
| 118 | minstrel_set_rate(mi, ratetbl, i++, mi->max_prob_rate); | ||
| 119 | } | ||
| 120 | |||
| 121 | /* Use lowest rate last */ | ||
| 122 | ratetbl->rate[i].idx = mi->lowest_rix; | ||
| 123 | ratetbl->rate[i].count = mp->max_retry; | ||
| 124 | ratetbl->rate[i].count_cts = mp->max_retry; | ||
| 125 | ratetbl->rate[i].count_rts = mp->max_retry; | ||
| 126 | |||
| 127 | rate_control_set_rates(mp->hw, mi->sta, ratetbl); | ||
| 128 | } | ||
| 129 | |||
| 130 | static void | ||
| 87 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | 131 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) |
| 88 | { | 132 | { |
| 89 | u8 tmp_tp_rate[MAX_THR_RATES]; | 133 | u8 tmp_tp_rate[MAX_THR_RATES]; |
| @@ -161,6 +205,8 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
| 161 | 205 | ||
| 162 | /* Reset update timer */ | 206 | /* Reset update timer */ |
| 163 | mi->stats_update = jiffies; | 207 | mi->stats_update = jiffies; |
| 208 | |||
| 209 | minstrel_update_rates(mp, mi); | ||
| 164 | } | 210 | } |
| 165 | 211 | ||
| 166 | static void | 212 | static void |
| @@ -209,9 +255,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr, | |||
| 209 | { | 255 | { |
| 210 | unsigned int retry = mr->adjusted_retry_count; | 256 | unsigned int retry = mr->adjusted_retry_count; |
| 211 | 257 | ||
| 212 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | 258 | if (info->control.use_rts) |
| 213 | retry = max(2U, min(mr->retry_count_rtscts, retry)); | 259 | retry = max(2U, min(mr->retry_count_rtscts, retry)); |
| 214 | else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 260 | else if (info->control.use_cts_prot) |
| 215 | retry = max(2U, min(mr->retry_count_cts, retry)); | 261 | retry = max(2U, min(mr->retry_count_cts, retry)); |
| 216 | return retry; | 262 | return retry; |
| 217 | } | 263 | } |
| @@ -240,13 +286,12 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
| 240 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 286 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 241 | struct minstrel_sta_info *mi = priv_sta; | 287 | struct minstrel_sta_info *mi = priv_sta; |
| 242 | struct minstrel_priv *mp = priv; | 288 | struct minstrel_priv *mp = priv; |
| 243 | struct ieee80211_tx_rate *ar = info->control.rates; | 289 | struct ieee80211_tx_rate *rate = &info->control.rates[0]; |
| 244 | unsigned int ndx, sample_ndx = 0; | 290 | struct minstrel_rate *msr, *mr; |
| 291 | unsigned int ndx; | ||
| 245 | bool mrr_capable; | 292 | bool mrr_capable; |
| 246 | bool indirect_rate_sampling = false; | 293 | bool prev_sample = mi->prev_sample; |
| 247 | bool rate_sampling = false; | 294 | int delta; |
| 248 | int i, delta; | ||
| 249 | int mrr_ndx[3]; | ||
| 250 | int sampling_ratio; | 295 | int sampling_ratio; |
| 251 | 296 | ||
| 252 | /* management/no-ack frames do not use rate control */ | 297 | /* management/no-ack frames do not use rate control */ |
| @@ -262,107 +307,75 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
| 262 | else | 307 | else |
| 263 | sampling_ratio = mp->lookaround_rate; | 308 | sampling_ratio = mp->lookaround_rate; |
| 264 | 309 | ||
| 265 | /* init rateindex [ndx] with max throughput rate */ | ||
| 266 | ndx = mi->max_tp_rate[0]; | ||
| 267 | |||
| 268 | /* increase sum packet counter */ | 310 | /* increase sum packet counter */ |
| 269 | mi->packet_count++; | 311 | mi->packet_count++; |
| 270 | 312 | ||
| 271 | delta = (mi->packet_count * sampling_ratio / 100) - | 313 | delta = (mi->packet_count * sampling_ratio / 100) - |
| 272 | (mi->sample_count + mi->sample_deferred / 2); | 314 | (mi->sample_count + mi->sample_deferred / 2); |
| 273 | 315 | ||
| 274 | /* delta > 0: sampling required */ | 316 | /* delta < 0: no sampling required */ |
| 275 | if ((delta > 0) && (mrr_capable || !mi->prev_sample)) { | 317 | mi->prev_sample = false; |
| 276 | struct minstrel_rate *msr; | 318 | if (delta < 0 || (!mrr_capable && prev_sample)) |
| 277 | if (mi->packet_count >= 10000) { | 319 | return; |
| 278 | mi->sample_deferred = 0; | ||
| 279 | mi->sample_count = 0; | ||
| 280 | mi->packet_count = 0; | ||
| 281 | } else if (delta > mi->n_rates * 2) { | ||
| 282 | /* With multi-rate retry, not every planned sample | ||
| 283 | * attempt actually gets used, due to the way the retry | ||
| 284 | * chain is set up - [max_tp,sample,prob,lowest] for | ||
| 285 | * sample_rate < max_tp. | ||
| 286 | * | ||
| 287 | * If there's too much sampling backlog and the link | ||
| 288 | * starts getting worse, minstrel would start bursting | ||
| 289 | * out lots of sampling frames, which would result | ||
| 290 | * in a large throughput loss. */ | ||
| 291 | mi->sample_count += (delta - mi->n_rates * 2); | ||
| 292 | } | ||
| 293 | 320 | ||
| 294 | /* get next random rate sample */ | 321 | if (mi->packet_count >= 10000) { |
| 295 | sample_ndx = minstrel_get_next_sample(mi); | 322 | mi->sample_deferred = 0; |
| 296 | msr = &mi->r[sample_ndx]; | 323 | mi->sample_count = 0; |
| 297 | rate_sampling = true; | 324 | mi->packet_count = 0; |
| 298 | 325 | } else if (delta > mi->n_rates * 2) { | |
| 299 | /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) | 326 | /* With multi-rate retry, not every planned sample |
| 300 | * rate sampling method should be used. | 327 | * attempt actually gets used, due to the way the retry |
| 301 | * Respect such rates that are not sampled for 20 interations. | 328 | * chain is set up - [max_tp,sample,prob,lowest] for |
| 302 | */ | 329 | * sample_rate < max_tp. |
| 303 | if (mrr_capable && | 330 | * |
| 304 | msr->perfect_tx_time > mi->r[ndx].perfect_tx_time && | 331 | * If there's too much sampling backlog and the link |
| 305 | msr->sample_skipped < 20) | 332 | * starts getting worse, minstrel would start bursting |
| 306 | indirect_rate_sampling = true; | 333 | * out lots of sampling frames, which would result |
| 307 | 334 | * in a large throughput loss. */ | |
| 308 | if (!indirect_rate_sampling) { | 335 | mi->sample_count += (delta - mi->n_rates * 2); |
| 309 | if (msr->sample_limit != 0) { | 336 | } |
| 310 | ndx = sample_ndx; | 337 | |
| 311 | mi->sample_count++; | 338 | /* get next random rate sample */ |
| 312 | if (msr->sample_limit > 0) | 339 | ndx = minstrel_get_next_sample(mi); |
| 313 | msr->sample_limit--; | 340 | msr = &mi->r[ndx]; |
| 314 | } else | 341 | mr = &mi->r[mi->max_tp_rate[0]]; |
| 315 | rate_sampling = false; | 342 | |
| 316 | } else { | 343 | /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) |
| 317 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark | 344 | * rate sampling method should be used. |
| 318 | * packets that have the sampling rate deferred to the | 345 | * Respect such rates that are not sampled for 20 interations. |
| 319 | * second MRR stage. Increase the sample counter only | 346 | */ |
| 320 | * if the deferred sample rate was actually used. | 347 | if (mrr_capable && |
| 321 | * Use the sample_deferred counter to make sure that | 348 | msr->perfect_tx_time > mr->perfect_tx_time && |
| 322 | * the sampling is not done in large bursts */ | 349 | msr->sample_skipped < 20) { |
| 323 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 350 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark |
| 324 | mi->sample_deferred++; | 351 | * packets that have the sampling rate deferred to the |
| 325 | } | 352 | * second MRR stage. Increase the sample counter only |
| 353 | * if the deferred sample rate was actually used. | ||
| 354 | * Use the sample_deferred counter to make sure that | ||
| 355 | * the sampling is not done in large bursts */ | ||
| 356 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
| 357 | rate++; | ||
| 358 | mi->sample_deferred++; | ||
| 359 | } else { | ||
| 360 | if (!msr->sample_limit != 0) | ||
| 361 | return; | ||
| 362 | |||
| 363 | mi->sample_count++; | ||
| 364 | if (msr->sample_limit > 0) | ||
| 365 | msr->sample_limit--; | ||
| 326 | } | 366 | } |
| 327 | mi->prev_sample = rate_sampling; | ||
| 328 | 367 | ||
| 329 | /* If we're not using MRR and the sampling rate already | 368 | /* If we're not using MRR and the sampling rate already |
| 330 | * has a probability of >95%, we shouldn't be attempting | 369 | * has a probability of >95%, we shouldn't be attempting |
| 331 | * to use it, as this only wastes precious airtime */ | 370 | * to use it, as this only wastes precious airtime */ |
| 332 | if (!mrr_capable && rate_sampling && | 371 | if (!mrr_capable && |
| 333 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) | 372 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) |
| 334 | ndx = mi->max_tp_rate[0]; | ||
| 335 | |||
| 336 | /* mrr setup for 1st stage */ | ||
| 337 | ar[0].idx = mi->r[ndx].rix; | ||
| 338 | ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); | ||
| 339 | |||
| 340 | /* non mrr setup for 2nd stage */ | ||
| 341 | if (!mrr_capable) { | ||
| 342 | if (!rate_sampling) | ||
| 343 | ar[0].count = mp->max_retry; | ||
| 344 | ar[1].idx = mi->lowest_rix; | ||
| 345 | ar[1].count = mp->max_retry; | ||
| 346 | return; | 373 | return; |
| 347 | } | ||
| 348 | 374 | ||
| 349 | /* mrr setup for 2nd stage */ | 375 | mi->prev_sample = true; |
| 350 | if (rate_sampling) { | ||
| 351 | if (indirect_rate_sampling) | ||
| 352 | mrr_ndx[0] = sample_ndx; | ||
| 353 | else | ||
| 354 | mrr_ndx[0] = mi->max_tp_rate[0]; | ||
| 355 | } else { | ||
| 356 | mrr_ndx[0] = mi->max_tp_rate[1]; | ||
| 357 | } | ||
| 358 | 376 | ||
| 359 | /* mrr setup for 3rd & 4th stage */ | 377 | rate->idx = mi->r[ndx].rix; |
| 360 | mrr_ndx[1] = mi->max_prob_rate; | 378 | rate->count = minstrel_get_retry_count(&mi->r[ndx], info); |
| 361 | mrr_ndx[2] = 0; | ||
| 362 | for (i = 1; i < 4; i++) { | ||
| 363 | ar[i].idx = mi->r[mrr_ndx[i - 1]].rix; | ||
| 364 | ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count; | ||
| 365 | } | ||
| 366 | } | 379 | } |
| 367 | 380 | ||
| 368 | 381 | ||
| @@ -412,12 +425,16 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
| 412 | unsigned int i, n = 0; | 425 | unsigned int i, n = 0; |
| 413 | unsigned int t_slot = 9; /* FIXME: get real slot time */ | 426 | unsigned int t_slot = 9; /* FIXME: get real slot time */ |
| 414 | 427 | ||
| 428 | mi->sta = sta; | ||
| 415 | mi->lowest_rix = rate_lowest_index(sband, sta); | 429 | mi->lowest_rix = rate_lowest_index(sband, sta); |
| 416 | ctl_rate = &sband->bitrates[mi->lowest_rix]; | 430 | ctl_rate = &sband->bitrates[mi->lowest_rix]; |
| 417 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, | 431 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, |
| 418 | ctl_rate->bitrate, | 432 | ctl_rate->bitrate, |
| 419 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); | 433 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); |
| 420 | 434 | ||
| 435 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); | ||
| 436 | mi->max_prob_rate = 0; | ||
| 437 | |||
| 421 | for (i = 0; i < sband->n_bitrates; i++) { | 438 | for (i = 0; i < sband->n_bitrates; i++) { |
| 422 | struct minstrel_rate *mr = &mi->r[n]; | 439 | struct minstrel_rate *mr = &mi->r[n]; |
| 423 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; | 440 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; |
| @@ -460,6 +477,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
| 460 | } while ((tx_time < mp->segment_size) && | 477 | } while ((tx_time < mp->segment_size) && |
| 461 | (++mr->retry_count < mp->max_retry)); | 478 | (++mr->retry_count < mp->max_retry)); |
| 462 | mr->adjusted_retry_count = mr->retry_count; | 479 | mr->adjusted_retry_count = mr->retry_count; |
| 480 | if (!(sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)) | ||
| 481 | mr->retry_count_cts = mr->retry_count; | ||
| 463 | } | 482 | } |
| 464 | 483 | ||
| 465 | for (i = n; i < sband->n_bitrates; i++) { | 484 | for (i = n; i < sband->n_bitrates; i++) { |
| @@ -471,6 +490,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
| 471 | mi->stats_update = jiffies; | 490 | mi->stats_update = jiffies; |
| 472 | 491 | ||
| 473 | init_sample_table(mi); | 492 | init_sample_table(mi); |
| 493 | minstrel_update_rates(mp, mi); | ||
| 474 | } | 494 | } |
| 475 | 495 | ||
| 476 | static void * | 496 | static void * |
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 85ebf42cb46d..f4301f4b2e41 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
| @@ -9,7 +9,8 @@ | |||
| 9 | #ifndef __RC_MINSTREL_H | 9 | #ifndef __RC_MINSTREL_H |
| 10 | #define __RC_MINSTREL_H | 10 | #define __RC_MINSTREL_H |
| 11 | 11 | ||
| 12 | #define EWMA_LEVEL 75 /* ewma weighting factor [%] */ | 12 | #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ |
| 13 | #define EWMA_DIV 128 | ||
| 13 | #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ | 14 | #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ |
| 14 | 15 | ||
| 15 | 16 | ||
| @@ -27,7 +28,7 @@ | |||
| 27 | static inline int | 28 | static inline int |
| 28 | minstrel_ewma(int old, int new, int weight) | 29 | minstrel_ewma(int old, int new, int weight) |
| 29 | { | 30 | { |
| 30 | return (new * (100 - weight) + old * weight) / 100; | 31 | return (new * (EWMA_DIV - weight) + old * weight) / EWMA_DIV; |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | 34 | ||
| @@ -62,6 +63,8 @@ struct minstrel_rate { | |||
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 64 | struct minstrel_sta_info { | 65 | struct minstrel_sta_info { |
| 66 | struct ieee80211_sta *sta; | ||
| 67 | |||
| 65 | unsigned long stats_update; | 68 | unsigned long stats_update; |
| 66 | unsigned int sp_ack_dur; | 69 | unsigned int sp_ack_dur; |
| 67 | unsigned int rate_avg; | 70 | unsigned int rate_avg; |
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index d1048348d399..fd0b9ca1570e 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c | |||
| @@ -68,7 +68,7 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
| 68 | 68 | ||
| 69 | file->private_data = ms; | 69 | file->private_data = ms; |
| 70 | p = ms->buf; | 70 | p = ms->buf; |
| 71 | p += sprintf(p, "rate throughput ewma prob this prob " | 71 | p += sprintf(p, "rate throughput ewma prob this prob " |
| 72 | "this succ/attempt success attempts\n"); | 72 | "this succ/attempt success attempts\n"); |
| 73 | for (i = 0; i < mi->n_rates; i++) { | 73 | for (i = 0; i < mi->n_rates; i++) { |
| 74 | struct minstrel_rate *mr = &mi->r[i]; | 74 | struct minstrel_rate *mr = &mi->r[i]; |
| @@ -86,7 +86,7 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
| 86 | eprob = MINSTREL_TRUNC(mr->probability * 1000); | 86 | eprob = MINSTREL_TRUNC(mr->probability * 1000); |
| 87 | 87 | ||
| 88 | p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " | 88 | p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " |
| 89 | "%3u(%3u) %8llu %8llu\n", | 89 | " %3u(%3u) %8llu %8llu\n", |
| 90 | tp / 10, tp % 10, | 90 | tp / 10, tp % 10, |
| 91 | eprob / 10, eprob % 10, | 91 | eprob / 10, eprob % 10, |
| 92 | prob / 10, prob % 10, | 92 | prob / 10, prob % 10, |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index d2b264d1311d..5b2d3012b983 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
| @@ -126,6 +126,9 @@ const struct mcs_group minstrel_mcs_groups[] = { | |||
| 126 | 126 | ||
| 127 | static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; | 127 | static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; |
| 128 | 128 | ||
| 129 | static void | ||
| 130 | minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); | ||
| 131 | |||
| 129 | /* | 132 | /* |
| 130 | * Look up an MCS group index based on mac80211 rate information | 133 | * Look up an MCS group index based on mac80211 rate information |
| 131 | */ | 134 | */ |
| @@ -244,6 +247,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 244 | struct minstrel_rate_stats *mr; | 247 | struct minstrel_rate_stats *mr; |
| 245 | int cur_prob, cur_prob_tp, cur_tp, cur_tp2; | 248 | int cur_prob, cur_prob_tp, cur_tp, cur_tp2; |
| 246 | int group, i, index; | 249 | int group, i, index; |
| 250 | bool mi_rates_valid = false; | ||
| 247 | 251 | ||
| 248 | if (mi->ampdu_packets > 0) { | 252 | if (mi->ampdu_packets > 0) { |
| 249 | mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, | 253 | mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, |
| @@ -254,11 +258,10 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 254 | 258 | ||
| 255 | mi->sample_slow = 0; | 259 | mi->sample_slow = 0; |
| 256 | mi->sample_count = 0; | 260 | mi->sample_count = 0; |
| 257 | mi->max_tp_rate = 0; | ||
| 258 | mi->max_tp_rate2 = 0; | ||
| 259 | mi->max_prob_rate = 0; | ||
| 260 | 261 | ||
| 261 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { | 262 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { |
| 263 | bool mg_rates_valid = false; | ||
| 264 | |||
| 262 | cur_prob = 0; | 265 | cur_prob = 0; |
| 263 | cur_prob_tp = 0; | 266 | cur_prob_tp = 0; |
| 264 | cur_tp = 0; | 267 | cur_tp = 0; |
| @@ -268,15 +271,24 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 268 | if (!mg->supported) | 271 | if (!mg->supported) |
| 269 | continue; | 272 | continue; |
| 270 | 273 | ||
| 271 | mg->max_tp_rate = 0; | ||
| 272 | mg->max_tp_rate2 = 0; | ||
| 273 | mg->max_prob_rate = 0; | ||
| 274 | mi->sample_count++; | 274 | mi->sample_count++; |
| 275 | 275 | ||
| 276 | for (i = 0; i < MCS_GROUP_RATES; i++) { | 276 | for (i = 0; i < MCS_GROUP_RATES; i++) { |
| 277 | if (!(mg->supported & BIT(i))) | 277 | if (!(mg->supported & BIT(i))) |
| 278 | continue; | 278 | continue; |
| 279 | 279 | ||
| 280 | /* initialize rates selections starting indexes */ | ||
| 281 | if (!mg_rates_valid) { | ||
| 282 | mg->max_tp_rate = mg->max_tp_rate2 = | ||
| 283 | mg->max_prob_rate = i; | ||
| 284 | if (!mi_rates_valid) { | ||
| 285 | mi->max_tp_rate = mi->max_tp_rate2 = | ||
| 286 | mi->max_prob_rate = i; | ||
| 287 | mi_rates_valid = true; | ||
| 288 | } | ||
| 289 | mg_rates_valid = true; | ||
| 290 | } | ||
| 291 | |||
| 280 | mr = &mg->rates[i]; | 292 | mr = &mg->rates[i]; |
| 281 | mr->retry_updated = false; | 293 | mr->retry_updated = false; |
| 282 | index = MCS_GROUP_RATES * group + i; | 294 | index = MCS_GROUP_RATES * group + i; |
| @@ -456,7 +468,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
| 456 | struct ieee80211_tx_rate *ar = info->status.rates; | 468 | struct ieee80211_tx_rate *ar = info->status.rates; |
| 457 | struct minstrel_rate_stats *rate, *rate2; | 469 | struct minstrel_rate_stats *rate, *rate2; |
| 458 | struct minstrel_priv *mp = priv; | 470 | struct minstrel_priv *mp = priv; |
| 459 | bool last; | 471 | bool last, update = false; |
| 460 | int i; | 472 | int i; |
| 461 | 473 | ||
| 462 | if (!msp->is_ht) | 474 | if (!msp->is_ht) |
| @@ -505,21 +517,29 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
| 505 | rate = minstrel_get_ratestats(mi, mi->max_tp_rate); | 517 | rate = minstrel_get_ratestats(mi, mi->max_tp_rate); |
| 506 | if (rate->attempts > 30 && | 518 | if (rate->attempts > 30 && |
| 507 | MINSTREL_FRAC(rate->success, rate->attempts) < | 519 | MINSTREL_FRAC(rate->success, rate->attempts) < |
| 508 | MINSTREL_FRAC(20, 100)) | 520 | MINSTREL_FRAC(20, 100)) { |
| 509 | minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); | 521 | minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); |
| 522 | update = true; | ||
| 523 | } | ||
| 510 | 524 | ||
| 511 | rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); | 525 | rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); |
| 512 | if (rate2->attempts > 30 && | 526 | if (rate2->attempts > 30 && |
| 513 | MINSTREL_FRAC(rate2->success, rate2->attempts) < | 527 | MINSTREL_FRAC(rate2->success, rate2->attempts) < |
| 514 | MINSTREL_FRAC(20, 100)) | 528 | MINSTREL_FRAC(20, 100)) { |
| 515 | minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); | 529 | minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); |
| 530 | update = true; | ||
| 531 | } | ||
| 516 | 532 | ||
| 517 | if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { | 533 | if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { |
| 534 | update = true; | ||
| 518 | minstrel_ht_update_stats(mp, mi); | 535 | minstrel_ht_update_stats(mp, mi); |
| 519 | if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && | 536 | if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && |
| 520 | mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) | 537 | mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) |
| 521 | minstrel_aggr_check(sta, skb); | 538 | minstrel_aggr_check(sta, skb); |
| 522 | } | 539 | } |
| 540 | |||
| 541 | if (update) | ||
| 542 | minstrel_ht_update_rates(mp, mi); | ||
| 523 | } | 543 | } |
| 524 | 544 | ||
| 525 | static void | 545 | static void |
| @@ -583,36 +603,71 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | |||
| 583 | 603 | ||
| 584 | static void | 604 | static void |
| 585 | minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | 605 | minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, |
| 586 | struct ieee80211_tx_rate *rate, int index, | 606 | struct ieee80211_sta_rates *ratetbl, int offset, int index) |
| 587 | bool sample, bool rtscts) | ||
| 588 | { | 607 | { |
| 589 | const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; | 608 | const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; |
| 590 | struct minstrel_rate_stats *mr; | 609 | struct minstrel_rate_stats *mr; |
| 610 | u8 idx; | ||
| 611 | u16 flags; | ||
| 591 | 612 | ||
| 592 | mr = minstrel_get_ratestats(mi, index); | 613 | mr = minstrel_get_ratestats(mi, index); |
| 593 | if (!mr->retry_updated) | 614 | if (!mr->retry_updated) |
| 594 | minstrel_calc_retransmit(mp, mi, index); | 615 | minstrel_calc_retransmit(mp, mi, index); |
| 595 | 616 | ||
| 596 | if (sample) | 617 | if (mr->probability < MINSTREL_FRAC(20, 100) || !mr->retry_count) { |
| 597 | rate->count = 1; | 618 | ratetbl->rate[offset].count = 2; |
| 598 | else if (mr->probability < MINSTREL_FRAC(20, 100)) | 619 | ratetbl->rate[offset].count_rts = 2; |
| 599 | rate->count = 2; | 620 | ratetbl->rate[offset].count_cts = 2; |
| 600 | else if (rtscts) | 621 | } else { |
| 601 | rate->count = mr->retry_count_rtscts; | 622 | ratetbl->rate[offset].count = mr->retry_count; |
| 602 | else | 623 | ratetbl->rate[offset].count_cts = mr->retry_count; |
| 603 | rate->count = mr->retry_count; | 624 | ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; |
| 604 | 625 | } | |
| 605 | rate->flags = 0; | ||
| 606 | if (rtscts) | ||
| 607 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
| 608 | 626 | ||
| 609 | if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { | 627 | if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { |
| 610 | rate->idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; | 628 | idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; |
| 629 | flags = 0; | ||
| 630 | } else { | ||
| 631 | idx = index % MCS_GROUP_RATES + | ||
| 632 | (group->streams - 1) * MCS_GROUP_RATES; | ||
| 633 | flags = IEEE80211_TX_RC_MCS | group->flags; | ||
| 634 | } | ||
| 635 | |||
| 636 | if (offset > 0) { | ||
| 637 | ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; | ||
| 638 | flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
| 639 | } | ||
| 640 | |||
| 641 | ratetbl->rate[offset].idx = idx; | ||
| 642 | ratetbl->rate[offset].flags = flags; | ||
| 643 | } | ||
| 644 | |||
| 645 | static void | ||
| 646 | minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | ||
| 647 | { | ||
| 648 | struct ieee80211_sta_rates *rates; | ||
| 649 | int i = 0; | ||
| 650 | |||
| 651 | rates = kzalloc(sizeof(*rates), GFP_ATOMIC); | ||
| 652 | if (!rates) | ||
| 611 | return; | 653 | return; |
| 654 | |||
| 655 | /* Start with max_tp_rate */ | ||
| 656 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate); | ||
| 657 | |||
| 658 | if (mp->hw->max_rates >= 3) { | ||
| 659 | /* At least 3 tx rates supported, use max_tp_rate2 next */ | ||
| 660 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate2); | ||
| 661 | } | ||
| 662 | |||
| 663 | if (mp->hw->max_rates >= 2) { | ||
| 664 | /* | ||
| 665 | * At least 2 tx rates supported, use max_prob_rate next */ | ||
| 666 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); | ||
| 612 | } | 667 | } |
| 613 | 668 | ||
| 614 | rate->flags |= IEEE80211_TX_RC_MCS | group->flags; | 669 | rates->rate[i].idx = -1; |
| 615 | rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; | 670 | rate_control_set_rates(mp->hw, mi->sta, rates); |
| 616 | } | 671 | } |
| 617 | 672 | ||
| 618 | static inline int | 673 | static inline int |
| @@ -702,13 +757,13 @@ static void | |||
| 702 | minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | 757 | minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, |
| 703 | struct ieee80211_tx_rate_control *txrc) | 758 | struct ieee80211_tx_rate_control *txrc) |
| 704 | { | 759 | { |
| 760 | const struct mcs_group *sample_group; | ||
| 705 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | 761 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); |
| 706 | struct ieee80211_tx_rate *ar = info->status.rates; | 762 | struct ieee80211_tx_rate *rate = &info->status.rates[0]; |
| 707 | struct minstrel_ht_sta_priv *msp = priv_sta; | 763 | struct minstrel_ht_sta_priv *msp = priv_sta; |
| 708 | struct minstrel_ht_sta *mi = &msp->ht; | 764 | struct minstrel_ht_sta *mi = &msp->ht; |
| 709 | struct minstrel_priv *mp = priv; | 765 | struct minstrel_priv *mp = priv; |
| 710 | int sample_idx; | 766 | int sample_idx; |
| 711 | bool sample = false; | ||
| 712 | 767 | ||
| 713 | if (rate_control_send_low(sta, priv_sta, txrc)) | 768 | if (rate_control_send_low(sta, priv_sta, txrc)) |
| 714 | return; | 769 | return; |
| @@ -736,51 +791,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
| 736 | } | 791 | } |
| 737 | #endif | 792 | #endif |
| 738 | 793 | ||
| 739 | if (sample_idx >= 0) { | ||
| 740 | sample = true; | ||
| 741 | minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, | ||
| 742 | true, false); | ||
| 743 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
| 744 | } else { | ||
| 745 | minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, | ||
| 746 | false, false); | ||
| 747 | } | ||
| 748 | |||
| 749 | if (mp->hw->max_rates >= 3) { | ||
| 750 | /* | ||
| 751 | * At least 3 tx rates supported, use | ||
| 752 | * sample_rate -> max_tp_rate -> max_prob_rate for sampling and | ||
| 753 | * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default. | ||
| 754 | */ | ||
| 755 | if (sample_idx >= 0) | ||
| 756 | minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, | ||
| 757 | false, false); | ||
| 758 | else | ||
| 759 | minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, | ||
| 760 | false, true); | ||
| 761 | |||
| 762 | minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, | ||
| 763 | false, !sample); | ||
| 764 | |||
| 765 | ar[3].count = 0; | ||
| 766 | ar[3].idx = -1; | ||
| 767 | } else if (mp->hw->max_rates == 2) { | ||
| 768 | /* | ||
| 769 | * Only 2 tx rates supported, use | ||
| 770 | * sample_rate -> max_prob_rate for sampling and | ||
| 771 | * max_tp_rate -> max_prob_rate by default. | ||
| 772 | */ | ||
| 773 | minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate, | ||
| 774 | false, !sample); | ||
| 775 | |||
| 776 | ar[2].count = 0; | ||
| 777 | ar[2].idx = -1; | ||
| 778 | } else { | ||
| 779 | /* Not using MRR, only use the first rate */ | ||
| 780 | ar[1].count = 0; | ||
| 781 | ar[1].idx = -1; | ||
| 782 | } | ||
| 783 | |||
| 784 | mi->total_packets++; | 794 | mi->total_packets++; |
| 785 | 795 | ||
| 786 | /* wraparound */ | 796 | /* wraparound */ |
| @@ -788,6 +798,16 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
| 788 | mi->total_packets = 0; | 798 | mi->total_packets = 0; |
| 789 | mi->sample_packets = 0; | 799 | mi->sample_packets = 0; |
| 790 | } | 800 | } |
| 801 | |||
| 802 | if (sample_idx < 0) | ||
| 803 | return; | ||
| 804 | |||
| 805 | sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; | ||
| 806 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
| 807 | rate->idx = sample_idx % MCS_GROUP_RATES + | ||
| 808 | (sample_group->streams - 1) * MCS_GROUP_RATES; | ||
| 809 | rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; | ||
| 810 | rate->count = 1; | ||
| 791 | } | 811 | } |
| 792 | 812 | ||
| 793 | static void | 813 | static void |
| @@ -837,6 +857,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
| 837 | 857 | ||
| 838 | msp->is_ht = true; | 858 | msp->is_ht = true; |
| 839 | memset(mi, 0, sizeof(*mi)); | 859 | memset(mi, 0, sizeof(*mi)); |
| 860 | |||
| 861 | mi->sta = sta; | ||
| 840 | mi->stats_update = jiffies; | 862 | mi->stats_update = jiffies; |
| 841 | 863 | ||
| 842 | ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); | 864 | ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); |
| @@ -898,6 +920,10 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
| 898 | if (!n_supported) | 920 | if (!n_supported) |
| 899 | goto use_legacy; | 921 | goto use_legacy; |
| 900 | 922 | ||
| 923 | /* create an initial rate table with the lowest supported rates */ | ||
| 924 | minstrel_ht_update_stats(mp, mi); | ||
| 925 | minstrel_ht_update_rates(mp, mi); | ||
| 926 | |||
| 901 | return; | 927 | return; |
| 902 | 928 | ||
| 903 | use_legacy: | 929 | use_legacy: |
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index 9b16e9de9923..d655586773ac 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h | |||
| @@ -65,6 +65,8 @@ struct minstrel_mcs_group_data { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | struct minstrel_ht_sta { | 67 | struct minstrel_ht_sta { |
| 68 | struct ieee80211_sta *sta; | ||
| 69 | |||
| 68 | /* ampdu length (average, per sampling interval) */ | 70 | /* ampdu length (average, per sampling interval) */ |
| 69 | unsigned int ampdu_len; | 71 | unsigned int ampdu_len; |
| 70 | unsigned int ampdu_packets; | 72 | unsigned int ampdu_packets; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2528b5a4d6d4..c8447af76ead 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2085,6 +2085,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 2085 | } | 2085 | } |
| 2086 | 2086 | ||
| 2087 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 2087 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
| 2088 | fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY); | ||
| 2088 | info = IEEE80211_SKB_CB(fwd_skb); | 2089 | info = IEEE80211_SKB_CB(fwd_skb); |
| 2089 | memset(info, 0, sizeof(*info)); | 2090 | memset(info, 0, sizeof(*info)); |
| 2090 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 2091 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
| @@ -2423,6 +2424,22 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2423 | } | 2424 | } |
| 2424 | 2425 | ||
| 2425 | break; | 2426 | break; |
| 2427 | case WLAN_CATEGORY_PUBLIC: | ||
| 2428 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | ||
| 2429 | goto invalid; | ||
| 2430 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
| 2431 | break; | ||
| 2432 | if (!rx->sta) | ||
| 2433 | break; | ||
| 2434 | if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) | ||
| 2435 | break; | ||
| 2436 | if (mgmt->u.action.u.ext_chan_switch.action_code != | ||
| 2437 | WLAN_PUB_ACTION_EXT_CHANSW_ANN) | ||
| 2438 | break; | ||
| 2439 | if (len < offsetof(struct ieee80211_mgmt, | ||
| 2440 | u.action.u.ext_chan_switch.variable)) | ||
| 2441 | goto invalid; | ||
| 2442 | goto queue; | ||
| 2426 | case WLAN_CATEGORY_VHT: | 2443 | case WLAN_CATEGORY_VHT: |
| 2427 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2444 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
| 2428 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | 2445 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && |
| @@ -2506,10 +2523,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2506 | ieee80211_process_measurement_req(sdata, mgmt, len); | 2523 | ieee80211_process_measurement_req(sdata, mgmt, len); |
| 2507 | goto handled; | 2524 | goto handled; |
| 2508 | case WLAN_ACTION_SPCT_CHL_SWITCH: | 2525 | case WLAN_ACTION_SPCT_CHL_SWITCH: |
| 2509 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 2510 | sizeof(mgmt->u.action.u.chan_switch))) | ||
| 2511 | break; | ||
| 2512 | |||
| 2513 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2526 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 2514 | break; | 2527 | break; |
| 2515 | 2528 | ||
| @@ -3042,7 +3055,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
| 3042 | !ieee80211_is_probe_resp(hdr->frame_control) && | 3055 | !ieee80211_is_probe_resp(hdr->frame_control) && |
| 3043 | !ieee80211_is_beacon(hdr->frame_control)) | 3056 | !ieee80211_is_beacon(hdr->frame_control)) |
| 3044 | return 0; | 3057 | return 0; |
| 3045 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) | 3058 | if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) && |
| 3059 | !multicast) | ||
| 3046 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 3060 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
| 3047 | break; | 3061 | break; |
| 3048 | default: | 3062 | default: |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index cb34cbbaa20c..99b103921a4b 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -98,9 +98,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /* save the ERP value so that it is available at association time */ | 100 | /* save the ERP value so that it is available at association time */ |
| 101 | if (elems->erp_info && elems->erp_info_len >= 1 && | 101 | if (elems->erp_info && (!elems->parse_error || |
| 102 | (!elems->parse_error || | 102 | !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) { |
| 103 | !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) { | ||
| 104 | bss->erp_value = elems->erp_info[0]; | 103 | bss->erp_value = elems->erp_info[0]; |
| 105 | bss->has_erp_value = true; | 104 | bss->has_erp_value = true; |
| 106 | if (!elems->parse_error) | 105 | if (!elems->parse_error) |
| @@ -182,7 +181,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) | |||
| 182 | if (baselen > skb->len) | 181 | if (baselen > skb->len) |
| 183 | return; | 182 | return; |
| 184 | 183 | ||
| 185 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); | 184 | ieee802_11_parse_elems(elements, skb->len - baselen, false, &elems); |
| 186 | 185 | ||
| 187 | channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); | 186 | channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); |
| 188 | 187 | ||
| @@ -384,7 +383,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
| 384 | { | 383 | { |
| 385 | int i; | 384 | int i; |
| 386 | struct ieee80211_sub_if_data *sdata; | 385 | struct ieee80211_sub_if_data *sdata; |
| 387 | enum ieee80211_band band = local->hw.conf.channel->band; | 386 | enum ieee80211_band band = local->hw.conf.chandef.chan->band; |
| 388 | u32 tx_flags; | 387 | u32 tx_flags; |
| 389 | 388 | ||
| 390 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; | 389 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; |
| @@ -401,7 +400,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
| 401 | local->scan_req->ssids[i].ssid_len, | 400 | local->scan_req->ssids[i].ssid_len, |
| 402 | local->scan_req->ie, local->scan_req->ie_len, | 401 | local->scan_req->ie, local->scan_req->ie_len, |
| 403 | local->scan_req->rates[band], false, | 402 | local->scan_req->rates[band], false, |
| 404 | tx_flags, local->hw.conf.channel, true); | 403 | tx_flags, local->hw.conf.chandef.chan, true); |
| 405 | 404 | ||
| 406 | /* | 405 | /* |
| 407 | * After sending probe requests, wait for probe responses | 406 | * After sending probe requests, wait for probe responses |
| @@ -467,7 +466,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
| 467 | if (local->ops->hw_scan) { | 466 | if (local->ops->hw_scan) { |
| 468 | __set_bit(SCAN_HW_SCANNING, &local->scanning); | 467 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
| 469 | } else if ((req->n_channels == 1) && | 468 | } else if ((req->n_channels == 1) && |
| 470 | (req->channels[0] == local->_oper_channel)) { | 469 | (req->channels[0] == local->_oper_chandef.chan)) { |
| 471 | /* | 470 | /* |
| 472 | * If we are scanning only on the operating channel | 471 | * If we are scanning only on the operating channel |
| 473 | * then we do not need to stop normal activities | 472 | * then we do not need to stop normal activities |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index c5899797a8d4..c215fafd7a2f 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
| @@ -28,27 +28,27 @@ | |||
| 28 | #define VIF_PR_FMT " vif:%s(%d%s)" | 28 | #define VIF_PR_FMT " vif:%s(%d%s)" |
| 29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" | 29 | #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" |
| 30 | 30 | ||
| 31 | #define CHANDEF_ENTRY __field(u32, control_freq) \ | 31 | #define CHANDEF_ENTRY __field(u32, control_freq) \ |
| 32 | __field(u32, chan_width) \ | 32 | __field(u32, chan_width) \ |
| 33 | __field(u32, center_freq1) \ | 33 | __field(u32, center_freq1) \ |
| 34 | __field(u32, center_freq2) | 34 | __field(u32, center_freq2) |
| 35 | #define CHANDEF_ASSIGN(c) \ | 35 | #define CHANDEF_ASSIGN(c) \ |
| 36 | __entry->control_freq = (c)->chan->center_freq; \ | 36 | __entry->control_freq = (c)->chan ? (c)->chan->center_freq : 0; \ |
| 37 | __entry->chan_width = (c)->width; \ | 37 | __entry->chan_width = (c)->width; \ |
| 38 | __entry->center_freq1 = (c)->center_freq1; \ | 38 | __entry->center_freq1 = (c)->center_freq1; \ |
| 39 | __entry->center_freq2 = (c)->center_freq2; | 39 | __entry->center_freq2 = (c)->center_freq2; |
| 40 | #define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz" | 40 | #define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz" |
| 41 | #define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ | 41 | #define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ |
| 42 | __entry->center_freq1, __entry->center_freq2 | 42 | __entry->center_freq1, __entry->center_freq2 |
| 43 | 43 | ||
| 44 | #define CHANCTX_ENTRY CHANDEF_ENTRY \ | 44 | #define CHANCTX_ENTRY CHANDEF_ENTRY \ |
| 45 | __field(u8, rx_chains_static) \ | 45 | __field(u8, rx_chains_static) \ |
| 46 | __field(u8, rx_chains_dynamic) | 46 | __field(u8, rx_chains_dynamic) |
| 47 | #define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \ | 47 | #define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \ |
| 48 | __entry->rx_chains_static = ctx->conf.rx_chains_static; \ | 48 | __entry->rx_chains_static = ctx->conf.rx_chains_static; \ |
| 49 | __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic | 49 | __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic |
| 50 | #define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d" | 50 | #define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d" |
| 51 | #define CHANCTX_PR_ARG CHANDEF_PR_ARG, \ | 51 | #define CHANCTX_PR_ARG CHANDEF_PR_ARG, \ |
| 52 | __entry->rx_chains_static, __entry->rx_chains_dynamic | 52 | __entry->rx_chains_static, __entry->rx_chains_dynamic |
| 53 | 53 | ||
| 54 | 54 | ||
| @@ -286,8 +286,7 @@ TRACE_EVENT(drv_config, | |||
| 286 | __field(u16, listen_interval) | 286 | __field(u16, listen_interval) |
| 287 | __field(u8, long_frame_max_tx_count) | 287 | __field(u8, long_frame_max_tx_count) |
| 288 | __field(u8, short_frame_max_tx_count) | 288 | __field(u8, short_frame_max_tx_count) |
| 289 | __field(int, center_freq) | 289 | CHANDEF_ENTRY |
| 290 | __field(int, channel_type) | ||
| 291 | __field(int, smps) | 290 | __field(int, smps) |
| 292 | ), | 291 | ), |
| 293 | 292 | ||
| @@ -303,15 +302,13 @@ TRACE_EVENT(drv_config, | |||
| 303 | local->hw.conf.long_frame_max_tx_count; | 302 | local->hw.conf.long_frame_max_tx_count; |
| 304 | __entry->short_frame_max_tx_count = | 303 | __entry->short_frame_max_tx_count = |
| 305 | local->hw.conf.short_frame_max_tx_count; | 304 | local->hw.conf.short_frame_max_tx_count; |
| 306 | __entry->center_freq = local->hw.conf.channel ? | 305 | CHANDEF_ASSIGN(&local->hw.conf.chandef) |
| 307 | local->hw.conf.channel->center_freq : 0; | ||
| 308 | __entry->channel_type = local->hw.conf.channel_type; | ||
| 309 | __entry->smps = local->hw.conf.smps_mode; | 306 | __entry->smps = local->hw.conf.smps_mode; |
| 310 | ), | 307 | ), |
| 311 | 308 | ||
| 312 | TP_printk( | 309 | TP_printk( |
| 313 | LOCAL_PR_FMT " ch:%#x freq:%d", | 310 | LOCAL_PR_FMT " ch:%#x" CHANDEF_PR_FMT, |
| 314 | LOCAL_PR_ARG, __entry->changed, __entry->center_freq | 311 | LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG |
| 315 | ) | 312 | ) |
| 316 | ); | 313 | ); |
| 317 | 314 | ||
| @@ -359,8 +356,7 @@ TRACE_EVENT(drv_bss_info_changed, | |||
| 359 | __dynamic_array(u8, ssid, info->ssid_len); | 356 | __dynamic_array(u8, ssid, info->ssid_len); |
| 360 | __field(bool, hidden_ssid); | 357 | __field(bool, hidden_ssid); |
| 361 | __field(int, txpower) | 358 | __field(int, txpower) |
| 362 | __field(u8, p2p_ctwindow) | 359 | __field(u8, p2p_oppps_ctwindow) |
| 363 | __field(bool, p2p_oppps) | ||
| 364 | ), | 360 | ), |
| 365 | 361 | ||
| 366 | TP_fast_assign( | 362 | TP_fast_assign( |
| @@ -400,8 +396,7 @@ TRACE_EVENT(drv_bss_info_changed, | |||
| 400 | memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); | 396 | memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); |
| 401 | __entry->hidden_ssid = info->hidden_ssid; | 397 | __entry->hidden_ssid = info->hidden_ssid; |
| 402 | __entry->txpower = info->txpower; | 398 | __entry->txpower = info->txpower; |
| 403 | __entry->p2p_ctwindow = info->p2p_ctwindow; | 399 | __entry->p2p_oppps_ctwindow = info->p2p_noa_attr.oppps_ctwindow; |
| 404 | __entry->p2p_oppps = info->p2p_oppps; | ||
| 405 | ), | 400 | ), |
| 406 | 401 | ||
| 407 | TP_printk( | 402 | TP_printk( |
| @@ -995,23 +990,23 @@ TRACE_EVENT(drv_channel_switch, | |||
| 995 | 990 | ||
| 996 | TP_STRUCT__entry( | 991 | TP_STRUCT__entry( |
| 997 | LOCAL_ENTRY | 992 | LOCAL_ENTRY |
| 993 | CHANDEF_ENTRY | ||
| 998 | __field(u64, timestamp) | 994 | __field(u64, timestamp) |
| 999 | __field(bool, block_tx) | 995 | __field(bool, block_tx) |
| 1000 | __field(u16, freq) | ||
| 1001 | __field(u8, count) | 996 | __field(u8, count) |
| 1002 | ), | 997 | ), |
| 1003 | 998 | ||
| 1004 | TP_fast_assign( | 999 | TP_fast_assign( |
| 1005 | LOCAL_ASSIGN; | 1000 | LOCAL_ASSIGN; |
| 1001 | CHANDEF_ASSIGN(&ch_switch->chandef) | ||
| 1006 | __entry->timestamp = ch_switch->timestamp; | 1002 | __entry->timestamp = ch_switch->timestamp; |
| 1007 | __entry->block_tx = ch_switch->block_tx; | 1003 | __entry->block_tx = ch_switch->block_tx; |
| 1008 | __entry->freq = ch_switch->channel->center_freq; | ||
| 1009 | __entry->count = ch_switch->count; | 1004 | __entry->count = ch_switch->count; |
| 1010 | ), | 1005 | ), |
| 1011 | 1006 | ||
| 1012 | TP_printk( | 1007 | TP_printk( |
| 1013 | LOCAL_PR_FMT " new freq:%u count:%d", | 1008 | LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", |
| 1014 | LOCAL_PR_ARG, __entry->freq, __entry->count | 1009 | LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count |
| 1015 | ) | 1010 | ) |
| 1016 | ); | 1011 | ); |
| 1017 | 1012 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9e67cc97b87b..9972e07a2f96 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -48,15 +48,15 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
| 48 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 48 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 49 | 49 | ||
| 50 | /* assume HW handles this */ | 50 | /* assume HW handles this */ |
| 51 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | 51 | if (tx->rate.flags & IEEE80211_TX_RC_MCS) |
| 52 | return 0; | 52 | return 0; |
| 53 | 53 | ||
| 54 | /* uh huh? */ | 54 | /* uh huh? */ |
| 55 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) | 55 | if (WARN_ON_ONCE(tx->rate.idx < 0)) |
| 56 | return 0; | 56 | return 0; |
| 57 | 57 | ||
| 58 | sband = local->hw.wiphy->bands[info->band]; | 58 | sband = local->hw.wiphy->bands[info->band]; |
| 59 | txrate = &sband->bitrates[info->control.rates[0].idx]; | 59 | txrate = &sband->bitrates[tx->rate.idx]; |
| 60 | 60 | ||
| 61 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | 61 | erp = txrate->flags & IEEE80211_RATE_ERP_G; |
| 62 | 62 | ||
| @@ -617,11 +617,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
| 617 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 617 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
| 618 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | 618 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; |
| 619 | struct ieee80211_supported_band *sband; | 619 | struct ieee80211_supported_band *sband; |
| 620 | struct ieee80211_rate *rate; | ||
| 621 | int i; | ||
| 622 | u32 len; | 620 | u32 len; |
| 623 | bool inval = false, rts = false, short_preamble = false; | ||
| 624 | struct ieee80211_tx_rate_control txrc; | 621 | struct ieee80211_tx_rate_control txrc; |
| 622 | struct ieee80211_sta_rates *ratetbl = NULL; | ||
| 625 | bool assoc = false; | 623 | bool assoc = false; |
| 626 | 624 | ||
| 627 | memset(&txrc, 0, sizeof(txrc)); | 625 | memset(&txrc, 0, sizeof(txrc)); |
| @@ -642,18 +640,23 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
| 642 | txrc.max_rate_idx = -1; | 640 | txrc.max_rate_idx = -1; |
| 643 | else | 641 | else |
| 644 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 642 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
| 645 | memcpy(txrc.rate_idx_mcs_mask, | 643 | |
| 646 | tx->sdata->rc_rateidx_mcs_mask[info->band], | 644 | if (tx->sdata->rc_has_mcs_mask[info->band]) |
| 647 | sizeof(txrc.rate_idx_mcs_mask)); | 645 | txrc.rate_idx_mcs_mask = |
| 646 | tx->sdata->rc_rateidx_mcs_mask[info->band]; | ||
| 647 | |||
| 648 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || | 648 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || |
| 649 | tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || | 649 | tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || |
| 650 | tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); | 650 | tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); |
| 651 | 651 | ||
| 652 | /* set up RTS protection if desired */ | 652 | /* set up RTS protection if desired */ |
| 653 | if (len > tx->local->hw.wiphy->rts_threshold) { | 653 | if (len > tx->local->hw.wiphy->rts_threshold) { |
| 654 | txrc.rts = rts = true; | 654 | txrc.rts = true; |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | info->control.use_rts = txrc.rts; | ||
| 658 | info->control.use_cts_prot = tx->sdata->vif.bss_conf.use_cts_prot; | ||
| 659 | |||
| 657 | /* | 660 | /* |
| 658 | * Use short preamble if the BSS can handle it, but not for | 661 | * Use short preamble if the BSS can handle it, but not for |
| 659 | * management frames unless we know the receiver can handle | 662 | * management frames unless we know the receiver can handle |
| @@ -663,7 +666,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
| 663 | if (tx->sdata->vif.bss_conf.use_short_preamble && | 666 | if (tx->sdata->vif.bss_conf.use_short_preamble && |
| 664 | (ieee80211_is_data(hdr->frame_control) || | 667 | (ieee80211_is_data(hdr->frame_control) || |
| 665 | (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | 668 | (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) |
| 666 | txrc.short_preamble = short_preamble = true; | 669 | txrc.short_preamble = true; |
| 670 | |||
| 671 | info->control.short_preamble = txrc.short_preamble; | ||
| 667 | 672 | ||
| 668 | if (tx->sta) | 673 | if (tx->sta) |
| 669 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); | 674 | assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); |
| @@ -687,16 +692,38 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
| 687 | */ | 692 | */ |
| 688 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); | 693 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); |
| 689 | 694 | ||
| 690 | if (unlikely(info->control.rates[0].idx < 0)) | 695 | if (tx->sta && !info->control.skip_table) |
| 691 | return TX_DROP; | 696 | ratetbl = rcu_dereference(tx->sta->sta.rates); |
| 697 | |||
| 698 | if (unlikely(info->control.rates[0].idx < 0)) { | ||
| 699 | if (ratetbl) { | ||
| 700 | struct ieee80211_tx_rate rate = { | ||
| 701 | .idx = ratetbl->rate[0].idx, | ||
| 702 | .flags = ratetbl->rate[0].flags, | ||
| 703 | .count = ratetbl->rate[0].count | ||
| 704 | }; | ||
| 705 | |||
| 706 | if (ratetbl->rate[0].idx < 0) | ||
| 707 | return TX_DROP; | ||
| 708 | |||
| 709 | tx->rate = rate; | ||
| 710 | } else { | ||
| 711 | return TX_DROP; | ||
| 712 | } | ||
| 713 | } else { | ||
| 714 | tx->rate = info->control.rates[0]; | ||
| 715 | } | ||
| 692 | 716 | ||
| 693 | if (txrc.reported_rate.idx < 0) { | 717 | if (txrc.reported_rate.idx < 0) { |
| 694 | txrc.reported_rate = info->control.rates[0]; | 718 | txrc.reported_rate = tx->rate; |
| 695 | if (tx->sta && ieee80211_is_data(hdr->frame_control)) | 719 | if (tx->sta && ieee80211_is_data(hdr->frame_control)) |
| 696 | tx->sta->last_tx_rate = txrc.reported_rate; | 720 | tx->sta->last_tx_rate = txrc.reported_rate; |
| 697 | } else if (tx->sta) | 721 | } else if (tx->sta) |
| 698 | tx->sta->last_tx_rate = txrc.reported_rate; | 722 | tx->sta->last_tx_rate = txrc.reported_rate; |
| 699 | 723 | ||
| 724 | if (ratetbl) | ||
| 725 | return TX_CONTINUE; | ||
| 726 | |||
| 700 | if (unlikely(!info->control.rates[0].count)) | 727 | if (unlikely(!info->control.rates[0].count)) |
| 701 | info->control.rates[0].count = 1; | 728 | info->control.rates[0].count = 1; |
| 702 | 729 | ||
| @@ -704,91 +731,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
| 704 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) | 731 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) |
| 705 | info->control.rates[0].count = 1; | 732 | info->control.rates[0].count = 1; |
| 706 | 733 | ||
| 707 | if (is_multicast_ether_addr(hdr->addr1)) { | ||
| 708 | /* | ||
| 709 | * XXX: verify the rate is in the basic rateset | ||
| 710 | */ | ||
| 711 | return TX_CONTINUE; | ||
| 712 | } | ||
| 713 | |||
| 714 | /* | ||
| 715 | * set up the RTS/CTS rate as the fastest basic rate | ||
| 716 | * that is not faster than the data rate | ||
| 717 | * | ||
| 718 | * XXX: Should this check all retry rates? | ||
| 719 | */ | ||
| 720 | if (!(info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { | ||
| 721 | s8 baserate = 0; | ||
| 722 | |||
| 723 | rate = &sband->bitrates[info->control.rates[0].idx]; | ||
| 724 | |||
| 725 | for (i = 0; i < sband->n_bitrates; i++) { | ||
| 726 | /* must be a basic rate */ | ||
| 727 | if (!(tx->sdata->vif.bss_conf.basic_rates & BIT(i))) | ||
| 728 | continue; | ||
| 729 | /* must not be faster than the data rate */ | ||
| 730 | if (sband->bitrates[i].bitrate > rate->bitrate) | ||
| 731 | continue; | ||
| 732 | /* maximum */ | ||
| 733 | if (sband->bitrates[baserate].bitrate < | ||
| 734 | sband->bitrates[i].bitrate) | ||
| 735 | baserate = i; | ||
| 736 | } | ||
| 737 | |||
| 738 | info->control.rts_cts_rate_idx = baserate; | ||
| 739 | } | ||
| 740 | |||
| 741 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
| 742 | /* | ||
| 743 | * make sure there's no valid rate following | ||
| 744 | * an invalid one, just in case drivers don't | ||
| 745 | * take the API seriously to stop at -1. | ||
| 746 | */ | ||
| 747 | if (inval) { | ||
| 748 | info->control.rates[i].idx = -1; | ||
| 749 | continue; | ||
| 750 | } | ||
| 751 | if (info->control.rates[i].idx < 0) { | ||
| 752 | inval = true; | ||
| 753 | continue; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* | ||
| 757 | * For now assume MCS is already set up correctly, this | ||
| 758 | * needs to be fixed. | ||
| 759 | */ | ||
| 760 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) { | ||
| 761 | WARN_ON(info->control.rates[i].idx > 76); | ||
| 762 | continue; | ||
| 763 | } | ||
| 764 | |||
| 765 | /* set up RTS protection if desired */ | ||
| 766 | if (rts) | ||
| 767 | info->control.rates[i].flags |= | ||
| 768 | IEEE80211_TX_RC_USE_RTS_CTS; | ||
| 769 | |||
| 770 | /* RC is busted */ | ||
| 771 | if (WARN_ON_ONCE(info->control.rates[i].idx >= | ||
| 772 | sband->n_bitrates)) { | ||
| 773 | info->control.rates[i].idx = -1; | ||
| 774 | continue; | ||
| 775 | } | ||
| 776 | |||
| 777 | rate = &sband->bitrates[info->control.rates[i].idx]; | ||
| 778 | |||
| 779 | /* set up short preamble */ | ||
| 780 | if (short_preamble && | ||
| 781 | rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
| 782 | info->control.rates[i].flags |= | ||
| 783 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
| 784 | |||
| 785 | /* set up G protection */ | ||
| 786 | if (!rts && tx->sdata->vif.bss_conf.use_cts_prot && | ||
| 787 | rate->flags & IEEE80211_RATE_ERP_G) | ||
| 788 | info->control.rates[i].flags |= | ||
| 789 | IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
| 790 | } | ||
| 791 | |||
| 792 | return TX_CONTINUE; | 734 | return TX_CONTINUE; |
| 793 | } | 735 | } |
| 794 | 736 | ||
| @@ -1709,7 +1651,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
| 1709 | if (chanctx_conf) | 1651 | if (chanctx_conf) |
| 1710 | chan = chanctx_conf->def.chan; | 1652 | chan = chanctx_conf->def.chan; |
| 1711 | else if (!local->use_chanctx) | 1653 | else if (!local->use_chanctx) |
| 1712 | chan = local->_oper_channel; | 1654 | chan = local->_oper_chandef.chan; |
| 1713 | else | 1655 | else |
| 1714 | goto fail_rcu; | 1656 | goto fail_rcu; |
| 1715 | 1657 | ||
| @@ -1843,7 +1785,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1843 | * This is the exception! WDS style interfaces are prohibited | 1785 | * This is the exception! WDS style interfaces are prohibited |
| 1844 | * when channel contexts are in used so this must be valid | 1786 | * when channel contexts are in used so this must be valid |
| 1845 | */ | 1787 | */ |
| 1846 | band = local->hw.conf.channel->band; | 1788 | band = local->hw.conf.chandef.chan->band; |
| 1847 | break; | 1789 | break; |
| 1848 | #ifdef CONFIG_MAC80211_MESH | 1790 | #ifdef CONFIG_MAC80211_MESH |
| 1849 | case NL80211_IFTYPE_MESH_POINT: | 1791 | case NL80211_IFTYPE_MESH_POINT: |
| @@ -2442,14 +2384,17 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
| 2442 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 2384 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
| 2443 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 2385 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
| 2444 | struct ieee80211_hdr *hdr; | 2386 | struct ieee80211_hdr *hdr; |
| 2445 | struct sk_buff *presp = rcu_dereference(ifibss->presp); | 2387 | struct beacon_data *presp = rcu_dereference(ifibss->presp); |
| 2446 | 2388 | ||
| 2447 | if (!presp) | 2389 | if (!presp) |
| 2448 | goto out; | 2390 | goto out; |
| 2449 | 2391 | ||
| 2450 | skb = skb_copy(presp, GFP_ATOMIC); | 2392 | skb = dev_alloc_skb(local->tx_headroom + presp->head_len); |
| 2451 | if (!skb) | 2393 | if (!skb) |
| 2452 | goto out; | 2394 | goto out; |
| 2395 | skb_reserve(skb, local->tx_headroom); | ||
| 2396 | memcpy(skb_put(skb, presp->head_len), presp->head, | ||
| 2397 | presp->head_len); | ||
| 2453 | 2398 | ||
| 2454 | hdr = (struct ieee80211_hdr *) skb->data; | 2399 | hdr = (struct ieee80211_hdr *) skb->data; |
| 2455 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 2400 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
| @@ -2499,8 +2444,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
| 2499 | txrc.max_rate_idx = -1; | 2444 | txrc.max_rate_idx = -1; |
| 2500 | else | 2445 | else |
| 2501 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 2446 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
| 2502 | memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band], | ||
| 2503 | sizeof(txrc.rate_idx_mcs_mask)); | ||
| 2504 | txrc.bss = true; | 2447 | txrc.bss = true; |
| 2505 | rate_control_get_rate(sdata, NULL, &txrc); | 2448 | rate_control_get_rate(sdata, NULL, &txrc); |
| 2506 | 2449 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a7368870c8ee..3f87fa468b1f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -485,7 +485,8 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | |||
| 485 | return true; | 485 | return true; |
| 486 | 486 | ||
| 487 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 487 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
| 488 | ret = !!local->queue_stop_reasons[queue]; | 488 | ret = test_bit(IEEE80211_QUEUE_STOP_REASON_DRIVER, |
| 489 | &local->queue_stop_reasons[queue]); | ||
| 489 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 490 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
| 490 | return ret; | 491 | return ret; |
| 491 | } | 492 | } |
| @@ -660,7 +661,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
| 660 | } | 661 | } |
| 661 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
| 662 | 663 | ||
| 663 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, |
| 664 | struct ieee802_11_elems *elems, | 665 | struct ieee802_11_elems *elems, |
| 665 | u64 filter, u32 crc) | 666 | u64 filter, u32 crc) |
| 666 | { | 667 | { |
| @@ -668,6 +669,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 668 | u8 *pos = start; | 669 | u8 *pos = start; |
| 669 | bool calc_crc = filter != 0; | 670 | bool calc_crc = filter != 0; |
| 670 | DECLARE_BITMAP(seen_elems, 256); | 671 | DECLARE_BITMAP(seen_elems, 256); |
| 672 | const u8 *ie; | ||
| 671 | 673 | ||
| 672 | bitmap_zero(seen_elems, 256); | 674 | bitmap_zero(seen_elems, 256); |
| 673 | memset(elems, 0, sizeof(*elems)); | 675 | memset(elems, 0, sizeof(*elems)); |
| @@ -715,6 +717,12 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 715 | case WLAN_EID_COUNTRY: | 717 | case WLAN_EID_COUNTRY: |
| 716 | case WLAN_EID_PWR_CONSTRAINT: | 718 | case WLAN_EID_PWR_CONSTRAINT: |
| 717 | case WLAN_EID_TIMEOUT_INTERVAL: | 719 | case WLAN_EID_TIMEOUT_INTERVAL: |
| 720 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: | ||
| 721 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | ||
| 722 | /* | ||
| 723 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible | ||
| 724 | * that if the content gets bigger it might be needed more than once | ||
| 725 | */ | ||
| 718 | if (test_bit(id, seen_elems)) { | 726 | if (test_bit(id, seen_elems)) { |
| 719 | elems->parse_error = true; | 727 | elems->parse_error = true; |
| 720 | left -= elen; | 728 | left -= elen; |
| @@ -738,17 +746,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 738 | elems->supp_rates = pos; | 746 | elems->supp_rates = pos; |
| 739 | elems->supp_rates_len = elen; | 747 | elems->supp_rates_len = elen; |
| 740 | break; | 748 | break; |
| 741 | case WLAN_EID_FH_PARAMS: | ||
| 742 | elems->fh_params = pos; | ||
| 743 | elems->fh_params_len = elen; | ||
| 744 | break; | ||
| 745 | case WLAN_EID_DS_PARAMS: | 749 | case WLAN_EID_DS_PARAMS: |
| 746 | elems->ds_params = pos; | 750 | if (elen >= 1) |
| 747 | elems->ds_params_len = elen; | 751 | elems->ds_params = pos; |
| 748 | break; | 752 | else |
| 749 | case WLAN_EID_CF_PARAMS: | 753 | elem_parse_failed = true; |
| 750 | elems->cf_params = pos; | ||
| 751 | elems->cf_params_len = elen; | ||
| 752 | break; | 754 | break; |
| 753 | case WLAN_EID_TIM: | 755 | case WLAN_EID_TIM: |
| 754 | if (elen >= sizeof(struct ieee80211_tim_ie)) { | 756 | if (elen >= sizeof(struct ieee80211_tim_ie)) { |
| @@ -757,10 +759,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 757 | } else | 759 | } else |
| 758 | elem_parse_failed = true; | 760 | elem_parse_failed = true; |
| 759 | break; | 761 | break; |
| 760 | case WLAN_EID_IBSS_PARAMS: | ||
| 761 | elems->ibss_params = pos; | ||
| 762 | elems->ibss_params_len = elen; | ||
| 763 | break; | ||
| 764 | case WLAN_EID_CHALLENGE: | 762 | case WLAN_EID_CHALLENGE: |
| 765 | elems->challenge = pos; | 763 | elems->challenge = pos; |
| 766 | elems->challenge_len = elen; | 764 | elems->challenge_len = elen; |
| @@ -790,8 +788,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 790 | elems->rsn_len = elen; | 788 | elems->rsn_len = elen; |
| 791 | break; | 789 | break; |
| 792 | case WLAN_EID_ERP_INFO: | 790 | case WLAN_EID_ERP_INFO: |
| 793 | elems->erp_info = pos; | 791 | if (elen >= 1) |
| 794 | elems->erp_info_len = elen; | 792 | elems->erp_info = pos; |
| 793 | else | ||
| 794 | elem_parse_failed = true; | ||
| 795 | break; | 795 | break; |
| 796 | case WLAN_EID_EXT_SUPP_RATES: | 796 | case WLAN_EID_EXT_SUPP_RATES: |
| 797 | elems->ext_supp_rates = pos; | 797 | elems->ext_supp_rates = pos; |
| @@ -870,12 +870,47 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 870 | } | 870 | } |
| 871 | elems->ch_switch_ie = (void *)pos; | 871 | elems->ch_switch_ie = (void *)pos; |
| 872 | break; | 872 | break; |
| 873 | case WLAN_EID_QUIET: | 873 | case WLAN_EID_EXT_CHANSWITCH_ANN: |
| 874 | if (!elems->quiet_elem) { | 874 | if (elen != sizeof(struct ieee80211_ext_chansw_ie)) { |
| 875 | elems->quiet_elem = pos; | 875 | elem_parse_failed = true; |
| 876 | elems->quiet_elem_len = elen; | 876 | break; |
| 877 | } | ||
| 878 | elems->ext_chansw_ie = (void *)pos; | ||
| 879 | break; | ||
| 880 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: | ||
| 881 | if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) { | ||
| 882 | elem_parse_failed = true; | ||
| 883 | break; | ||
| 884 | } | ||
| 885 | elems->sec_chan_offs = (void *)pos; | ||
| 886 | break; | ||
| 887 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | ||
| 888 | if (!action || | ||
| 889 | elen != sizeof(*elems->wide_bw_chansw_ie)) { | ||
| 890 | elem_parse_failed = true; | ||
| 891 | break; | ||
| 892 | } | ||
| 893 | elems->wide_bw_chansw_ie = (void *)pos; | ||
| 894 | break; | ||
| 895 | case WLAN_EID_CHANNEL_SWITCH_WRAPPER: | ||
| 896 | if (action) { | ||
| 897 | elem_parse_failed = true; | ||
| 898 | break; | ||
| 899 | } | ||
| 900 | /* | ||
| 901 | * This is a bit tricky, but as we only care about | ||
| 902 | * the wide bandwidth channel switch element, so | ||
| 903 | * just parse it out manually. | ||
| 904 | */ | ||
| 905 | ie = cfg80211_find_ie(WLAN_EID_WIDE_BW_CHANNEL_SWITCH, | ||
| 906 | pos, elen); | ||
| 907 | if (ie) { | ||
| 908 | if (ie[1] == sizeof(*elems->wide_bw_chansw_ie)) | ||
| 909 | elems->wide_bw_chansw_ie = | ||
| 910 | (void *)(ie + 2); | ||
| 911 | else | ||
| 912 | elem_parse_failed = true; | ||
| 877 | } | 913 | } |
| 878 | elems->num_of_quiet_elem++; | ||
| 879 | break; | 914 | break; |
| 880 | case WLAN_EID_COUNTRY: | 915 | case WLAN_EID_COUNTRY: |
| 881 | elems->country_elem = pos; | 916 | elems->country_elem = pos; |
| @@ -889,8 +924,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 889 | elems->pwr_constr_elem = pos; | 924 | elems->pwr_constr_elem = pos; |
| 890 | break; | 925 | break; |
| 891 | case WLAN_EID_TIMEOUT_INTERVAL: | 926 | case WLAN_EID_TIMEOUT_INTERVAL: |
| 892 | elems->timeout_int = pos; | 927 | if (elen >= sizeof(struct ieee80211_timeout_interval_ie)) |
| 893 | elems->timeout_int_len = elen; | 928 | elems->timeout_int = (void *)pos; |
| 929 | else | ||
| 930 | elem_parse_failed = true; | ||
| 894 | break; | 931 | break; |
| 895 | default: | 932 | default: |
| 896 | break; | 933 | break; |
| @@ -911,12 +948,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
| 911 | return crc; | 948 | return crc; |
| 912 | } | 949 | } |
| 913 | 950 | ||
| 914 | void ieee802_11_parse_elems(u8 *start, size_t len, | ||
| 915 | struct ieee802_11_elems *elems) | ||
| 916 | { | ||
| 917 | ieee802_11_parse_elems_crc(start, len, elems, 0, 0); | ||
| 918 | } | ||
| 919 | |||
| 920 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | 951 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
| 921 | bool bss_notify) | 952 | bool bss_notify) |
| 922 | { | 953 | { |
| @@ -1474,6 +1505,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1474 | /* add interfaces */ | 1505 | /* add interfaces */ |
| 1475 | sdata = rtnl_dereference(local->monitor_sdata); | 1506 | sdata = rtnl_dereference(local->monitor_sdata); |
| 1476 | if (sdata) { | 1507 | if (sdata) { |
| 1508 | /* in HW restart it exists already */ | ||
| 1509 | WARN_ON(local->resuming); | ||
| 1477 | res = drv_add_interface(local, sdata); | 1510 | res = drv_add_interface(local, sdata); |
| 1478 | if (WARN_ON(res)) { | 1511 | if (WARN_ON(res)) { |
| 1479 | rcu_assign_pointer(local->monitor_sdata, NULL); | 1512 | rcu_assign_pointer(local->monitor_sdata, NULL); |
| @@ -1663,6 +1696,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1663 | local->in_reconfig = false; | 1696 | local->in_reconfig = false; |
| 1664 | barrier(); | 1697 | barrier(); |
| 1665 | 1698 | ||
| 1699 | if (local->monitors == local->open_count && local->monitors > 0) | ||
| 1700 | ieee80211_add_virtual_monitor(local); | ||
| 1701 | |||
| 1666 | /* | 1702 | /* |
| 1667 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1703 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
| 1668 | * sessions can be established after a resume. | 1704 | * sessions can be established after a resume. |
| @@ -2056,7 +2092,7 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif) | |||
| 2056 | /* non-managed type inferfaces */ | 2092 | /* non-managed type inferfaces */ |
| 2057 | return 0; | 2093 | return 0; |
| 2058 | } | 2094 | } |
| 2059 | return ifmgd->ave_beacon_signal; | 2095 | return ifmgd->ave_beacon_signal / 16; |
| 2060 | } | 2096 | } |
| 2061 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); | 2097 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); |
| 2062 | 2098 | ||
| @@ -2171,8 +2207,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) | |||
| 2171 | /* currently not handled */ | 2207 | /* currently not handled */ |
| 2172 | WARN_ON(1); | 2208 | WARN_ON(1); |
| 2173 | else { | 2209 | else { |
| 2174 | cfg80211_chandef_create(&chandef, local->hw.conf.channel, | 2210 | chandef = local->hw.conf.chandef; |
| 2175 | local->hw.conf.channel_type); | ||
| 2176 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); | 2211 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); |
| 2177 | } | 2212 | } |
| 2178 | } | 2213 | } |
diff --git a/net/nfc/core.c b/net/nfc/core.c index 6ceee8e181ca..40d2527693da 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/rfkill.h> | ||
| 30 | #include <linux/nfc.h> | 31 | #include <linux/nfc.h> |
| 31 | 32 | ||
| 32 | #include <net/genetlink.h> | 33 | #include <net/genetlink.h> |
| @@ -58,6 +59,11 @@ int nfc_dev_up(struct nfc_dev *dev) | |||
| 58 | 59 | ||
| 59 | device_lock(&dev->dev); | 60 | device_lock(&dev->dev); |
| 60 | 61 | ||
| 62 | if (dev->rfkill && rfkill_blocked(dev->rfkill)) { | ||
| 63 | rc = -ERFKILL; | ||
| 64 | goto error; | ||
| 65 | } | ||
| 66 | |||
| 61 | if (!device_is_registered(&dev->dev)) { | 67 | if (!device_is_registered(&dev->dev)) { |
| 62 | rc = -ENODEV; | 68 | rc = -ENODEV; |
| 63 | goto error; | 69 | goto error; |
| @@ -117,6 +123,24 @@ error: | |||
| 117 | return rc; | 123 | return rc; |
| 118 | } | 124 | } |
| 119 | 125 | ||
| 126 | static int nfc_rfkill_set_block(void *data, bool blocked) | ||
| 127 | { | ||
| 128 | struct nfc_dev *dev = data; | ||
| 129 | |||
| 130 | pr_debug("%s blocked %d", dev_name(&dev->dev), blocked); | ||
| 131 | |||
| 132 | if (!blocked) | ||
| 133 | return 0; | ||
| 134 | |||
| 135 | nfc_dev_down(dev); | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static const struct rfkill_ops nfc_rfkill_ops = { | ||
| 141 | .set_block = nfc_rfkill_set_block, | ||
| 142 | }; | ||
| 143 | |||
| 120 | /** | 144 | /** |
| 121 | * nfc_start_poll - start polling for nfc targets | 145 | * nfc_start_poll - start polling for nfc targets |
| 122 | * | 146 | * |
| @@ -143,6 +167,11 @@ int nfc_start_poll(struct nfc_dev *dev, u32 im_protocols, u32 tm_protocols) | |||
| 143 | goto error; | 167 | goto error; |
| 144 | } | 168 | } |
| 145 | 169 | ||
| 170 | if (!dev->dev_up) { | ||
| 171 | rc = -ENODEV; | ||
| 172 | goto error; | ||
| 173 | } | ||
| 174 | |||
| 146 | if (dev->polling) { | 175 | if (dev->polling) { |
| 147 | rc = -EBUSY; | 176 | rc = -EBUSY; |
| 148 | goto error; | 177 | goto error; |
| @@ -835,6 +864,15 @@ int nfc_register_device(struct nfc_dev *dev) | |||
| 835 | pr_debug("The userspace won't be notified that the device %s was added\n", | 864 | pr_debug("The userspace won't be notified that the device %s was added\n", |
| 836 | dev_name(&dev->dev)); | 865 | dev_name(&dev->dev)); |
| 837 | 866 | ||
| 867 | dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev, | ||
| 868 | RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev); | ||
| 869 | if (dev->rfkill) { | ||
| 870 | if (rfkill_register(dev->rfkill) < 0) { | ||
| 871 | rfkill_destroy(dev->rfkill); | ||
| 872 | dev->rfkill = NULL; | ||
| 873 | } | ||
| 874 | } | ||
| 875 | |||
| 838 | return 0; | 876 | return 0; |
| 839 | } | 877 | } |
| 840 | EXPORT_SYMBOL(nfc_register_device); | 878 | EXPORT_SYMBOL(nfc_register_device); |
| @@ -852,6 +890,11 @@ void nfc_unregister_device(struct nfc_dev *dev) | |||
| 852 | 890 | ||
| 853 | id = dev->idx; | 891 | id = dev->idx; |
| 854 | 892 | ||
| 893 | if (dev->rfkill) { | ||
| 894 | rfkill_unregister(dev->rfkill); | ||
| 895 | rfkill_destroy(dev->rfkill); | ||
| 896 | } | ||
| 897 | |||
| 855 | if (dev->ops->check_presence) { | 898 | if (dev->ops->check_presence) { |
| 856 | device_lock(&dev->dev); | 899 | device_lock(&dev->dev); |
| 857 | dev->shutting_down = true; | 900 | dev->shutting_down = true; |
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index b75a9b3f9e89..094f7e27e910 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c | |||
| @@ -420,7 +420,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | /* If the socket parameters are not set, use the local ones */ | 422 | /* If the socket parameters are not set, use the local ones */ |
| 423 | miux = sock->miux > LLCP_MAX_MIUX ? local->miux : sock->miux; | 423 | miux = be16_to_cpu(sock->miux) > LLCP_MAX_MIUX ? |
| 424 | local->miux : sock->miux; | ||
| 424 | rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw; | 425 | rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw; |
| 425 | 426 | ||
| 426 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | 427 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, |
| @@ -475,7 +476,8 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
| 475 | return -ENODEV; | 476 | return -ENODEV; |
| 476 | 477 | ||
| 477 | /* If the socket parameters are not set, use the local ones */ | 478 | /* If the socket parameters are not set, use the local ones */ |
| 478 | miux = sock->miux > LLCP_MAX_MIUX ? local->miux : sock->miux; | 479 | miux = be16_to_cpu(sock->miux) > LLCP_MAX_MIUX ? |
| 480 | local->miux : sock->miux; | ||
| 479 | rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw; | 481 | rw = sock->rw > LLCP_MAX_RW ? local->rw : sock->rw; |
| 480 | 482 | ||
| 481 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | 483 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, |
| @@ -656,6 +658,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
| 656 | struct nfc_llcp_local *local; | 658 | struct nfc_llcp_local *local; |
| 657 | size_t frag_len = 0, remaining_len; | 659 | size_t frag_len = 0, remaining_len; |
| 658 | u8 *msg_data, *msg_ptr; | 660 | u8 *msg_data, *msg_ptr; |
| 661 | u16 remote_miu; | ||
| 659 | 662 | ||
| 660 | pr_debug("Send I frame len %zd\n", len); | 663 | pr_debug("Send I frame len %zd\n", len); |
| 661 | 664 | ||
| @@ -692,9 +695,11 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
| 692 | remaining_len = len; | 695 | remaining_len = len; |
| 693 | msg_ptr = msg_data; | 696 | msg_ptr = msg_data; |
| 694 | 697 | ||
| 695 | while (remaining_len > 0) { | 698 | do { |
| 699 | remote_miu = sock->remote_miu > LLCP_MAX_MIU ? | ||
| 700 | local->remote_miu : sock->remote_miu; | ||
| 696 | 701 | ||
| 697 | frag_len = min_t(size_t, sock->remote_miu, remaining_len); | 702 | frag_len = min_t(size_t, remote_miu, remaining_len); |
| 698 | 703 | ||
| 699 | pr_debug("Fragment %zd bytes remaining %zd", | 704 | pr_debug("Fragment %zd bytes remaining %zd", |
| 700 | frag_len, remaining_len); | 705 | frag_len, remaining_len); |
| @@ -706,7 +711,8 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
| 706 | 711 | ||
| 707 | skb_put(pdu, LLCP_SEQUENCE_SIZE); | 712 | skb_put(pdu, LLCP_SEQUENCE_SIZE); |
| 708 | 713 | ||
| 709 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | 714 | if (likely(frag_len > 0)) |
| 715 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | ||
| 710 | 716 | ||
| 711 | skb_queue_tail(&sock->tx_queue, pdu); | 717 | skb_queue_tail(&sock->tx_queue, pdu); |
| 712 | 718 | ||
| @@ -718,7 +724,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | |||
| 718 | 724 | ||
| 719 | remaining_len -= frag_len; | 725 | remaining_len -= frag_len; |
| 720 | msg_ptr += frag_len; | 726 | msg_ptr += frag_len; |
| 721 | } | 727 | } while (remaining_len > 0); |
| 722 | 728 | ||
| 723 | kfree(msg_data); | 729 | kfree(msg_data); |
| 724 | 730 | ||
| @@ -732,6 +738,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | |||
| 732 | struct nfc_llcp_local *local; | 738 | struct nfc_llcp_local *local; |
| 733 | size_t frag_len = 0, remaining_len; | 739 | size_t frag_len = 0, remaining_len; |
| 734 | u8 *msg_ptr, *msg_data; | 740 | u8 *msg_ptr, *msg_data; |
| 741 | u16 remote_miu; | ||
| 735 | int err; | 742 | int err; |
| 736 | 743 | ||
| 737 | pr_debug("Send UI frame len %zd\n", len); | 744 | pr_debug("Send UI frame len %zd\n", len); |
| @@ -752,9 +759,11 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | |||
| 752 | remaining_len = len; | 759 | remaining_len = len; |
| 753 | msg_ptr = msg_data; | 760 | msg_ptr = msg_data; |
| 754 | 761 | ||
| 755 | while (remaining_len > 0) { | 762 | do { |
| 763 | remote_miu = sock->remote_miu > LLCP_MAX_MIU ? | ||
| 764 | local->remote_miu : sock->remote_miu; | ||
| 756 | 765 | ||
| 757 | frag_len = min_t(size_t, sock->remote_miu, remaining_len); | 766 | frag_len = min_t(size_t, remote_miu, remaining_len); |
| 758 | 767 | ||
| 759 | pr_debug("Fragment %zd bytes remaining %zd", | 768 | pr_debug("Fragment %zd bytes remaining %zd", |
| 760 | frag_len, remaining_len); | 769 | frag_len, remaining_len); |
| @@ -768,14 +777,15 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, | |||
| 768 | 777 | ||
| 769 | pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); | 778 | pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); |
| 770 | 779 | ||
| 771 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | 780 | if (likely(frag_len > 0)) |
| 781 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | ||
| 772 | 782 | ||
| 773 | /* No need to check for the peer RW for UI frames */ | 783 | /* No need to check for the peer RW for UI frames */ |
| 774 | skb_queue_tail(&local->tx_queue, pdu); | 784 | skb_queue_tail(&local->tx_queue, pdu); |
| 775 | 785 | ||
| 776 | remaining_len -= frag_len; | 786 | remaining_len -= frag_len; |
| 777 | msg_ptr += frag_len; | 787 | msg_ptr += frag_len; |
| 778 | } | 788 | } while (remaining_len > 0); |
| 779 | 789 | ||
| 780 | kfree(msg_data); | 790 | kfree(msg_data); |
| 781 | 791 | ||
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 7de0368aff0c..9e483c8e52f8 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
| @@ -31,6 +31,8 @@ static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; | |||
| 31 | 31 | ||
| 32 | static struct list_head llcp_devices; | 32 | static struct list_head llcp_devices; |
| 33 | 33 | ||
| 34 | static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb); | ||
| 35 | |||
| 34 | void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *sk) | 36 | void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *sk) |
| 35 | { | 37 | { |
| 36 | write_lock(&l->lock); | 38 | write_lock(&l->lock); |
| @@ -45,6 +47,12 @@ void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *sk) | |||
| 45 | write_unlock(&l->lock); | 47 | write_unlock(&l->lock); |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 50 | void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock) | ||
| 51 | { | ||
| 52 | sock->remote_rw = LLCP_DEFAULT_RW; | ||
| 53 | sock->remote_miu = LLCP_MAX_MIU + 1; | ||
| 54 | } | ||
| 55 | |||
| 48 | static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) | 56 | static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) |
| 49 | { | 57 | { |
| 50 | struct nfc_llcp_local *local = sock->local; | 58 | struct nfc_llcp_local *local = sock->local; |
| @@ -68,7 +76,7 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) | |||
| 68 | } | 76 | } |
| 69 | } | 77 | } |
| 70 | 78 | ||
| 71 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | 79 | static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, |
| 72 | int err) | 80 | int err) |
| 73 | { | 81 | { |
| 74 | struct sock *sk; | 82 | struct sock *sk; |
| @@ -108,21 +116,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | |||
| 108 | 116 | ||
| 109 | bh_unlock_sock(accept_sk); | 117 | bh_unlock_sock(accept_sk); |
| 110 | } | 118 | } |
| 111 | |||
| 112 | if (listen == true) { | ||
| 113 | bh_unlock_sock(sk); | ||
| 114 | continue; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | /* | ||
| 119 | * If we have a connection less socket bound, we keep it alive | ||
| 120 | * if the device is still present. | ||
| 121 | */ | ||
| 122 | if (sk->sk_state == LLCP_BOUND && sk->sk_type == SOCK_DGRAM && | ||
| 123 | listen == true) { | ||
| 124 | bh_unlock_sock(sk); | ||
| 125 | continue; | ||
| 126 | } | 119 | } |
| 127 | 120 | ||
| 128 | if (err) | 121 | if (err) |
| @@ -137,11 +130,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, | |||
| 137 | 130 | ||
| 138 | write_unlock(&local->sockets.lock); | 131 | write_unlock(&local->sockets.lock); |
| 139 | 132 | ||
| 140 | /* | 133 | /* If we still have a device, we keep the RAW sockets alive */ |
| 141 | * If we want to keep the listening sockets alive, | 134 | if (device == true) |
| 142 | * we don't touch the RAW ones. | ||
| 143 | */ | ||
| 144 | if (listen == true) | ||
| 145 | return; | 135 | return; |
| 146 | 136 | ||
| 147 | write_lock(&local->raw_sockets.lock); | 137 | write_lock(&local->raw_sockets.lock); |
| @@ -173,9 +163,9 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) | |||
| 173 | return local; | 163 | return local; |
| 174 | } | 164 | } |
| 175 | 165 | ||
| 176 | static void local_cleanup(struct nfc_llcp_local *local, bool listen) | 166 | static void local_cleanup(struct nfc_llcp_local *local) |
| 177 | { | 167 | { |
| 178 | nfc_llcp_socket_release(local, listen, ENXIO); | 168 | nfc_llcp_socket_release(local, false, ENXIO); |
| 179 | del_timer_sync(&local->link_timer); | 169 | del_timer_sync(&local->link_timer); |
| 180 | skb_queue_purge(&local->tx_queue); | 170 | skb_queue_purge(&local->tx_queue); |
| 181 | cancel_work_sync(&local->tx_work); | 171 | cancel_work_sync(&local->tx_work); |
| @@ -194,7 +184,7 @@ static void local_release(struct kref *ref) | |||
| 194 | local = container_of(ref, struct nfc_llcp_local, ref); | 184 | local = container_of(ref, struct nfc_llcp_local, ref); |
| 195 | 185 | ||
| 196 | list_del(&local->list); | 186 | list_del(&local->list); |
| 197 | local_cleanup(local, false); | 187 | local_cleanup(local); |
| 198 | kfree(local); | 188 | kfree(local); |
| 199 | } | 189 | } |
| 200 | 190 | ||
| @@ -1116,6 +1106,12 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, | |||
| 1116 | dsap = nfc_llcp_dsap(skb); | 1106 | dsap = nfc_llcp_dsap(skb); |
| 1117 | ssap = nfc_llcp_ssap(skb); | 1107 | ssap = nfc_llcp_ssap(skb); |
| 1118 | 1108 | ||
| 1109 | if ((dsap == 0) && (ssap == 0)) { | ||
| 1110 | pr_debug("Connection termination"); | ||
| 1111 | nfc_dep_link_down(local->dev); | ||
| 1112 | return; | ||
| 1113 | } | ||
| 1114 | |||
| 1119 | llcp_sock = nfc_llcp_sock_get(local, dsap, ssap); | 1115 | llcp_sock = nfc_llcp_sock_get(local, dsap, ssap); |
| 1120 | if (llcp_sock == NULL) { | 1116 | if (llcp_sock == NULL) { |
| 1121 | nfc_llcp_send_dm(local, dsap, ssap, LLCP_DM_NOCONN); | 1117 | nfc_llcp_send_dm(local, dsap, ssap, LLCP_DM_NOCONN); |
| @@ -1349,19 +1345,54 @@ exit: | |||
| 1349 | nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len); | 1345 | nfc_llcp_send_snl_sdres(local, &llc_sdres_list, sdres_tlvs_len); |
| 1350 | } | 1346 | } |
| 1351 | 1347 | ||
| 1352 | static void nfc_llcp_rx_work(struct work_struct *work) | 1348 | static void nfc_llcp_recv_agf(struct nfc_llcp_local *local, struct sk_buff *skb) |
| 1353 | { | 1349 | { |
| 1354 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, | 1350 | u8 ptype; |
| 1355 | rx_work); | 1351 | u16 pdu_len; |
| 1356 | u8 dsap, ssap, ptype; | 1352 | struct sk_buff *new_skb; |
| 1357 | struct sk_buff *skb; | ||
| 1358 | 1353 | ||
| 1359 | skb = local->rx_pending; | 1354 | if (skb->len <= LLCP_HEADER_SIZE) { |
| 1360 | if (skb == NULL) { | 1355 | pr_err("Malformed AGF PDU\n"); |
| 1361 | pr_debug("No pending SKB\n"); | ||
| 1362 | return; | 1356 | return; |
| 1363 | } | 1357 | } |
| 1364 | 1358 | ||
| 1359 | skb_pull(skb, LLCP_HEADER_SIZE); | ||
| 1360 | |||
| 1361 | while (skb->len > LLCP_AGF_PDU_HEADER_SIZE) { | ||
| 1362 | pdu_len = skb->data[0] << 8 | skb->data[1]; | ||
| 1363 | |||
| 1364 | skb_pull(skb, LLCP_AGF_PDU_HEADER_SIZE); | ||
| 1365 | |||
| 1366 | if (pdu_len < LLCP_HEADER_SIZE || pdu_len > skb->len) { | ||
| 1367 | pr_err("Malformed AGF PDU\n"); | ||
| 1368 | return; | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | ptype = nfc_llcp_ptype(skb); | ||
| 1372 | |||
| 1373 | if (ptype == LLCP_PDU_SYMM || ptype == LLCP_PDU_AGF) | ||
| 1374 | goto next; | ||
| 1375 | |||
| 1376 | new_skb = nfc_alloc_recv_skb(pdu_len, GFP_KERNEL); | ||
| 1377 | if (new_skb == NULL) { | ||
| 1378 | pr_err("Could not allocate PDU\n"); | ||
| 1379 | return; | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | memcpy(skb_put(new_skb, pdu_len), skb->data, pdu_len); | ||
| 1383 | |||
| 1384 | nfc_llcp_rx_skb(local, new_skb); | ||
| 1385 | |||
| 1386 | kfree_skb(new_skb); | ||
| 1387 | next: | ||
| 1388 | skb_pull(skb, pdu_len); | ||
| 1389 | } | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb) | ||
| 1393 | { | ||
| 1394 | u8 dsap, ssap, ptype; | ||
| 1395 | |||
| 1365 | ptype = nfc_llcp_ptype(skb); | 1396 | ptype = nfc_llcp_ptype(skb); |
| 1366 | dsap = nfc_llcp_dsap(skb); | 1397 | dsap = nfc_llcp_dsap(skb); |
| 1367 | ssap = nfc_llcp_ssap(skb); | 1398 | ssap = nfc_llcp_ssap(skb); |
| @@ -1372,10 +1403,6 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
| 1372 | print_hex_dump(KERN_DEBUG, "LLCP Rx: ", DUMP_PREFIX_OFFSET, | 1403 | print_hex_dump(KERN_DEBUG, "LLCP Rx: ", DUMP_PREFIX_OFFSET, |
| 1373 | 16, 1, skb->data, skb->len, true); | 1404 | 16, 1, skb->data, skb->len, true); |
| 1374 | 1405 | ||
| 1375 | __net_timestamp(skb); | ||
| 1376 | |||
| 1377 | nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX); | ||
| 1378 | |||
| 1379 | switch (ptype) { | 1406 | switch (ptype) { |
| 1380 | case LLCP_PDU_SYMM: | 1407 | case LLCP_PDU_SYMM: |
| 1381 | pr_debug("SYMM\n"); | 1408 | pr_debug("SYMM\n"); |
| @@ -1418,7 +1445,30 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
| 1418 | nfc_llcp_recv_hdlc(local, skb); | 1445 | nfc_llcp_recv_hdlc(local, skb); |
| 1419 | break; | 1446 | break; |
| 1420 | 1447 | ||
| 1448 | case LLCP_PDU_AGF: | ||
| 1449 | pr_debug("AGF frame\n"); | ||
| 1450 | nfc_llcp_recv_agf(local, skb); | ||
| 1451 | break; | ||
| 1421 | } | 1452 | } |
| 1453 | } | ||
| 1454 | |||
| 1455 | static void nfc_llcp_rx_work(struct work_struct *work) | ||
| 1456 | { | ||
| 1457 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, | ||
| 1458 | rx_work); | ||
| 1459 | struct sk_buff *skb; | ||
| 1460 | |||
| 1461 | skb = local->rx_pending; | ||
| 1462 | if (skb == NULL) { | ||
| 1463 | pr_debug("No pending SKB\n"); | ||
| 1464 | return; | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | __net_timestamp(skb); | ||
| 1468 | |||
| 1469 | nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX); | ||
| 1470 | |||
| 1471 | nfc_llcp_rx_skb(local, skb); | ||
| 1422 | 1472 | ||
| 1423 | schedule_work(&local->tx_work); | 1473 | schedule_work(&local->tx_work); |
| 1424 | kfree_skb(local->rx_pending); | 1474 | kfree_skb(local->rx_pending); |
| @@ -1466,6 +1516,9 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev) | |||
| 1466 | if (local == NULL) | 1516 | if (local == NULL) |
| 1467 | return; | 1517 | return; |
| 1468 | 1518 | ||
| 1519 | local->remote_miu = LLCP_DEFAULT_MIU; | ||
| 1520 | local->remote_lto = LLCP_DEFAULT_LTO; | ||
| 1521 | |||
| 1469 | /* Close and purge all existing sockets */ | 1522 | /* Close and purge all existing sockets */ |
| 1470 | nfc_llcp_socket_release(local, true, 0); | 1523 | nfc_llcp_socket_release(local, true, 0); |
| 1471 | } | 1524 | } |
| @@ -1553,7 +1606,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) | |||
| 1553 | return; | 1606 | return; |
| 1554 | } | 1607 | } |
| 1555 | 1608 | ||
| 1556 | local_cleanup(local, false); | 1609 | local_cleanup(local); |
| 1557 | 1610 | ||
| 1558 | nfc_llcp_local_put(local); | 1611 | nfc_llcp_local_put(local); |
| 1559 | } | 1612 | } |
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 7e87a66b02ec..ff8c434f7df8 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h | |||
| @@ -31,6 +31,7 @@ enum llcp_state { | |||
| 31 | #define LLCP_MAX_LTO 0xff | 31 | #define LLCP_MAX_LTO 0xff |
| 32 | #define LLCP_MAX_RW 15 | 32 | #define LLCP_MAX_RW 15 |
| 33 | #define LLCP_MAX_MIUX 0x7ff | 33 | #define LLCP_MAX_MIUX 0x7ff |
| 34 | #define LLCP_MAX_MIU (LLCP_MAX_MIUX + 128) | ||
| 34 | 35 | ||
| 35 | #define LLCP_WKS_NUM_SAP 16 | 36 | #define LLCP_WKS_NUM_SAP 16 |
| 36 | #define LLCP_SDP_NUM_SAP 16 | 37 | #define LLCP_SDP_NUM_SAP 16 |
| @@ -124,7 +125,7 @@ struct nfc_llcp_sock { | |||
| 124 | char *service_name; | 125 | char *service_name; |
| 125 | size_t service_name_len; | 126 | size_t service_name_len; |
| 126 | u8 rw; | 127 | u8 rw; |
| 127 | u16 miux; | 128 | __be16 miux; |
| 128 | 129 | ||
| 129 | 130 | ||
| 130 | /* Remote link parameters */ | 131 | /* Remote link parameters */ |
| @@ -162,6 +163,7 @@ struct nfc_llcp_ui_cb { | |||
| 162 | 163 | ||
| 163 | #define LLCP_HEADER_SIZE 2 | 164 | #define LLCP_HEADER_SIZE 2 |
| 164 | #define LLCP_SEQUENCE_SIZE 1 | 165 | #define LLCP_SEQUENCE_SIZE 1 |
| 166 | #define LLCP_AGF_PDU_HEADER_SIZE 2 | ||
| 165 | 167 | ||
| 166 | /* LLCP versions: 1.1 is 1.0 plus SDP */ | 168 | /* LLCP versions: 1.1 is 1.0 plus SDP */ |
| 167 | #define LLCP_VERSION_10 0x10 | 169 | #define LLCP_VERSION_10 0x10 |
| @@ -210,6 +212,7 @@ struct nfc_llcp_ui_cb { | |||
| 210 | 212 | ||
| 211 | void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s); | 213 | void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s); |
| 212 | void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s); | 214 | void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s); |
| 215 | void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock); | ||
| 213 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); | 216 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); |
| 214 | struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); | 217 | struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local); |
| 215 | int nfc_llcp_local_put(struct nfc_llcp_local *local); | 218 | int nfc_llcp_local_put(struct nfc_llcp_local *local); |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index c1101e6de170..d6faa47c9bba 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
| @@ -279,7 +279,7 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, | |||
| 279 | break; | 279 | break; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | llcp_sock->miux = (u16) opt; | 282 | llcp_sock->miux = cpu_to_be16((u16) opt); |
| 283 | 283 | ||
| 284 | break; | 284 | break; |
| 285 | 285 | ||
| @@ -299,9 +299,12 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, | |||
| 299 | static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname, | 299 | static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname, |
| 300 | char __user *optval, int __user *optlen) | 300 | char __user *optval, int __user *optlen) |
| 301 | { | 301 | { |
| 302 | struct nfc_llcp_local *local; | ||
| 302 | struct sock *sk = sock->sk; | 303 | struct sock *sk = sock->sk; |
| 303 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | 304 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
| 304 | int len, err = 0; | 305 | int len, err = 0; |
| 306 | u16 miux, remote_miu; | ||
| 307 | u8 rw; | ||
| 305 | 308 | ||
| 306 | pr_debug("%p optname %d\n", sk, optname); | 309 | pr_debug("%p optname %d\n", sk, optname); |
| 307 | 310 | ||
| @@ -311,19 +314,48 @@ static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname, | |||
| 311 | if (get_user(len, optlen)) | 314 | if (get_user(len, optlen)) |
| 312 | return -EFAULT; | 315 | return -EFAULT; |
| 313 | 316 | ||
| 317 | local = llcp_sock->local; | ||
| 318 | if (!local) | ||
| 319 | return -ENODEV; | ||
| 320 | |||
| 314 | len = min_t(u32, len, sizeof(u32)); | 321 | len = min_t(u32, len, sizeof(u32)); |
| 315 | 322 | ||
| 316 | lock_sock(sk); | 323 | lock_sock(sk); |
| 317 | 324 | ||
| 318 | switch (optname) { | 325 | switch (optname) { |
| 319 | case NFC_LLCP_RW: | 326 | case NFC_LLCP_RW: |
| 320 | if (put_user(llcp_sock->rw, (u32 __user *) optval)) | 327 | rw = llcp_sock->rw > LLCP_MAX_RW ? local->rw : llcp_sock->rw; |
| 328 | if (put_user(rw, (u32 __user *) optval)) | ||
| 321 | err = -EFAULT; | 329 | err = -EFAULT; |
| 322 | 330 | ||
| 323 | break; | 331 | break; |
| 324 | 332 | ||
| 325 | case NFC_LLCP_MIUX: | 333 | case NFC_LLCP_MIUX: |
| 326 | if (put_user(llcp_sock->miux, (u32 __user *) optval)) | 334 | miux = be16_to_cpu(llcp_sock->miux) > LLCP_MAX_MIUX ? |
| 335 | be16_to_cpu(local->miux) : be16_to_cpu(llcp_sock->miux); | ||
| 336 | |||
| 337 | if (put_user(miux, (u32 __user *) optval)) | ||
| 338 | err = -EFAULT; | ||
| 339 | |||
| 340 | break; | ||
| 341 | |||
| 342 | case NFC_LLCP_REMOTE_MIU: | ||
| 343 | remote_miu = llcp_sock->remote_miu > LLCP_MAX_MIU ? | ||
| 344 | local->remote_miu : llcp_sock->remote_miu; | ||
| 345 | |||
| 346 | if (put_user(remote_miu, (u32 __user *) optval)) | ||
| 347 | err = -EFAULT; | ||
| 348 | |||
| 349 | break; | ||
| 350 | |||
| 351 | case NFC_LLCP_REMOTE_LTO: | ||
| 352 | if (put_user(local->remote_lto / 10, (u32 __user *) optval)) | ||
| 353 | err = -EFAULT; | ||
| 354 | |||
| 355 | break; | ||
| 356 | |||
| 357 | case NFC_LLCP_REMOTE_RW: | ||
| 358 | if (put_user(llcp_sock->remote_rw, (u32 __user *) optval)) | ||
| 327 | err = -EFAULT; | 359 | err = -EFAULT; |
| 328 | 360 | ||
| 329 | break; | 361 | break; |
| @@ -925,13 +957,12 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) | |||
| 925 | llcp_sock->ssap = 0; | 957 | llcp_sock->ssap = 0; |
| 926 | llcp_sock->dsap = LLCP_SAP_SDP; | 958 | llcp_sock->dsap = LLCP_SAP_SDP; |
| 927 | llcp_sock->rw = LLCP_MAX_RW + 1; | 959 | llcp_sock->rw = LLCP_MAX_RW + 1; |
| 928 | llcp_sock->miux = LLCP_MAX_MIUX + 1; | 960 | llcp_sock->miux = cpu_to_be16(LLCP_MAX_MIUX + 1); |
| 929 | llcp_sock->remote_rw = LLCP_DEFAULT_RW; | ||
| 930 | llcp_sock->remote_miu = LLCP_DEFAULT_MIU; | ||
| 931 | llcp_sock->send_n = llcp_sock->send_ack_n = 0; | 961 | llcp_sock->send_n = llcp_sock->send_ack_n = 0; |
| 932 | llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; | 962 | llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; |
| 933 | llcp_sock->remote_ready = 1; | 963 | llcp_sock->remote_ready = 1; |
| 934 | llcp_sock->reserved_ssap = LLCP_SAP_MAX; | 964 | llcp_sock->reserved_ssap = LLCP_SAP_MAX; |
| 965 | nfc_llcp_socket_remote_param_init(llcp_sock); | ||
| 935 | skb_queue_head_init(&llcp_sock->tx_queue); | 966 | skb_queue_head_init(&llcp_sock->tx_queue); |
| 936 | skb_queue_head_init(&llcp_sock->tx_pending_queue); | 967 | skb_queue_head_init(&llcp_sock->tx_pending_queue); |
| 937 | INIT_LIST_HEAD(&llcp_sock->accept_queue); | 968 | INIT_LIST_HEAD(&llcp_sock->accept_queue); |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 9b9be5279f5d..1cec5e4f3a5e 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
| @@ -587,7 +587,7 @@ static ssize_t rfkill_name_show(struct device *dev, | |||
| 587 | 587 | ||
| 588 | static const char *rfkill_get_type_str(enum rfkill_type type) | 588 | static const char *rfkill_get_type_str(enum rfkill_type type) |
| 589 | { | 589 | { |
| 590 | BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_FM + 1); | 590 | BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_NFC + 1); |
| 591 | 591 | ||
| 592 | switch (type) { | 592 | switch (type) { |
| 593 | case RFKILL_TYPE_WLAN: | 593 | case RFKILL_TYPE_WLAN: |
| @@ -604,6 +604,8 @@ static const char *rfkill_get_type_str(enum rfkill_type type) | |||
| 604 | return "gps"; | 604 | return "gps"; |
| 605 | case RFKILL_TYPE_FM: | 605 | case RFKILL_TYPE_FM: |
| 606 | return "fm"; | 606 | return "fm"; |
| 607 | case RFKILL_TYPE_NFC: | ||
| 608 | return "nfc"; | ||
| 607 | default: | 609 | default: |
| 608 | BUG(); | 610 | BUG(); |
| 609 | } | 611 | } |
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 78fc0937948d..fb076cd6f808 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c | |||
| @@ -131,6 +131,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev) | |||
| 131 | rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); | 131 | rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); |
| 132 | if (IS_ERR(rfkill->pwr_clk)) { | 132 | if (IS_ERR(rfkill->pwr_clk)) { |
| 133 | pr_warn("%s: can't find pwr_clk.\n", __func__); | 133 | pr_warn("%s: can't find pwr_clk.\n", __func__); |
| 134 | ret = PTR_ERR(rfkill->pwr_clk); | ||
| 134 | goto fail_shutdown_name; | 135 | goto fail_shutdown_name; |
| 135 | } | 136 | } |
| 136 | } | 137 | } |
| @@ -152,9 +153,11 @@ static int rfkill_gpio_probe(struct platform_device *pdev) | |||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, | 155 | rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, |
| 155 | &rfkill_gpio_ops, rfkill); | 156 | &rfkill_gpio_ops, rfkill); |
| 156 | if (!rfkill->rfkill_dev) | 157 | if (!rfkill->rfkill_dev) { |
| 158 | ret = -ENOMEM; | ||
| 157 | goto fail_shutdown; | 159 | goto fail_shutdown; |
| 160 | } | ||
| 158 | 161 | ||
| 159 | ret = rfkill_register(rfkill->rfkill_dev); | 162 | ret = rfkill_register(rfkill->rfkill_dev); |
| 160 | if (ret < 0) | 163 | if (ret < 0) |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 124e5e773fbc..fd35dae547c4 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -88,6 +88,9 @@ struct cfg80211_registered_device { | |||
| 88 | 88 | ||
| 89 | struct delayed_work dfs_update_channels_wk; | 89 | struct delayed_work dfs_update_channels_wk; |
| 90 | 90 | ||
| 91 | /* netlink port which started critical protocol (0 means not started) */ | ||
| 92 | u32 crit_proto_nlportid; | ||
| 93 | |||
| 91 | /* must be last because of the way we do wiphy_priv(), | 94 | /* must be last because of the way we do wiphy_priv(), |
| 92 | * and it should at least be aligned to NETDEV_ALIGN */ | 95 | * and it should at least be aligned to NETDEV_ALIGN */ |
| 93 | struct wiphy wiphy __aligned(NETDEV_ALIGN); | 96 | struct wiphy wiphy __aligned(NETDEV_ALIGN); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 390198bf4b36..0c7b7dd855f6 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -648,6 +648,11 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) | |||
| 648 | 648 | ||
| 649 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 649 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
| 650 | 650 | ||
| 651 | if (nlportid && rdev->crit_proto_nlportid == nlportid) { | ||
| 652 | rdev->crit_proto_nlportid = 0; | ||
| 653 | rdev_crit_proto_stop(rdev, wdev); | ||
| 654 | } | ||
| 655 | |||
| 651 | if (nlportid == wdev->ap_unexpected_nlportid) | 656 | if (nlportid == wdev->ap_unexpected_nlportid) |
| 652 | wdev->ap_unexpected_nlportid = 0; | 657 | wdev->ap_unexpected_nlportid = 0; |
| 653 | } | 658 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 671b69a3c136..afa283841e8c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -447,62 +447,69 @@ nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { | |||
| 447 | [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, | 447 | [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, |
| 448 | }; | 448 | }; |
| 449 | 449 | ||
| 450 | /* ifidx get helper */ | 450 | static int nl80211_prepare_wdev_dump(struct sk_buff *skb, |
| 451 | static int nl80211_get_ifidx(struct netlink_callback *cb) | 451 | struct netlink_callback *cb, |
| 452 | struct cfg80211_registered_device **rdev, | ||
| 453 | struct wireless_dev **wdev) | ||
| 452 | { | 454 | { |
| 453 | int res; | 455 | int err; |
| 454 | |||
| 455 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | ||
| 456 | nl80211_fam.attrbuf, nl80211_fam.maxattr, | ||
| 457 | nl80211_policy); | ||
| 458 | if (res) | ||
| 459 | return res; | ||
| 460 | |||
| 461 | if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) | ||
| 462 | return -EINVAL; | ||
| 463 | 456 | ||
| 464 | res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); | 457 | rtnl_lock(); |
| 465 | if (!res) | 458 | mutex_lock(&cfg80211_mutex); |
| 466 | return -EINVAL; | ||
| 467 | return res; | ||
| 468 | } | ||
| 469 | 459 | ||
| 470 | static int nl80211_prepare_netdev_dump(struct sk_buff *skb, | 460 | if (!cb->args[0]) { |
| 471 | struct netlink_callback *cb, | 461 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
| 472 | struct cfg80211_registered_device **rdev, | 462 | nl80211_fam.attrbuf, nl80211_fam.maxattr, |
| 473 | struct net_device **dev) | 463 | nl80211_policy); |
| 474 | { | 464 | if (err) |
| 475 | int ifidx = cb->args[0]; | 465 | goto out_unlock; |
| 476 | int err; | ||
| 477 | 466 | ||
| 478 | if (!ifidx) | 467 | *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), |
| 479 | ifidx = nl80211_get_ifidx(cb); | 468 | nl80211_fam.attrbuf); |
| 480 | if (ifidx < 0) | 469 | if (IS_ERR(*wdev)) { |
| 481 | return ifidx; | 470 | err = PTR_ERR(*wdev); |
| 471 | goto out_unlock; | ||
| 472 | } | ||
| 473 | *rdev = wiphy_to_dev((*wdev)->wiphy); | ||
| 474 | cb->args[0] = (*rdev)->wiphy_idx; | ||
| 475 | cb->args[1] = (*wdev)->identifier; | ||
| 476 | } else { | ||
| 477 | struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]); | ||
| 478 | struct wireless_dev *tmp; | ||
| 482 | 479 | ||
| 483 | cb->args[0] = ifidx; | 480 | if (!wiphy) { |
| 481 | err = -ENODEV; | ||
| 482 | goto out_unlock; | ||
| 483 | } | ||
| 484 | *rdev = wiphy_to_dev(wiphy); | ||
| 485 | *wdev = NULL; | ||
| 484 | 486 | ||
| 485 | rtnl_lock(); | 487 | mutex_lock(&(*rdev)->devlist_mtx); |
| 488 | list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { | ||
| 489 | if (tmp->identifier == cb->args[1]) { | ||
| 490 | *wdev = tmp; | ||
| 491 | break; | ||
| 492 | } | ||
| 493 | } | ||
| 494 | mutex_unlock(&(*rdev)->devlist_mtx); | ||
| 486 | 495 | ||
| 487 | *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); | 496 | if (!*wdev) { |
| 488 | if (!*dev) { | 497 | err = -ENODEV; |
| 489 | err = -ENODEV; | 498 | goto out_unlock; |
| 490 | goto out_rtnl; | 499 | } |
| 491 | } | 500 | } |
| 492 | 501 | ||
| 493 | *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); | 502 | cfg80211_lock_rdev(*rdev); |
| 494 | if (IS_ERR(*rdev)) { | ||
| 495 | err = PTR_ERR(*rdev); | ||
| 496 | goto out_rtnl; | ||
| 497 | } | ||
| 498 | 503 | ||
| 504 | mutex_unlock(&cfg80211_mutex); | ||
| 499 | return 0; | 505 | return 0; |
| 500 | out_rtnl: | 506 | out_unlock: |
| 507 | mutex_unlock(&cfg80211_mutex); | ||
| 501 | rtnl_unlock(); | 508 | rtnl_unlock(); |
| 502 | return err; | 509 | return err; |
| 503 | } | 510 | } |
| 504 | 511 | ||
| 505 | static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) | 512 | static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) |
| 506 | { | 513 | { |
| 507 | cfg80211_unlock_rdev(rdev); | 514 | cfg80211_unlock_rdev(rdev); |
| 508 | rtnl_unlock(); | 515 | rtnl_unlock(); |
| @@ -1417,6 +1424,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
| 1417 | } | 1424 | } |
| 1418 | CMD(start_p2p_device, START_P2P_DEVICE); | 1425 | CMD(start_p2p_device, START_P2P_DEVICE); |
| 1419 | CMD(set_mcast_rate, SET_MCAST_RATE); | 1426 | CMD(set_mcast_rate, SET_MCAST_RATE); |
| 1427 | if (split) { | ||
| 1428 | CMD(crit_proto_start, CRIT_PROTOCOL_START); | ||
| 1429 | CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); | ||
| 1430 | } | ||
| 1420 | 1431 | ||
| 1421 | #ifdef CONFIG_NL80211_TESTMODE | 1432 | #ifdef CONFIG_NL80211_TESTMODE |
| 1422 | CMD(testmode_cmd, TESTMODE); | 1433 | CMD(testmode_cmd, TESTMODE); |
| @@ -3525,15 +3536,20 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
| 3525 | { | 3536 | { |
| 3526 | struct station_info sinfo; | 3537 | struct station_info sinfo; |
| 3527 | struct cfg80211_registered_device *dev; | 3538 | struct cfg80211_registered_device *dev; |
| 3528 | struct net_device *netdev; | 3539 | struct wireless_dev *wdev; |
| 3529 | u8 mac_addr[ETH_ALEN]; | 3540 | u8 mac_addr[ETH_ALEN]; |
| 3530 | int sta_idx = cb->args[1]; | 3541 | int sta_idx = cb->args[2]; |
| 3531 | int err; | 3542 | int err; |
| 3532 | 3543 | ||
| 3533 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 3544 | err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); |
| 3534 | if (err) | 3545 | if (err) |
| 3535 | return err; | 3546 | return err; |
| 3536 | 3547 | ||
| 3548 | if (!wdev->netdev) { | ||
| 3549 | err = -EINVAL; | ||
| 3550 | goto out_err; | ||
| 3551 | } | ||
| 3552 | |||
| 3537 | if (!dev->ops->dump_station) { | 3553 | if (!dev->ops->dump_station) { |
| 3538 | err = -EOPNOTSUPP; | 3554 | err = -EOPNOTSUPP; |
| 3539 | goto out_err; | 3555 | goto out_err; |
| @@ -3541,7 +3557,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
| 3541 | 3557 | ||
| 3542 | while (1) { | 3558 | while (1) { |
| 3543 | memset(&sinfo, 0, sizeof(sinfo)); | 3559 | memset(&sinfo, 0, sizeof(sinfo)); |
| 3544 | err = rdev_dump_station(dev, netdev, sta_idx, | 3560 | err = rdev_dump_station(dev, wdev->netdev, sta_idx, |
| 3545 | mac_addr, &sinfo); | 3561 | mac_addr, &sinfo); |
| 3546 | if (err == -ENOENT) | 3562 | if (err == -ENOENT) |
| 3547 | break; | 3563 | break; |
| @@ -3551,7 +3567,7 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
| 3551 | if (nl80211_send_station(skb, | 3567 | if (nl80211_send_station(skb, |
| 3552 | NETLINK_CB(cb->skb).portid, | 3568 | NETLINK_CB(cb->skb).portid, |
| 3553 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3569 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
| 3554 | dev, netdev, mac_addr, | 3570 | dev, wdev->netdev, mac_addr, |
| 3555 | &sinfo) < 0) | 3571 | &sinfo) < 0) |
| 3556 | goto out; | 3572 | goto out; |
| 3557 | 3573 | ||
| @@ -3560,10 +3576,10 @@ static int nl80211_dump_station(struct sk_buff *skb, | |||
| 3560 | 3576 | ||
| 3561 | 3577 | ||
| 3562 | out: | 3578 | out: |
| 3563 | cb->args[1] = sta_idx; | 3579 | cb->args[2] = sta_idx; |
| 3564 | err = skb->len; | 3580 | err = skb->len; |
| 3565 | out_err: | 3581 | out_err: |
| 3566 | nl80211_finish_netdev_dump(dev); | 3582 | nl80211_finish_wdev_dump(dev); |
| 3567 | 3583 | ||
| 3568 | return err; | 3584 | return err; |
| 3569 | } | 3585 | } |
| @@ -4167,13 +4183,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
| 4167 | { | 4183 | { |
| 4168 | struct mpath_info pinfo; | 4184 | struct mpath_info pinfo; |
| 4169 | struct cfg80211_registered_device *dev; | 4185 | struct cfg80211_registered_device *dev; |
| 4170 | struct net_device *netdev; | 4186 | struct wireless_dev *wdev; |
| 4171 | u8 dst[ETH_ALEN]; | 4187 | u8 dst[ETH_ALEN]; |
| 4172 | u8 next_hop[ETH_ALEN]; | 4188 | u8 next_hop[ETH_ALEN]; |
| 4173 | int path_idx = cb->args[1]; | 4189 | int path_idx = cb->args[2]; |
| 4174 | int err; | 4190 | int err; |
| 4175 | 4191 | ||
| 4176 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 4192 | err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); |
| 4177 | if (err) | 4193 | if (err) |
| 4178 | return err; | 4194 | return err; |
| 4179 | 4195 | ||
| @@ -4182,14 +4198,14 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
| 4182 | goto out_err; | 4198 | goto out_err; |
| 4183 | } | 4199 | } |
| 4184 | 4200 | ||
| 4185 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | 4201 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { |
| 4186 | err = -EOPNOTSUPP; | 4202 | err = -EOPNOTSUPP; |
| 4187 | goto out_err; | 4203 | goto out_err; |
| 4188 | } | 4204 | } |
| 4189 | 4205 | ||
| 4190 | while (1) { | 4206 | while (1) { |
| 4191 | err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop, | 4207 | err = rdev_dump_mpath(dev, wdev->netdev, path_idx, dst, |
| 4192 | &pinfo); | 4208 | next_hop, &pinfo); |
| 4193 | if (err == -ENOENT) | 4209 | if (err == -ENOENT) |
| 4194 | break; | 4210 | break; |
| 4195 | if (err) | 4211 | if (err) |
| @@ -4197,7 +4213,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
| 4197 | 4213 | ||
| 4198 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, | 4214 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, |
| 4199 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 4215 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
| 4200 | netdev, dst, next_hop, | 4216 | wdev->netdev, dst, next_hop, |
| 4201 | &pinfo) < 0) | 4217 | &pinfo) < 0) |
| 4202 | goto out; | 4218 | goto out; |
| 4203 | 4219 | ||
| @@ -4206,10 +4222,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb, | |||
| 4206 | 4222 | ||
| 4207 | 4223 | ||
| 4208 | out: | 4224 | out: |
| 4209 | cb->args[1] = path_idx; | 4225 | cb->args[2] = path_idx; |
| 4210 | err = skb->len; | 4226 | err = skb->len; |
| 4211 | out_err: | 4227 | out_err: |
| 4212 | nl80211_finish_netdev_dump(dev); | 4228 | nl80211_finish_wdev_dump(dev); |
| 4213 | return err; | 4229 | return err; |
| 4214 | } | 4230 | } |
| 4215 | 4231 | ||
| @@ -5565,9 +5581,13 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | |||
| 5565 | 5581 | ||
| 5566 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); | 5582 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); |
| 5567 | 5583 | ||
| 5568 | if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) || | 5584 | if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation)) |
| 5585 | goto nla_put_failure; | ||
| 5586 | if (wdev->netdev && | ||
| 5569 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) | 5587 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) |
| 5570 | goto nla_put_failure; | 5588 | goto nla_put_failure; |
| 5589 | if (nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) | ||
| 5590 | goto nla_put_failure; | ||
| 5571 | 5591 | ||
| 5572 | bss = nla_nest_start(msg, NL80211_ATTR_BSS); | 5592 | bss = nla_nest_start(msg, NL80211_ATTR_BSS); |
| 5573 | if (!bss) | 5593 | if (!bss) |
| @@ -5647,22 +5667,18 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | |||
| 5647 | return -EMSGSIZE; | 5667 | return -EMSGSIZE; |
| 5648 | } | 5668 | } |
| 5649 | 5669 | ||
| 5650 | static int nl80211_dump_scan(struct sk_buff *skb, | 5670 | static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) |
| 5651 | struct netlink_callback *cb) | ||
| 5652 | { | 5671 | { |
| 5653 | struct cfg80211_registered_device *rdev; | 5672 | struct cfg80211_registered_device *rdev; |
| 5654 | struct net_device *dev; | ||
| 5655 | struct cfg80211_internal_bss *scan; | 5673 | struct cfg80211_internal_bss *scan; |
| 5656 | struct wireless_dev *wdev; | 5674 | struct wireless_dev *wdev; |
| 5657 | int start = cb->args[1], idx = 0; | 5675 | int start = cb->args[2], idx = 0; |
| 5658 | int err; | 5676 | int err; |
| 5659 | 5677 | ||
| 5660 | err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); | 5678 | err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); |
| 5661 | if (err) | 5679 | if (err) |
| 5662 | return err; | 5680 | return err; |
| 5663 | 5681 | ||
| 5664 | wdev = dev->ieee80211_ptr; | ||
| 5665 | |||
| 5666 | wdev_lock(wdev); | 5682 | wdev_lock(wdev); |
| 5667 | spin_lock_bh(&rdev->bss_lock); | 5683 | spin_lock_bh(&rdev->bss_lock); |
| 5668 | cfg80211_bss_expire(rdev); | 5684 | cfg80211_bss_expire(rdev); |
| @@ -5683,8 +5699,8 @@ static int nl80211_dump_scan(struct sk_buff *skb, | |||
| 5683 | spin_unlock_bh(&rdev->bss_lock); | 5699 | spin_unlock_bh(&rdev->bss_lock); |
| 5684 | wdev_unlock(wdev); | 5700 | wdev_unlock(wdev); |
| 5685 | 5701 | ||
| 5686 | cb->args[1] = idx; | 5702 | cb->args[2] = idx; |
| 5687 | nl80211_finish_netdev_dump(rdev); | 5703 | nl80211_finish_wdev_dump(rdev); |
| 5688 | 5704 | ||
| 5689 | return skb->len; | 5705 | return skb->len; |
| 5690 | } | 5706 | } |
| @@ -5753,14 +5769,19 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
| 5753 | { | 5769 | { |
| 5754 | struct survey_info survey; | 5770 | struct survey_info survey; |
| 5755 | struct cfg80211_registered_device *dev; | 5771 | struct cfg80211_registered_device *dev; |
| 5756 | struct net_device *netdev; | 5772 | struct wireless_dev *wdev; |
| 5757 | int survey_idx = cb->args[1]; | 5773 | int survey_idx = cb->args[2]; |
| 5758 | int res; | 5774 | int res; |
| 5759 | 5775 | ||
| 5760 | res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 5776 | res = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev); |
| 5761 | if (res) | 5777 | if (res) |
| 5762 | return res; | 5778 | return res; |
| 5763 | 5779 | ||
| 5780 | if (!wdev->netdev) { | ||
| 5781 | res = -EINVAL; | ||
| 5782 | goto out_err; | ||
| 5783 | } | ||
| 5784 | |||
| 5764 | if (!dev->ops->dump_survey) { | 5785 | if (!dev->ops->dump_survey) { |
| 5765 | res = -EOPNOTSUPP; | 5786 | res = -EOPNOTSUPP; |
| 5766 | goto out_err; | 5787 | goto out_err; |
| @@ -5769,7 +5790,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
| 5769 | while (1) { | 5790 | while (1) { |
| 5770 | struct ieee80211_channel *chan; | 5791 | struct ieee80211_channel *chan; |
| 5771 | 5792 | ||
| 5772 | res = rdev_dump_survey(dev, netdev, survey_idx, &survey); | 5793 | res = rdev_dump_survey(dev, wdev->netdev, survey_idx, &survey); |
| 5773 | if (res == -ENOENT) | 5794 | if (res == -ENOENT) |
| 5774 | break; | 5795 | break; |
| 5775 | if (res) | 5796 | if (res) |
| @@ -5791,17 +5812,16 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
| 5791 | if (nl80211_send_survey(skb, | 5812 | if (nl80211_send_survey(skb, |
| 5792 | NETLINK_CB(cb->skb).portid, | 5813 | NETLINK_CB(cb->skb).portid, |
| 5793 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 5814 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
| 5794 | netdev, | 5815 | wdev->netdev, &survey) < 0) |
| 5795 | &survey) < 0) | ||
| 5796 | goto out; | 5816 | goto out; |
| 5797 | survey_idx++; | 5817 | survey_idx++; |
| 5798 | } | 5818 | } |
| 5799 | 5819 | ||
| 5800 | out: | 5820 | out: |
| 5801 | cb->args[1] = survey_idx; | 5821 | cb->args[2] = survey_idx; |
| 5802 | res = skb->len; | 5822 | res = skb->len; |
| 5803 | out_err: | 5823 | out_err: |
| 5804 | nl80211_finish_netdev_dump(dev); | 5824 | nl80211_finish_wdev_dump(dev); |
| 5805 | return res; | 5825 | return res; |
| 5806 | } | 5826 | } |
| 5807 | 5827 | ||
| @@ -8143,9 +8163,11 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) | |||
| 8143 | if (!rdev->ops->stop_p2p_device) | 8163 | if (!rdev->ops->stop_p2p_device) |
| 8144 | return -EOPNOTSUPP; | 8164 | return -EOPNOTSUPP; |
| 8145 | 8165 | ||
| 8166 | mutex_lock(&rdev->devlist_mtx); | ||
| 8146 | mutex_lock(&rdev->sched_scan_mtx); | 8167 | mutex_lock(&rdev->sched_scan_mtx); |
| 8147 | cfg80211_stop_p2p_device(rdev, wdev); | 8168 | cfg80211_stop_p2p_device(rdev, wdev); |
| 8148 | mutex_unlock(&rdev->sched_scan_mtx); | 8169 | mutex_unlock(&rdev->sched_scan_mtx); |
| 8170 | mutex_unlock(&rdev->devlist_mtx); | ||
| 8149 | 8171 | ||
| 8150 | return 0; | 8172 | return 0; |
| 8151 | } | 8173 | } |
| @@ -8198,6 +8220,64 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info) | |||
| 8198 | return rdev_update_ft_ies(rdev, dev, &ft_params); | 8220 | return rdev_update_ft_ies(rdev, dev, &ft_params); |
| 8199 | } | 8221 | } |
| 8200 | 8222 | ||
| 8223 | static int nl80211_crit_protocol_start(struct sk_buff *skb, | ||
| 8224 | struct genl_info *info) | ||
| 8225 | { | ||
| 8226 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
| 8227 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
| 8228 | enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC; | ||
| 8229 | u16 duration; | ||
| 8230 | int ret; | ||
| 8231 | |||
| 8232 | if (!rdev->ops->crit_proto_start) | ||
| 8233 | return -EOPNOTSUPP; | ||
| 8234 | |||
| 8235 | if (WARN_ON(!rdev->ops->crit_proto_stop)) | ||
| 8236 | return -EINVAL; | ||
| 8237 | |||
| 8238 | if (rdev->crit_proto_nlportid) | ||
| 8239 | return -EBUSY; | ||
| 8240 | |||
| 8241 | /* determine protocol if provided */ | ||
| 8242 | if (info->attrs[NL80211_ATTR_CRIT_PROT_ID]) | ||
| 8243 | proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]); | ||
| 8244 | |||
| 8245 | if (proto >= NUM_NL80211_CRIT_PROTO) | ||
| 8246 | return -EINVAL; | ||
| 8247 | |||
| 8248 | /* timeout must be provided */ | ||
| 8249 | if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]) | ||
| 8250 | return -EINVAL; | ||
| 8251 | |||
| 8252 | duration = | ||
| 8253 | nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]); | ||
| 8254 | |||
| 8255 | if (duration > NL80211_CRIT_PROTO_MAX_DURATION) | ||
| 8256 | return -ERANGE; | ||
| 8257 | |||
| 8258 | ret = rdev_crit_proto_start(rdev, wdev, proto, duration); | ||
| 8259 | if (!ret) | ||
| 8260 | rdev->crit_proto_nlportid = info->snd_portid; | ||
| 8261 | |||
| 8262 | return ret; | ||
| 8263 | } | ||
| 8264 | |||
| 8265 | static int nl80211_crit_protocol_stop(struct sk_buff *skb, | ||
| 8266 | struct genl_info *info) | ||
| 8267 | { | ||
| 8268 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
| 8269 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
| 8270 | |||
| 8271 | if (!rdev->ops->crit_proto_stop) | ||
| 8272 | return -EOPNOTSUPP; | ||
| 8273 | |||
| 8274 | if (rdev->crit_proto_nlportid) { | ||
| 8275 | rdev->crit_proto_nlportid = 0; | ||
| 8276 | rdev_crit_proto_stop(rdev, wdev); | ||
| 8277 | } | ||
| 8278 | return 0; | ||
| 8279 | } | ||
| 8280 | |||
| 8201 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 8281 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
| 8202 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 8282 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
| 8203 | #define NL80211_FLAG_NEED_RTNL 0x04 | 8283 | #define NL80211_FLAG_NEED_RTNL 0x04 |
| @@ -8887,6 +8967,22 @@ static struct genl_ops nl80211_ops[] = { | |||
| 8887 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 8967 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 8888 | NL80211_FLAG_NEED_RTNL, | 8968 | NL80211_FLAG_NEED_RTNL, |
| 8889 | }, | 8969 | }, |
| 8970 | { | ||
| 8971 | .cmd = NL80211_CMD_CRIT_PROTOCOL_START, | ||
| 8972 | .doit = nl80211_crit_protocol_start, | ||
| 8973 | .policy = nl80211_policy, | ||
| 8974 | .flags = GENL_ADMIN_PERM, | ||
| 8975 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | ||
| 8976 | NL80211_FLAG_NEED_RTNL, | ||
| 8977 | }, | ||
| 8978 | { | ||
| 8979 | .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP, | ||
| 8980 | .doit = nl80211_crit_protocol_stop, | ||
| 8981 | .policy = nl80211_policy, | ||
| 8982 | .flags = GENL_ADMIN_PERM, | ||
| 8983 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | ||
| 8984 | NL80211_FLAG_NEED_RTNL, | ||
| 8985 | } | ||
| 8890 | }; | 8986 | }; |
| 8891 | 8987 | ||
| 8892 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 8988 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
| @@ -10632,6 +10728,45 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
| 10632 | } | 10728 | } |
| 10633 | EXPORT_SYMBOL(cfg80211_ft_event); | 10729 | EXPORT_SYMBOL(cfg80211_ft_event); |
| 10634 | 10730 | ||
| 10731 | void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp) | ||
| 10732 | { | ||
| 10733 | struct cfg80211_registered_device *rdev; | ||
| 10734 | struct sk_buff *msg; | ||
| 10735 | void *hdr; | ||
| 10736 | u32 nlportid; | ||
| 10737 | |||
| 10738 | rdev = wiphy_to_dev(wdev->wiphy); | ||
| 10739 | if (!rdev->crit_proto_nlportid) | ||
| 10740 | return; | ||
| 10741 | |||
| 10742 | nlportid = rdev->crit_proto_nlportid; | ||
| 10743 | rdev->crit_proto_nlportid = 0; | ||
| 10744 | |||
| 10745 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | ||
| 10746 | if (!msg) | ||
| 10747 | return; | ||
| 10748 | |||
| 10749 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP); | ||
| 10750 | if (!hdr) | ||
| 10751 | goto nla_put_failure; | ||
| 10752 | |||
| 10753 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | ||
| 10754 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) | ||
| 10755 | goto nla_put_failure; | ||
| 10756 | |||
| 10757 | genlmsg_end(msg, hdr); | ||
| 10758 | |||
| 10759 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); | ||
| 10760 | return; | ||
| 10761 | |||
| 10762 | nla_put_failure: | ||
| 10763 | if (hdr) | ||
| 10764 | genlmsg_cancel(msg, hdr); | ||
| 10765 | nlmsg_free(msg); | ||
| 10766 | |||
| 10767 | } | ||
| 10768 | EXPORT_SYMBOL(cfg80211_crit_proto_stopped); | ||
| 10769 | |||
| 10635 | /* initialisation/exit functions */ | 10770 | /* initialisation/exit functions */ |
| 10636 | 10771 | ||
| 10637 | int nl80211_init(void) | 10772 | int nl80211_init(void) |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index d77e1c1d3a0e..9f15f0ac824d 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
| @@ -875,7 +875,7 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
| 875 | trace_rdev_stop_p2p_device(&rdev->wiphy, wdev); | 875 | trace_rdev_stop_p2p_device(&rdev->wiphy, wdev); |
| 876 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); | 876 | rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); |
| 877 | trace_rdev_return_void(&rdev->wiphy); | 877 | trace_rdev_return_void(&rdev->wiphy); |
| 878 | } | 878 | } |
| 879 | 879 | ||
| 880 | static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, | 880 | static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, |
| 881 | struct net_device *dev, | 881 | struct net_device *dev, |
| @@ -901,4 +901,26 @@ static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev, | |||
| 901 | return ret; | 901 | return ret; |
| 902 | } | 902 | } |
| 903 | 903 | ||
| 904 | static inline int rdev_crit_proto_start(struct cfg80211_registered_device *rdev, | ||
| 905 | struct wireless_dev *wdev, | ||
| 906 | enum nl80211_crit_proto_id protocol, | ||
| 907 | u16 duration) | ||
| 908 | { | ||
| 909 | int ret; | ||
| 910 | |||
| 911 | trace_rdev_crit_proto_start(&rdev->wiphy, wdev, protocol, duration); | ||
| 912 | ret = rdev->ops->crit_proto_start(&rdev->wiphy, wdev, | ||
| 913 | protocol, duration); | ||
| 914 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
| 915 | return ret; | ||
| 916 | } | ||
| 917 | |||
| 918 | static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev, | ||
| 919 | struct wireless_dev *wdev) | ||
| 920 | { | ||
| 921 | trace_rdev_crit_proto_stop(&rdev->wiphy, wdev); | ||
| 922 | rdev->ops->crit_proto_stop(&rdev->wiphy, wdev); | ||
| 923 | trace_rdev_return_void(&rdev->wiphy); | ||
| 924 | } | ||
| 925 | |||
| 904 | #endif /* __CFG80211_RDEV_OPS */ | 926 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index e6df52dc8c69..cc35fbaa4578 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -855,7 +855,7 @@ static void handle_channel(struct wiphy *wiphy, | |||
| 855 | return; | 855 | return; |
| 856 | 856 | ||
| 857 | REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); | 857 | REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); |
| 858 | chan->flags = IEEE80211_CHAN_DISABLED; | 858 | chan->flags |= IEEE80211_CHAN_DISABLED; |
| 859 | return; | 859 | return; |
| 860 | } | 860 | } |
| 861 | 861 | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 3c2033b8f596..ecd4fcec3c94 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
| @@ -1806,6 +1806,41 @@ TRACE_EVENT(rdev_update_ft_ies, | |||
| 1806 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md) | 1806 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md) |
| 1807 | ); | 1807 | ); |
| 1808 | 1808 | ||
| 1809 | TRACE_EVENT(rdev_crit_proto_start, | ||
| 1810 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
| 1811 | enum nl80211_crit_proto_id protocol, u16 duration), | ||
| 1812 | TP_ARGS(wiphy, wdev, protocol, duration), | ||
| 1813 | TP_STRUCT__entry( | ||
| 1814 | WIPHY_ENTRY | ||
| 1815 | WDEV_ENTRY | ||
| 1816 | __field(u16, proto) | ||
| 1817 | __field(u16, duration) | ||
| 1818 | ), | ||
| 1819 | TP_fast_assign( | ||
| 1820 | WIPHY_ASSIGN; | ||
| 1821 | WDEV_ASSIGN; | ||
| 1822 | __entry->proto = protocol; | ||
| 1823 | __entry->duration = duration; | ||
| 1824 | ), | ||
| 1825 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", proto=%x, duration=%u", | ||
| 1826 | WIPHY_PR_ARG, WDEV_PR_ARG, __entry->proto, __entry->duration) | ||
| 1827 | ); | ||
| 1828 | |||
| 1829 | TRACE_EVENT(rdev_crit_proto_stop, | ||
| 1830 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
| 1831 | TP_ARGS(wiphy, wdev), | ||
| 1832 | TP_STRUCT__entry( | ||
| 1833 | WIPHY_ENTRY | ||
| 1834 | WDEV_ENTRY | ||
| 1835 | ), | ||
| 1836 | TP_fast_assign( | ||
| 1837 | WIPHY_ASSIGN; | ||
| 1838 | WDEV_ASSIGN; | ||
| 1839 | ), | ||
| 1840 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, | ||
| 1841 | WIPHY_PR_ARG, WDEV_PR_ARG) | ||
| 1842 | ); | ||
| 1843 | |||
| 1809 | /************************************************************* | 1844 | /************************************************************* |
| 1810 | * cfg80211 exported functions traces * | 1845 | * cfg80211 exported functions traces * |
| 1811 | *************************************************************/ | 1846 | *************************************************************/ |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 6cbac99ae03d..f5ad4d94ba88 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -1155,6 +1155,26 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, | |||
| 1155 | } | 1155 | } |
| 1156 | EXPORT_SYMBOL(cfg80211_get_p2p_attr); | 1156 | EXPORT_SYMBOL(cfg80211_get_p2p_attr); |
| 1157 | 1157 | ||
| 1158 | bool ieee80211_operating_class_to_band(u8 operating_class, | ||
| 1159 | enum ieee80211_band *band) | ||
| 1160 | { | ||
| 1161 | switch (operating_class) { | ||
| 1162 | case 112: | ||
| 1163 | case 115 ... 127: | ||
| 1164 | *band = IEEE80211_BAND_5GHZ; | ||
| 1165 | return true; | ||
| 1166 | case 81: | ||
| 1167 | case 82: | ||
| 1168 | case 83: | ||
| 1169 | case 84: | ||
| 1170 | *band = IEEE80211_BAND_2GHZ; | ||
| 1171 | return true; | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | return false; | ||
| 1175 | } | ||
| 1176 | EXPORT_SYMBOL(ieee80211_operating_class_to_band); | ||
| 1177 | |||
| 1158 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | 1178 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, |
| 1159 | u32 beacon_int) | 1179 | u32 beacon_int) |
| 1160 | { | 1180 | { |
| @@ -1258,12 +1278,12 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
| 1258 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { | 1278 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { |
| 1259 | if (wdev_iter == wdev) | 1279 | if (wdev_iter == wdev) |
| 1260 | continue; | 1280 | continue; |
| 1261 | if (wdev_iter->netdev) { | 1281 | if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { |
| 1262 | if (!netif_running(wdev_iter->netdev)) | ||
| 1263 | continue; | ||
| 1264 | } else if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { | ||
| 1265 | if (!wdev_iter->p2p_started) | 1282 | if (!wdev_iter->p2p_started) |
| 1266 | continue; | 1283 | continue; |
| 1284 | } else if (wdev_iter->netdev) { | ||
| 1285 | if (!netif_running(wdev_iter->netdev)) | ||
| 1286 | continue; | ||
| 1267 | } else { | 1287 | } else { |
| 1268 | WARN_ON(1); | 1288 | WARN_ON(1); |
| 1269 | } | 1289 | } |
