diff options
author | David S. Miller <davem@davemloft.net> | 2013-04-24 16:27:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-24 16:27:02 -0400 |
commit | 8bfadc32b7ef56ac6245b7ae0a06f5ece193004b (patch) | |
tree | 571c0c29cee15aa59088cf9a66f798b20005c1f5 /drivers | |
parent | 1bf9310a1336c26873dc3eb5fa188d4263897929 (diff) | |
parent | 6ed0e321a0aef14a894e26658108bf7e895c36a6 (diff) | |
download | blackbird-op-linux-8bfadc32b7ef56ac6245b7ae0a06f5ece193004b.tar.gz blackbird-op-linux-8bfadc32b7ef56ac6245b7ae0a06f5ece193004b.zip |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says:
====================
Here is one last(?) big wireless bits pull request before the merge window...
Regarding the mac80211 bits, Johannes says:
"Here's another big pull request for the -next stream. This one has a ton
of driver updates, which hopefully addresses all drivers, but maybe you
have more new drivers than I have in my tree? Not entirely sure, let me
know if this is the case and then I can merge wireless-next.
I'm including a large number of small changes, see the shortlog. The two
bigger things are making VHT compatible with not using channel contexts
(from Karl) and the stop-while-suspended fixes I developed together with
Stanislaw."
...and...
"This time I have a relatively large number of fixes and small
improvements, the most important one being Bob's RCU fix. The two big
things are Felix's work on rate scaling tables (with a big thanks to
Karl too) and my own work on CSA handling to finally properly handle HT
(and some VHT.)"
As for the iwlwifi bits, Johannes says:
"The biggest work here is Bluetooth coexistence and power saving. Other
than that, I have a few small fixes that weren't really needed for 3.9
and a new PCI ID."
About the NFC bits, Samuel says:
"With this one we have:
- A major pn533 update. The pn533 framing support has been changed in order to
easily support all pn533 derivatives. For example we now support the ACR122
USB dongle.
- An NFC MEI physical layer code factorization through the mei_phy NFC API.
Both the microread and the pn544 drivers now use it.
- LLCP aggregation support. This allows NFC p2p devices to send aggregated
frames containing all sort of LLCP frames except SYMM and aggregation
frames.
- More LLCP socket options for getting the remote device link parameters.
- Fixes for the LLCP socket option code added with the first pull request for
3.10.
- Some support for LLCP corner cases like 0 length SDUs and general DISC
(tagged with a 0,0 dsap ssap couple) handling.
- RFKILL support for NFC."
For the b43 bits, Rafał says:
"Let me remind the changes for b43:
> Changes include:
> 1) Minor improvements for HT-PHY code (BCM4331)
> 2) Code cleaning for HT-PHY and N-PHY"
Concerning the bluetooth bits, Gustavo says:
"A set of changes intended for 3.10. The biggest changes here are from David
Herrmann, he rewrote most of the HIDP layer making it more reliable. Marcel
added a driver setup stage for device that need special handling on their
early initialization. Other than that we have the usual clean ups, bugfixes
and small improvements."
Along with all that, there is the usual collection of random/various
updates to ath9k, mwifiex, brcmfmac, brcmsmac, rt2x00, and wil6210.
I also included a pull of the wireless tree to resolve a merge conflict.
Please let me know if there are problems!
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
189 files changed, 6522 insertions, 3920 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[] = { { USB_DEVICE(0x13d3, 0x3393) }, { USB_DEVICE(0x0489, 0xe04e) }, { USB_DEVICE(0x0489, 0xe056) }, + { USB_DEVICE(0x0489, 0xe04d) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { 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[] = { { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, @@ -926,6 +927,22 @@ static void btusb_waker(struct work_struct *work) usb_autopm_put_interface(data->intf); } +static int btusb_setup_bcm92035(struct hci_dev *hdev) +{ + struct sk_buff *skb; + u8 val = 0x00; + + BT_DBG("%s", hdev->name); + + skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) + BT_ERR("BCM92035 command failed (%ld)", -PTR_ERR(skb)); + else + kfree_skb(skb); + + return 0; +} + static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1022,11 +1039,14 @@ static int btusb_probe(struct usb_interface *intf, SET_HCIDEV_DEV(hdev, &intf->dev); - hdev->open = btusb_open; - hdev->close = btusb_close; - hdev->flush = btusb_flush; - hdev->send = btusb_send_frame; - hdev->notify = btusb_notify; + hdev->open = btusb_open; + hdev->close = btusb_close; + hdev->flush = btusb_flush; + hdev->send = btusb_send_frame; + hdev->notify = btusb_notify; + + if (id->driver_info & BTUSB_BCM92035) + hdev->setup = btusb_setup_bcm92035; /* Interface numbers are hardcoded in the specification */ data->isoc = usb_ifnum_to_if(data->udev, 1); @@ -1065,17 +1085,6 @@ static int btusb_probe(struct usb_interface *intf, data->isoc = NULL; } - if (id->driver_info & BTUSB_BCM92035) { - unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 }; - struct sk_buff *skb; - - skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); - if (skb) { - memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd)); - skb_queue_tail(&hdev->driver_init, skb); - } - } - if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, 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) { int ret; + if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) + return -EUNATCH; + ret = hci_recv_stream_fragment(hu->hdev, data, count); if (ret < 0) { 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) /* ------ LDISC part ------ */ /* hci_uart_tty_open - * + * * Called when line discipline changed to HCI_UART. * * Arguments: * tty pointer to tty info structure - * Return Value: + * Return Value: * 0 if success, otherwise error code */ static int hci_uart_tty_open(struct tty_struct *tty) @@ -365,15 +365,15 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) } /* hci_uart_tty_receive() - * + * * Called by tty low level driver when receive data is * available. - * + * * Arguments: tty pointer to tty isntance data * data pointer to received data * flags pointer to flags for data * count count of received data in bytes - * + * * Return Value: None */ 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 spin_lock(&hu->rx_lock); hu->proto->recv(hu, (void *) data, count); - hu->hdev->stat.byte_rx += count; + + if (hu->hdev) + hu->hdev->stat.byte_rx += count; + spin_unlock(&hu->rx_lock); 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) { struct adm8211_priv *priv = dev->priv; struct ieee80211_conf *conf = &dev->conf; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + int channel = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); if (channel != priv->channel) { 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) struct at76_priv *priv = hw->priv; at76_dbg(DBG_MAC80211, "%s(): channel %d", - __func__, hw->conf.channel->hw_value); + __func__, hw->conf.chandef.chan->hw_value); at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); mutex_lock(&priv->mtx); - priv->channel = hw->conf.channel->hw_value; + priv->channel = hw->conf.chandef.chan->hw_value; if (is_valid_ether_addr(priv->bssid)) 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) memset(&reset, 0, sizeof(reset)); reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); - reset.freq = cpu_to_be32(conf->channel->center_freq); + reset.freq = cpu_to_be32(conf->chandef.chan->center_freq); reset.maxrdpower = cpu_to_be32(50); /* XXX */ reset.channelchange = cpu_to_be32(1); reset.keeprccontent = cpu_to_be32(0); ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", be32_to_cpu(reset.flags), - conf->channel->center_freq); + conf->chandef.chan->center_freq); return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0); } @@ -594,7 +594,7 @@ static void ar5523_data_rx_cb(struct urb *urb) rx_status = IEEE80211_SKB_RXCB(data->skb); memset(rx_status, 0, sizeof(*rx_status)); rx_status->freq = be32_to_cpu(desc->channel); - rx_status->band = hw->conf.channel->band; + rx_status->band = hw->conf.chandef.chan->band; rx_status->signal = -95 + be32_to_cpu(desc->rssi); ieee80211_rx_irqsafe(hw, data->skb); @@ -1153,13 +1153,13 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar, struct ieee80211_sta *sta; u32 sta_rate_set; - band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; + band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); if (!sta) { ar5523_info(ar, "STA not found!\n"); return WLAN_MODE_11b; } - sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; + sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; for (bit = 0; bit < band->n_bitrates; bit++) { if (sta_rate_set & 1) { @@ -1197,11 +1197,11 @@ static void ar5523_create_rateset(struct ar5523 *ar, ar5523_info(ar, "STA not found. Cannot set rates\n"); sta_rate_set = bss_conf->basic_rates; } else - sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; + sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band]; ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); - band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; + band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; for (bit = 0; bit < band->n_bitrates; bit++) { BUG_ON(i >= AR5523_MAX_NRATES); 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 ath5k-y += reset.o ath5k-y += attach.o ath5k-y += base.o +CFLAGS_base.o += -I$(src) ath5k-y += led.o ath5k-y += rfkill.o 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) * be followed by initialization of the appropriate bits * and then setup of the interrupt mask. */ - ah->curchan = ah->hw->conf.channel; + ah->curchan = ah->hw->conf.chandef.chan; ah->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | 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) mutex_lock(&ah->lock); if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(ah, conf->channel); + ret = ath5k_chan_set(ah, conf->chandef.chan); if (ret < 0) goto unlock; } @@ -678,7 +678,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) memcpy(survey, &ah->survey, sizeof(*survey)); - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->noise = ah->ah_noise_floor; survey->filled = SURVEY_INFO_NOISE_DBM | 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, #if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) #undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k +#define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace 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 @@ #include "hw-ops.h" #include "../regd.h" #include "ar9002_phy.h" +#include "ar5008_initvals.h" /* All code below is for AR5008, AR9001, AR9002 */ @@ -43,23 +44,16 @@ static const int m2ThreshLowExt_off = 127; static const int m1ThreshExt_off = 127; static const int m2ThreshExt_off = 127; +static const struct ar5416IniArray bank0 = STATIC_INI_ARRAY(ar5416Bank0); +static const struct ar5416IniArray bank1 = STATIC_INI_ARRAY(ar5416Bank1); +static const struct ar5416IniArray bank2 = STATIC_INI_ARRAY(ar5416Bank2); +static const struct ar5416IniArray bank3 = STATIC_INI_ARRAY(ar5416Bank3); +static const struct ar5416IniArray bank7 = STATIC_INI_ARRAY(ar5416Bank7); -static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array, - int col) -{ - int i; - - for (i = 0; i < array->ia_rows; i++) - bank[i] = INI_RA(array, i, col); -} - - -#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \ - ar5008_write_rf_array(ah, iniarray, regData, &(regWr)) - -static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array, - u32 *data, unsigned int *writecnt) +static void ar5008_write_bank6(struct ath_hw *ah, unsigned int *writecnt) { + struct ar5416IniArray *array = &ah->iniBank6; + u32 *data = ah->analogBank6Data; int r; ENABLE_REGWRITE_BUFFER(ah); @@ -165,7 +159,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); /* write Bank 6 with new params */ - REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); + ar5008_write_bank6(ah, ®_writes); } /** @@ -469,31 +463,16 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, */ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) { -#define ATH_ALLOC_BANK(bank, size) do { \ - bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \ - if (!bank) \ - goto error; \ - } while (0); - - struct ath_common *common = ath9k_hw_common(ah); + int size = ah->iniBank6.ia_rows * sizeof(u32); if (AR_SREV_9280_20_OR_LATER(ah)) return 0; - ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); - ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); - ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); - ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); - ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); - ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); - ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); - ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); + ah->analogBank6Data = devm_kzalloc(ah->dev, size, GFP_KERNEL); + if (!ah->analogBank6Data) + return -ENOMEM; return 0; -#undef ATH_ALLOC_BANK -error: - ath_err(common, "Cannot allocate RF banks\n"); - return -ENOMEM; } @@ -517,6 +496,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, u32 ob5GHz = 0, db5GHz = 0; u32 ob2GHz = 0, db2GHz = 0; int regWrites = 0; + int i; /* * Software does not need to program bank data @@ -529,25 +509,8 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, /* Setup rf parameters */ eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); - /* Setup Bank 0 Write */ - ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1); - - /* Setup Bank 1 Write */ - ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1); - - /* Setup Bank 2 Write */ - ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1); - - /* Setup Bank 6 Write */ - ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3, - modesIndex); - { - int i; - for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { - ah->analogBank6Data[i] = - INI_RA(&ah->iniBank6TPC, i, modesIndex); - } - } + for (i = 0; i < ah->iniBank6.ia_rows; i++) + ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex); /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ if (eepMinorRev >= 2) { @@ -568,22 +531,13 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, } } - /* Setup Bank 7 Setup */ - ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1); - /* Write Analog registers */ - REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, - regWrites); - REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, - regWrites); - REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, - regWrites); - REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, - regWrites); - REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, - regWrites); - REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, - regWrites); + REG_WRITE_ARRAY(&bank0, 1, regWrites); + REG_WRITE_ARRAY(&bank1, 1, regWrites); + REG_WRITE_ARRAY(&bank2, 1, regWrites); + REG_WRITE_ARRAY(&bank3, modesIndex, regWrites); + ar5008_write_bank6(ah, ®Writes); + REG_WRITE_ARRAY(&bank7, 1, regWrites); return true; } 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) } else if (AR_SREV_9100_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100); - INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100); INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100); } else { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common); - INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC); INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac); } @@ -80,20 +78,11 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah) /* Common for AR5416, AR913x, AR9160 */ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain); - INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0); - INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1); - INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2); - INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3); - INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7); - - /* Common for AR5416, AR9160 */ - if (!AR_SREV_9100(ah)) - INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6); - /* Common for AR913x, AR9160 */ if (!AR_SREV_5416(ah)) - INIT_INI_ARRAY(&ah->iniBank6TPC, - ar5416Bank6TPC_9100); + INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC_9100); + else + INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC); } /* 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 { dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ bool bf_stale; + struct ieee80211_tx_rate rates[4]; struct ath_buf_state bf_state; }; @@ -311,6 +312,7 @@ struct ath_rx_edma { struct ath_rx { u8 defant; u8 rxotherant; + bool discard_next; u32 *rxlink; u32 num_pkts; unsigned int rxfilter; @@ -657,11 +659,10 @@ enum sc_op_flags { struct ath_rate_table; struct ath9k_vif_iter_data { - const u8 *hw_macaddr; /* phy's hardware address, set - * before starting iteration for - * valid bssid mask. - */ + u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */ u8 mask[ETH_ALEN]; /* bssid mask */ + bool has_hw_macaddr; + int naps; /* number of AP vifs */ int nmeshes; /* number of mesh vifs */ 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, u8 chainmask = ah->txchainmask; u8 rate = 0; - sband = &sc->sbands[common->hw->conf.channel->band]; + sband = &sc->sbands[common->hw->conf.chandef.chan->band]; rate = sband->bitrates[rateidx].hw_value; if (vif->bss_conf.use_short_preamble) 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) return true; ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", - currCal->calData->calType, conf->channel->center_freq); + currCal->calData->calType, conf->chandef.chan->center_freq); ah->caldata->CalValid &= ~currCal->calData->calType; 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 { u32 ia_columns; }; +#define STATIC_INI_ARRAY(array) { \ + .ia_array = (u32 *)(array), \ + .ia_rows = ARRAY_SIZE(array), \ + .ia_columns = ARRAY_SIZE(array[0]), \ + } + #define INIT_INI_ARRAY(iniarray, array) do { \ (iniarray)->ia_array = (u32 *)(array); \ (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"); MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); MODULE_LICENSE("Dual BSD/GPL"); -int ath9k_cmn_padpos(__le16 frame_control) -{ - int padpos = 24; - if (ieee80211_has_a4(frame_control)) { - padpos += ETH_ALEN; - } - if (ieee80211_is_data_qos(frame_control)) { - padpos += IEEE80211_QOS_CTL_LEN; - } - - return padpos; -} -EXPORT_SYMBOL(ath9k_cmn_padpos); - int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -133,13 +119,14 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel); struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, struct ath_hw *ah) { - struct ieee80211_channel *curchan = hw->conf.channel; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; struct ath9k_channel *channel; u8 chan_idx; chan_idx = curchan->hw_value; channel = &ah->channels[chan_idx]; - ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); + ath9k_cmn_update_ichannel(channel, curchan, + cfg80211_get_chandef_type(&hw->conf.chandef)); return channel; } 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 @@ #define ATH_EP_RND(x, mul) \ (((x) + ((mul)/2)) / (mul)) -int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, 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, u8 rssi; u16 dur; - ath_dbg(ath9k_hw_common(sc->sc_ah), DFS, - "pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n", - ard->pulse_bw_info, - ard->pulse_length_pri, ard->rssi, - ard->pulse_length_ext, ard->ext_rssi); - /* * Only the last 2 bits of the BW info are relevant, they indicate * 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 @@ #include "dfs_pattern_detector.h" #include "dfs_pri_detector.h" +#include "ath9k.h" /* * 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) { u32 sz, i; struct channel_detector *cd; + struct ath_common *common = ath9k_hw_common(dpd->ah); cd = kmalloc(sizeof(*cd), GFP_ATOMIC); if (cd == NULL) @@ -165,7 +167,8 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) return cd; fail: - pr_err("failed to allocate channel_detector for freq=%d\n", freq); + ath_dbg(common, DFS, + "failed to allocate channel_detector for freq=%d\n", freq); channel_detector_exit(dpd, cd); return NULL; } @@ -216,34 +219,34 @@ static bool dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) { u32 i; - bool ts_wraparound; struct channel_detector *cd; - if (dpd->region == NL80211_DFS_UNSET) { - /* - * pulses received for a non-supported or un-initialized - * domain are treated as detected radars - */ + /* + * pulses received for a non-supported or un-initialized + * domain are treated as detected radars for fail-safety + */ + if (dpd->region == NL80211_DFS_UNSET) return true; - } cd = channel_detector_get(dpd, event->freq); if (cd == NULL) return false; - ts_wraparound = (event->ts < dpd->last_pulse_ts); dpd->last_pulse_ts = event->ts; - if (ts_wraparound) { - /* - * reset detector on time stamp wraparound - * with monotonic time stamps, this should never happen - */ - pr_warn("DFS: time stamp wraparound detected, resetting\n"); + /* reset detector on time stamp wraparound, caused by TSF reset */ + if (event->ts < dpd->last_pulse_ts) dpd_reset(dpd); - } + /* do type individual pattern matching */ for (i = 0; i < dpd->num_radar_types; i++) { - if (cd->detectors[i]->add_pulse(cd->detectors[i], event) != 0) { + struct pri_detector *pd = cd->detectors[i]; + struct pri_sequence *ps = pd->add_pulse(pd, event); + if (ps != NULL) { + ath_dbg(ath9k_hw_common(dpd->ah), DFS, + "DFS: radar found on freq=%d: id=%d, pri=%d, " + "count=%d, count_false=%d\n", + event->freq, pd->rs->type_id, + ps->pri, ps->count, ps->count_falses); channel_detector_reset(dpd, cd); return true; } @@ -285,9 +288,10 @@ static struct dfs_pattern_detector default_dpd = { }; struct dfs_pattern_detector * -dfs_pattern_detector_init(enum nl80211_dfs_regions region) +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) { struct dfs_pattern_detector *dpd; + struct ath_common *common = ath9k_hw_common(ah); dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); if (dpd == NULL) @@ -296,10 +300,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) *dpd = default_dpd; INIT_LIST_HEAD(&dpd->channel_detectors); + dpd->ah = ah; if (dpd->set_dfs_domain(dpd, region)) return dpd; - pr_err("Could not set DFS domain to %d. ", region); + ath_dbg(common, DFS,"Could not set DFS domain to %d", region); kfree(dpd); return NULL; } 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 { enum nl80211_dfs_regions region; u8 num_radar_types; u64 last_pulse_ts; + /* needed for ath_dbg() */ + struct ath_hw *ah; const struct radar_detector_specs *radar_spec; struct list_head channel_detectors; @@ -92,10 +94,10 @@ struct dfs_pattern_detector { */ #if defined(CONFIG_ATH9K_DFS_CERTIFIED) extern struct dfs_pattern_detector * -dfs_pattern_detector_init(enum nl80211_dfs_regions region); +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region); #else static inline struct dfs_pattern_detector * -dfs_pattern_detector_init(enum nl80211_dfs_regions region) +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) { return NULL; } 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 @@ #include "dfs_debug.h" /** - * struct pri_sequence - sequence of pulses matching one PRI - * @head: list_head - * @pri: pulse repetition interval (PRI) in usecs - * @dur: duration of sequence in usecs - * @count: number of pulses in this sequence - * @count_falses: number of not matching pulses in this sequence - * @first_ts: time stamp of first pulse in usecs - * @last_ts: time stamp of last pulse in usecs - * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) - */ -struct pri_sequence { - struct list_head head; - u32 pri; - u32 dur; - u32 count; - u32 count_falses; - u64 first_ts; - u64 last_ts; - u64 deadline_ts; -}; - -/** * struct pulse_elem - elements in pulse queue * @ts: time stamp in usecs */ @@ -393,8 +371,8 @@ static void pri_detector_exit(struct pri_detector *de) kfree(de); } -static bool pri_detector_add_pulse(struct pri_detector *de, - struct pulse_event *event) +static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de, + struct pulse_event *event) { u32 max_updated_seq; struct pri_sequence *ps; @@ -403,38 +381,33 @@ static bool pri_detector_add_pulse(struct pri_detector *de, /* ignore pulses not within width range */ if ((rs->width_min > event->width) || (rs->width_max < event->width)) - return false; + return NULL; if ((ts - de->last_ts) < rs->max_pri_tolerance) /* if delta to last pulse is too short, don't use this pulse */ - return false; + return NULL; de->last_ts = ts; max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts); if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) { - pr_err("failed to create pulse sequences\n"); pri_detector_reset(de, ts); return false; } ps = pseq_handler_check_detection(de); - if (ps != NULL) { - pr_info("DFS: radar found: pri=%d, count=%d, count_false=%d\n", - ps->pri, ps->count, ps->count_falses); - pri_detector_reset(de, ts); - return true; - } - pulse_queue_enqueue(de, ts); - return false; + if (ps == NULL) + pulse_queue_enqueue(de, ts); + + return ps; } -struct pri_detector * -pri_detector_init(const struct radar_detector_specs *rs) +struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs) { struct pri_detector *de; - de = kzalloc(sizeof(*de), GFP_KERNEL); + + de = kzalloc(sizeof(*de), GFP_ATOMIC); if (de == NULL) return NULL; 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 @@ #include <linux/list.h> /** + * struct pri_sequence - sequence of pulses matching one PRI + * @head: list_head + * @pri: pulse repetition interval (PRI) in usecs + * @dur: duration of sequence in usecs + * @count: number of pulses in this sequence + * @count_falses: number of not matching pulses in this sequence + * @first_ts: time stamp of first pulse in usecs + * @last_ts: time stamp of last pulse in usecs + * @deadline_ts: deadline when this sequence becomes invalid (first_ts + dur) + */ +struct pri_sequence { + struct list_head head; + u32 pri; + u32 dur; + u32 count; + u32 count_falses; + u64 first_ts; + u64 last_ts; + u64 deadline_ts; +}; + +/** * struct pri_detector - PRI detector element for a dedicated radar type * @exit(): destructor - * @add_pulse(): add pulse event, returns true if pattern was detected + * @add_pulse(): add pulse event, returns pri_sequence if pattern was detected * @reset(): clear states and reset to given time stamp * @rs: detector specs for this detector element * @last_ts: last pulse time stamp considered for this element in usecs @@ -34,7 +56,8 @@ */ struct pri_detector { void (*exit) (struct pri_detector *de); - bool (*add_pulse)(struct pri_detector *de, struct pulse_event *e); + struct pri_sequence * + (*add_pulse)(struct pri_detector *de, struct pulse_event *e); void (*reset) (struct pri_detector *de, u64 ts); /* 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, while(skb) { hdr = (struct ieee80211_hdr *) skb->data; - padpos = ath9k_cmn_padpos(hdr->frame_control); + padpos = ieee80211_hdrlen(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len > padpos) { 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) { struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_channel *channel = priv->hw->conf.channel; + struct ieee80211_channel *channel = priv->hw->conf.chandef.chan; struct ath9k_hw_cal_data *caldata = NULL; enum htc_phymode mode; __be16 htc_mode; @@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &common->hw->conf; bool fastcc; - struct ieee80211_channel *channel = hw->conf.channel; + struct ieee80211_channel *channel = hw->conf.chandef.chan; struct ath9k_hw_cal_data *caldata = NULL; enum htc_phymode mode; __be16 htc_mode; @@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, u32 caps = 0; int i, j; - sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band]; + sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band]; for (i = 0, j = 0; i < sband->n_bitrates; i++) { if (sta->supp_rates[sband->band] & BIT(i)) { @@ -866,7 +866,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, hdr = (struct ieee80211_hdr *) skb->data; /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); + padpos = ieee80211_hdrlen(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len > padpos) { if (skb_headroom(skb) < padsize) { @@ -904,7 +904,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_channel *curchan = hw->conf.channel; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; struct ath9k_channel *init_channel; int ret = 0; enum htc_phymode mode; @@ -1193,15 +1193,17 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { - struct ieee80211_channel *curchan = hw->conf.channel; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&hw->conf.chandef); int pos = curchan->hw_value; ath_dbg(common, CONFIG, "Set channel: %d MHz\n", curchan->center_freq); ath9k_cmn_update_ichannel(&priv->ah->channels[pos], - hw->conf.channel, - hw->conf.channel_type); + hw->conf.chandef.chan, + channel_type); if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { 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, if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) rate->flags |= IEEE80211_TX_RC_SHORT_GI; } else { - if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) + if (cur_conf->chandef.chan->band == IEEE80211_BAND_5GHZ) rate->idx += 4; /* No CCK rates */ } @@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw, return; } - band = hw->conf.channel->band; + band = hw->conf.chandef.chan->band; sband = hw->wiphy->bands[band]; for (i = 0; i < sband->n_bitrates; i++) { @@ -966,7 +966,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, struct sk_buff *skb = rxbuf->skb; struct ath_common *common = ath9k_hw_common(priv->ah); struct ath_htc_rx_status *rxstatus; - int hdrlen, padpos, padsize; + int hdrlen, padsize; int last_rssi = ATH_RSSI_DUMMY_MARKER; __le16 fc; @@ -996,11 +996,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, fc = hdr->frame_control; hdrlen = ieee80211_get_hdrlen_from_skb(skb); - padpos = ath9k_cmn_padpos(fc); - - padsize = padpos & 3; - if (padsize && skb->len >= padpos+padsize+FCS_LEN) { - memmove(skb->data + padsize, skb->data, padpos); + padsize = hdrlen & 3; + if (padsize && skb->len >= hdrlen+padsize+FCS_LEN) { + memmove(skb->data + padsize, skb->data, hdrlen); skb_pull(skb, padsize); } @@ -1082,8 +1080,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, } rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); - rx_status->band = hw->conf.channel->band; - rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; rx_status->antenna = rxbuf->rxstatus.rs_antenna; 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) clockrate = 117; else if (!ah->curchan) /* should really check for CCK instead */ clockrate = ATH9K_CLOCK_RATE_CCK; - else if (conf->channel->band == IEEE80211_BAND_2GHZ) + else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ) clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; @@ -1100,7 +1100,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) } /* As defined by IEEE 802.11-2007 17.3.8.6 */ - acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset; + slottime += 3 * ah->coverage_class; + acktimeout = slottime + sifstime + ack_offset; ctstimeout = acktimeout; /* @@ -1110,7 +1111,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) * BA frames in some implementations, but it has been found to fix ACK * timeout issues in other cases as well. */ - if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ && + if (conf->chandef.chan && + conf->chandef.chan->band == IEEE80211_BAND_2GHZ && !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { acktimeout += 64 - sifstime - ah->slottime; ctstimeout += 48 - sifstime - ah->slottime; @@ -1697,12 +1699,11 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah, ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); - REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) - | macStaId1 + REG_RMW(ah, AR_STA_ID1, macStaId1 | AR_STA_ID1_RTS_USE_DEF | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) - | ah->sta_id1_defaults); + | ah->sta_id1_defaults, + ~AR_STA_ID1_SADH_MASK); ath_hw_setbssidmask(common); REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 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 { struct ath_hw_ops ops; /* Used to program the radio on non single-chip devices */ - u32 *analogBank0Data; - u32 *analogBank1Data; - u32 *analogBank2Data; - u32 *analogBank3Data; u32 *analogBank6Data; - u32 *analogBank6TPCData; - u32 *analogBank7Data; - u32 *bank6Temp; int coverage_class; u32 slottime; @@ -885,14 +878,8 @@ struct ath_hw { struct ar5416IniArray iniModes; struct ar5416IniArray iniCommon; - struct ar5416IniArray iniBank0; struct ar5416IniArray iniBB_RfGain; - struct ar5416IniArray iniBank1; - struct ar5416IniArray iniBank2; - struct ar5416IniArray iniBank3; struct ar5416IniArray iniBank6; - struct ar5416IniArray iniBank6TPC; - struct ar5416IniArray iniBank7; struct ar5416IniArray iniAddac; struct ar5416IniArray iniPcieSerdes; #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, atomic_set(&ah->intr_ref_cnt, -1); sc->sc_ah = ah; - sc->dfs_detector = dfs_pattern_detector_init(NL80211_DFS_UNSET); + sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET); if (!pdata) { ah->ah_flags |= AH_USE_EEPROM; @@ -766,7 +766,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_REPORTS_TX_ACK_STATUS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SUPPORTS_RC_TABLE; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 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 txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; memset(tx_info, 0, sizeof(*tx_info)); - tx_info->band = hw->conf.channel->band; + tx_info->band = hw->conf.chandef.chan->band; tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; tx_info->control.rates[0].idx = 0; 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, rs->rs_status |= ATH9K_RXERR_DECRYPT; else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; + } else { + if (ads.ds_rxstatus8 & + (AR_CRCErr | AR_PHYErr | AR_DecryptCRCErr | AR_MichaelErr)) + rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; + + /* Only up to MCS16 supported, everything above is invalid */ + if (rs->rs_rate >= 0x90) + rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; } 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 { #define ATH9K_RXERR_DECRYPT 0x08 #define ATH9K_RXERR_MIC 0x10 #define ATH9K_RXERR_KEYMISS 0x20 +#define ATH9K_RXERR_CORRUPT_DESC 0x40 #define ATH9K_RX_MORE 0x01 #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) struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_channel *curchan = hw->conf.channel; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; struct ath9k_channel *init_channel; int r; @@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) struct ath9k_vif_iter_data *iter_data = data; int i; - if (iter_data->hw_macaddr) + if (iter_data->has_hw_macaddr) { for (i = 0; i < ETH_ALEN; i++) iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); + } else { + memcpy(iter_data->hw_macaddr, mac, ETH_ALEN); + iter_data->has_hw_macaddr = true; + } switch (vif->type) { case NL80211_IFTYPE_AP: @@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, * together with the BSSID mask when matching addresses. */ memset(iter_data, 0, sizeof(*iter_data)); - iter_data->hw_macaddr = common->macaddr; memset(&iter_data->mask, 0xff, ETH_ALEN); if (vif) @@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, ieee80211_iterate_active_interfaces_atomic( sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, ath9k_vif_iter, iter_data); + + memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN); } /* Called with sc->mutex held. */ @@ -1188,7 +1193,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { - struct ieee80211_channel *curchan = hw->conf.channel; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&conf->chandef); int pos = curchan->hw_value; int old_pos = -1; unsigned long flags; @@ -1197,7 +1204,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) old_pos = ah->curchan - &ah->channels[0]; ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", - curchan->center_freq, conf->channel_type); + curchan->center_freq, channel_type); /* update survey stats for the old channel before switching */ spin_lock_irqsave(&common->cc_lock, flags); @@ -1212,7 +1219,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath9k_hw_getnf(ah, ah->curchan); ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], - curchan, conf->channel_type); + curchan, channel_type); /* * 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, * So, set fourth rate in series to be same as third one for * above conditions. */ - if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && + if ((sc->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) && (conf_is_ht(&sc->hw->conf))) { u8 dot11rate = rate_table->info[rix].dot11rate; u8 phy = rate_table->info[rix].phy; @@ -1328,7 +1328,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, "Operating HT Bandwidth changed to: %d\n", - sc->hw->conf.channel_type); + cfg80211_get_chandef_type(&sc->hw->conf.chandef)); } } 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, SKB_CB_ATHBUF(skb) = bf; ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype); - skb_queue_tail(&rx_edma->rx_fifo, skb); + __skb_queue_tail(&rx_edma->rx_fifo, skb); return true; } static void ath_rx_addbuffer_edma(struct ath_softc *sc, - enum ath9k_rx_qtype qtype, int size) + enum ath9k_rx_qtype qtype) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_buf *bf, *tbf; @@ -155,7 +155,7 @@ static void ath_rx_remove_buffer(struct ath_softc *sc, rx_edma = &sc->rx.rx_edma[qtype]; - while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) { + while ((skb = __skb_dequeue(&rx_edma->rx_fifo)) != NULL) { bf = SKB_CB_ATHBUF(skb); BUG_ON(!bf); list_add_tail(&bf->list, &sc->rx.rxbuf); @@ -250,15 +250,9 @@ rx_init_fail: static void ath_edma_start_recv(struct ath_softc *sc) { ath9k_hw_rxena(sc->sc_ah); - - ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, - sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize); - - ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, - sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); - + ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP); + ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP); ath_opmode_init(sc); - ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); } @@ -280,49 +274,47 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + sc->sc_ah->caps.rx_status_len; - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) return ath_rx_edma_init(sc, nbufs); - } else { - ath_dbg(common, CONFIG, "cachelsz %u rxbufsize %u\n", - common->cachelsz, common->rx_bufsize); - /* Initialize rx descriptors */ + ath_dbg(common, CONFIG, "cachelsz %u rxbufsize %u\n", + common->cachelsz, common->rx_bufsize); - error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, - "rx", nbufs, 1, 0); - if (error != 0) { - ath_err(common, - "failed to allocate rx descriptors: %d\n", - error); + /* Initialize rx descriptors */ + + error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, + "rx", nbufs, 1, 0); + if (error != 0) { + ath_err(common, + "failed to allocate rx descriptors: %d\n", + error); + goto err; + } + + list_for_each_entry(bf, &sc->rx.rxbuf, list) { + skb = ath_rxbuf_alloc(common, common->rx_bufsize, + GFP_KERNEL); + if (skb == NULL) { + error = -ENOMEM; goto err; } - list_for_each_entry(bf, &sc->rx.rxbuf, list) { - skb = ath_rxbuf_alloc(common, common->rx_bufsize, - GFP_KERNEL); - if (skb == NULL) { - error = -ENOMEM; - goto err; - } - - bf->bf_mpdu = skb; - bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, - common->rx_bufsize, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(sc->dev, - bf->bf_buf_addr))) { - dev_kfree_skb_any(skb); - bf->bf_mpdu = NULL; - bf->bf_buf_addr = 0; - ath_err(common, - "dma_mapping_error() on RX init\n"); - error = -ENOMEM; - goto err; - } + bf->bf_mpdu = skb; + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + common->rx_bufsize, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, + bf->bf_buf_addr))) { + dev_kfree_skb_any(skb); + bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; + ath_err(common, + "dma_mapping_error() on RX init\n"); + error = -ENOMEM; + goto err; } - sc->rx.rxlink = NULL; } - + sc->rx.rxlink = NULL; err: if (error) ath_rx_cleanup(sc); @@ -340,17 +332,17 @@ void ath_rx_cleanup(struct ath_softc *sc) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { ath_rx_edma_cleanup(sc); return; - } else { - list_for_each_entry(bf, &sc->rx.rxbuf, list) { - skb = bf->bf_mpdu; - if (skb) { - dma_unmap_single(sc->dev, bf->bf_buf_addr, - common->rx_bufsize, - DMA_FROM_DEVICE); - dev_kfree_skb(skb); - bf->bf_buf_addr = 0; - bf->bf_mpdu = NULL; - } + } + + list_for_each_entry(bf, &sc->rx.rxbuf, list) { + skb = bf->bf_mpdu; + if (skb) { + dma_unmap_single(sc->dev, bf->bf_buf_addr, + common->rx_bufsize, + DMA_FROM_DEVICE); + dev_kfree_skb(skb); + bf->bf_buf_addr = 0; + bf->bf_mpdu = NULL; } } } @@ -727,6 +719,13 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, ret = ath9k_hw_rxprocdesc(ah, tds, &trs); if (ret == -EINPROGRESS) return NULL; + + /* + * mark descriptor as zero-length and set the 'more' + * flag to ensure that both buffers get discarded + */ + rs->rs_datalen = 0; + rs->rs_more = true; } list_del(&bf->list); @@ -863,7 +862,7 @@ static int ath9k_process_rate(struct ath_common *common, unsigned int i = 0; struct ath_softc __maybe_unused *sc = common->priv; - band = hw->conf.channel->band; + band = hw->conf.chandef.chan->band; sband = hw->wiphy->bands[band]; if (rx_stats->rs_rate & 0x80) { @@ -933,14 +932,20 @@ static void ath9k_process_rssi(struct ath_common *common, * up the frame up to let mac80211 handle the actual error case, be it no * decryption key or real decryption error. This let us keep statistics there. */ -static int ath9k_rx_skb_preprocess(struct ath_common *common, - struct ieee80211_hw *hw, +static int ath9k_rx_skb_preprocess(struct ath_softc *sc, struct ieee80211_hdr *hdr, struct ath_rx_status *rx_stats, struct ieee80211_rx_status *rx_status, bool *decrypt_error) { - struct ath_hw *ah = common->ah; + struct ieee80211_hw *hw = sc->hw; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + bool discard_current = sc->rx.discard_next; + + sc->rx.discard_next = rx_stats->rs_more; + if (discard_current) + return -EINVAL; /* * 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, if (ath9k_process_rate(common, hw, rx_stats, rx_status)) return -EINVAL; - rx_status->band = hw->conf.channel->band; - rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->signal = ah->noise + rx_stats->rs_rssi; rx_status->antenna = rx_stats->rs_antenna; rx_status->flag |= RX_FLAG_MACTIME_END; if (rx_stats->rs_moreaggr) rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + sc->rx.discard_next = false; return 0; } @@ -985,7 +991,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; - padpos = ath9k_cmn_padpos(hdr->frame_control); + padpos = ieee80211_hdrlen(fc); /* The MAC header is padded to have 32-bit boundary if the * 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) u64 tsf = 0; u32 tsf_lower = 0; unsigned long flags; + dma_addr_t new_buf_addr; if (edma) dma_type = DMA_BIDIRECTIONAL; @@ -1242,8 +1249,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) } } - retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, - rxs, &decrypt_error); + retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs, + &decrypt_error); if (retval) goto requeue_drop_frag; @@ -1264,10 +1271,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) goto requeue_drop_frag; } + /* We will now give hardware our shiny new allocated skb */ + new_buf_addr = dma_map_single(sc->dev, requeue_skb->data, + common->rx_bufsize, dma_type); + if (unlikely(dma_mapping_error(sc->dev, new_buf_addr))) { + dev_kfree_skb_any(requeue_skb); + goto requeue_drop_frag; + } + /* Unmap the frame */ dma_unmap_single(sc->dev, bf->bf_buf_addr, - common->rx_bufsize, - dma_type); + common->rx_bufsize, dma_type); + + bf->bf_mpdu = requeue_skb; + bf->bf_buf_addr = new_buf_addr; skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); if (ah->caps.rx_status_len) @@ -1277,21 +1294,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ath9k_rx_skb_postprocess(common, hdr_skb, &rs, rxs, decrypt_error); - /* We will now give hardware our shiny new allocated skb */ - bf->bf_mpdu = requeue_skb; - bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, - common->rx_bufsize, - dma_type); - if (unlikely(dma_mapping_error(sc->dev, - bf->bf_buf_addr))) { - dev_kfree_skb_any(requeue_skb); - bf->bf_mpdu = NULL; - bf->bf_buf_addr = 0; - ath_err(common, "dma_mapping_error() on RX\n"); - ieee80211_rx(hw, skb); - break; - } - if (rs.rs_more) { RX_STAT_INC(rx_frags); /* @@ -1309,6 +1311,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) sc->rx.frag = skb; goto requeue; } + if (rs.rs_status & ATH9K_RXERR_CORRUPT_DESC) + goto requeue_drop_frag; if (sc->rx.frag) { 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 { #define AR9271_RADIO_RF_RST 0x20 #define AR9271_GATE_MAC_CTL 0x4000 -#define AR_STA_ID0 0x8000 -#define AR_STA_ID1 0x8004 -#define AR_STA_ID1_SADH_MASK 0x0000FFFF #define AR_STA_ID1_STA_AP 0x00010000 #define AR_STA_ID1_ADHOC 0x00020000 #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) seqno << IEEE80211_SEQ_SEQ_SHIFT); } +static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ath_buf *bf) +{ + ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, + ARRAY_SIZE(bf->rates)); +} + static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) { 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) ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); sendbar = true; } else { + ath_set_rates(tid->an->vif, tid->an->sta, bf); ath_tx_send_normal(sc, txq, NULL, skb); } } @@ -407,7 +415,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tx_info = IEEE80211_SKB_CB(skb); - memcpy(rates, tx_info->control.rates, sizeof(rates)); + memcpy(rates, bf->rates, sizeof(rates)); retries = ts->ts_longretry + 1; 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, * not a holding desc. */ INIT_LIST_HEAD(&bf_head); - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || - bf_next != NULL || !bf_last->bf_stale) + if (bf_next != NULL || !bf_last->bf_stale) list_move_tail(&bf->list, &bf_head); if (!txpending || (tid->state & AGGR_CLEANUP)) { @@ -537,8 +544,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !txfail); } else { /* retry the un-acked ones */ - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && - bf->bf_next == NULL && bf_last->bf_stale) { + if (bf->bf_next == NULL && bf_last->bf_stale) { struct ath_buf *tbf; 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, bool first_subfrm) { #define FIRST_DESC_NDELIMS 60 - struct sk_buff *skb = bf->bf_mpdu; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); u32 nsymbits, nsymbols; u16 minlen; u8 flags, rix; @@ -780,8 +784,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, if (tid->an->mpdudensity == 0) return ndelim; - rix = tx_info->control.rates[0].idx; - flags = tx_info->control.rates[0].flags; + rix = bf->rates[0].idx; + flags = bf->rates[0].flags; width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; @@ -860,6 +864,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, bf_first = bf; if (!rl) { + ath_set_rates(tid->an->vif, tid->an->sta, bf); aggr_limit = ath_lookup_rate(sc, bf, tid); rl = 1; } @@ -1000,14 +1005,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); - rates = tx_info->control.rates; + rates = bf->rates; hdr = (struct ieee80211_hdr *)skb->data; /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); info->rtscts_rate = fi->rtscts_rate; - for (i = 0; i < 4; i++) { + for (i = 0; i < ARRAY_SIZE(bf->rates); i++) { bool is_40, is_sgi, is_sp; int phy; @@ -1745,6 +1750,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, return; } + ath_set_rates(tid->an->vif, tid->an->sta, bf); bf->bf_state.bf_type = BUF_AMPDU; INIT_LIST_HEAD(&bf_head); list_add(&bf->list, &bf_head); @@ -1894,49 +1900,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, return bf; } -/* FIXME: tx power */ -static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, - struct ath_tx_control *txctl) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ath_atx_tid *tid = NULL; - struct ath_buf *bf; - u8 tidno; - - if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { - tidno = ieee80211_get_qos_ctl(hdr)[0] & - IEEE80211_QOS_CTL_TID_MASK; - tid = ATH_AN_2_TID(txctl->an, tidno); - - WARN_ON(tid->ac->txq != txctl->txq); - } - - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { - /* - * Try aggregation if it's a unicast data frame - * and the destination is HT capable. - */ - ath_tx_send_ampdu(sc, tid, skb, txctl); - } else { - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); - if (!bf) { - if (txctl->paprd) - dev_kfree_skb_any(skb); - else - ieee80211_free_txskb(sc->hw, skb); - return; - } - - bf->bf_state.bfs_paprd = txctl->paprd; - - if (txctl->paprd) - bf->bf_state.bfs_paprd_timestamp = jiffies; - - ath_tx_send_normal(sc, txctl->txq, tid, skb); - } -} - /* Upon failure caller should free skb */ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath_tx_control *txctl) @@ -1947,8 +1910,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_vif *vif = info->control.vif; struct ath_softc *sc = hw->priv; struct ath_txq *txq = txctl->txq; + struct ath_atx_tid *tid = NULL; + struct ath_buf *bf; int padpos, padsize; int frmlen = skb->len + FCS_LEN; + u8 tidno; int q; /* 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, } /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); + padpos = ieee80211_hdrlen(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len > padpos) { if (skb_headroom(skb) < padsize) @@ -2004,8 +1970,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, txq->stopped = true; } - ath_tx_start_dma(sc, skb, txctl); + if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { + tidno = ieee80211_get_qos_ctl(hdr)[0] & + IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(txctl->an, tidno); + + WARN_ON(tid->ac->txq != txctl->txq); + } + + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) { + /* + * Try aggregation if it's a unicast data frame + * and the destination is HT capable. + */ + ath_tx_send_ampdu(sc, tid, skb, txctl); + goto out; + } + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); + if (!bf) { + if (txctl->paprd) + dev_kfree_skb_any(skb); + else + ieee80211_free_txskb(sc->hw, skb); + goto out; + } + + bf->bf_state.bfs_paprd = txctl->paprd; + + if (txctl->paprd) + bf->bf_state.bfs_paprd_timestamp = jiffies; + + ath_set_rates(vif, sta, bf); + ath_tx_send_normal(sc, txctl->txq, tid, skb); + +out: ath_txq_unlock(sc, txq); return 0; @@ -2033,7 +2032,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; - padpos = ath9k_cmn_padpos(hdr->frame_control); + padpos = ieee80211_hdrlen(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len>padpos+padsize) { /* @@ -2264,6 +2263,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) struct ath_txq *txq; struct ath_buf *bf, *lastbf; struct list_head bf_head; + struct list_head *fifo_list; int status; for (;;) { @@ -2291,20 +2291,24 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) TX_STAT_INC(txq->axq_qnum, txprocdesc); - if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { + fifo_list = &txq->txq_fifo[txq->txq_tailidx]; + if (list_empty(fifo_list)) { ath_txq_unlock(sc, txq); return; } - bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], - struct ath_buf, list); + bf = list_first_entry(fifo_list, struct ath_buf, list); + if (bf->bf_stale) { + list_del(&bf->list); + ath_tx_return_buffer(sc, bf); + bf = list_first_entry(fifo_list, struct ath_buf, list); + } + lastbf = bf->bf_lastbf; INIT_LIST_HEAD(&bf_head); - list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], - &lastbf->list); - - if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { + if (list_is_last(&lastbf->list, fifo_list)) { + list_splice_tail_init(fifo_list, &bf_head); INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); if (!list_empty(&txq->axq_q)) { @@ -2315,6 +2319,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) list_splice_tail_init(&txq->axq_q, &bf_q); ath_tx_txqaddbuf(sc, txq, &bf_q, true); } + } else { + lastbf->bf_stale = true; + if (bf != lastbf) + list_cut_position(&bf_head, fifo_list, + lastbf->list.prev); } 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, goto out; case 'P': - err = carl9170_set_channel(ar, ar->hw->conf.channel, - ar->hw->conf.channel_type); + err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan, + cfg80211_get_chandef_type(&ar->hw->conf.chandef)); if (err < 0) count = err; 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) if (conf_is_ht40(&ar->hw->conf)) val = 0x010a; else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) + if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) val = 0x105; else val = 0x104; @@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar) rts_rate = 0x1da; cts_rate = 0x10a; } else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { /* 11 mbit CCK */ rts_rate = 033; cts_rate = 003; @@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar) return 0; } - if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || + if ((ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) || vif->bss_conf.use_short_slot) slottime = 9; @@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar) basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; rcu_read_unlock(); - if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) + if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ else 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) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&hw->conf.chandef); + /* adjust slot time for 5 GHz */ err = carl9170_set_slot_time(ar); if (err) @@ -938,8 +941,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) if (err) goto out; - err = carl9170_set_channel(ar, hw->conf.channel, - hw->conf.channel_type); + err = carl9170_set_channel(ar, hw->conf.chandef.chan, + channel_type); if (err) goto out; @@ -957,7 +960,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_POWER) { - err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); + err = carl9170_set_mac_tpc(ar, ar->hw->conf.chandef.chan); if (err) goto out; } 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) * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. */ ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, - ar->hw->conf.channel->band); + ar->hw->conf.chandef.chan->band); /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ 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) /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ return; - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { modes = mode_list_2ghz; nr_modes = ARRAY_SIZE(mode_list_2ghz); } 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 @@ void ath_hw_setbssidmask(struct ath_common *common) { void *ah = common->ah; + u32 id1; + + REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); + id1 = REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_SADH_MASK; + id1 |= get_unaligned_le16(common->macaddr + 4); + REG_WRITE(ah, AR_STA_ID1, id1); REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); 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 @@ #define AR_MIBC_CMC 0x00000004 #define AR_MIBC_MCS 0x00000008 +#define AR_STA_ID0 0x8000 +#define AR_STA_ID1 0x8004 +#define AR_STA_ID1_SADH_MASK 0x0000ffff + /* * BSSID mask registers. See ath_hw_set_bssid_mask() * 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, * - Phy info */ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, - struct sk_buff *skb, - volatile struct vring_rx_desc *d) + struct sk_buff *skb) { struct wireless_dev *wdev = wil->wdev; struct wil6210_rtap { @@ -216,6 +215,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, __le16 vendor_skip; u8 vendor_data[0]; } __packed; + struct vring_rx_desc *d = wil_skb_rxdesc(skb); struct wil6210_rtap_vendor *rtap_vendor; int rtap_len = sizeof(struct wil6210_rtap); int phy_length = 0; /* phy info header size, bytes */ @@ -312,6 +312,8 @@ static void wil_swap_ethaddr(void *data) /** * reap 1 frame from @swhead * + * Rx descriptor copied to skb->cb + * * Safe to call from IRQ */ 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, struct device *dev = wil_to_dev(wil); struct net_device *ndev = wil_to_ndev(wil); volatile struct vring_rx_desc *d; + struct vring_rx_desc *d1; struct sk_buff *skb; dma_addr_t pa; unsigned int sz = RX_BUF_LEN; u8 ftype; u8 ds_bits; + BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); + if (wil_vring_is_empty(vring)) return NULL; @@ -340,11 +345,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); skb_trim(skb, d->dma.length); - wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); + d1 = wil_skb_rxdesc(skb); + *d1 = *d; + + wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1); /* use radiotap header only if required */ if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) - wil_rx_add_radiotap_header(wil, skb, d); + wil_rx_add_radiotap_header(wil, skb); wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); 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, * Driver should recognize it by frame type, that is found * in Rx descriptor. If type is not data, it is 802.11 frame as is */ - ftype = wil_rxdesc_ftype(d) << 2; + ftype = wil_rxdesc_ftype(d1) << 2; if (ftype != IEEE80211_FTYPE_DATA) { wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); /* TODO: process it */ @@ -375,7 +383,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, return NULL; } - ds_bits = wil_rxdesc_ds_bits(d); + ds_bits = wil_rxdesc_ds_bits(d1); if (ds_bits == 1) { /* * 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, .vring_cfg = { .tx_sw_ring = { .max_mpdu_size = cpu_to_le16(TX_BUF_LEN), + .ring_size = cpu_to_le16(size), }, .ringid = id, .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), @@ -548,7 +557,6 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, goto out; cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); - cmd.vring_cfg.tx_sw_ring.ring_size = cpu_to_le16(vring->size); rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); @@ -779,9 +787,14 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid) wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); while (!wil_vring_is_empty(vring)) { - volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx; + volatile struct vring_tx_desc *d1 = + &vring->va[vring->swtail].tx; + struct vring_tx_desc dd, *d = ⅆ dma_addr_t pa; struct sk_buff *skb; + + dd = *d1; + if (!(d->dma.status & TX_DMA_STATUS_DU)) break; 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 { struct vring_rx_desc rx; } __packed; -static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) +static inline int wil_rxdesc_tid(struct vring_rx_desc *d) { - return WIL_GET_BITS(d->dma.d0, 16, 29); + return WIL_GET_BITS(d->mac.d0, 0, 3); } -static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) +static inline int wil_rxdesc_cid(struct vring_rx_desc *d) { - return WIL_GET_BITS(d->mac.d1, 21, 24); + return WIL_GET_BITS(d->mac.d0, 4, 6); } -static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) +static inline int wil_rxdesc_mid(struct vring_rx_desc *d) { - return WIL_GET_BITS(d->mac.d1, 8, 9); + return WIL_GET_BITS(d->mac.d0, 8, 9); } -static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) +static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) { return WIL_GET_BITS(d->mac.d0, 10, 11); } +static inline int wil_rxdesc_subtype(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->mac.d0, 12, 15); +} + +static inline int wil_rxdesc_seq(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->mac.d0, 16, 27); +} + +static inline int wil_rxdesc_ext_subtype(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->mac.d0, 28, 31); +} + +static inline int wil_rxdesc_ds_bits(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->mac.d1, 8, 9); +} + +static inline int wil_rxdesc_mcs(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->mac.d1, 21, 24); +} + +static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d) +{ + return WIL_GET_BITS(d->dma.d0, 16, 29); +} + +static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb) +{ + return (void *)skb->cb; +} + #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) */ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) { - return wl->hw->conf.channel->band; + return wl->hw->conf.chandef.chan->band; } 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) dev = wl->current_dev; /* Switch the band (if necessary). This might change the active core. */ - err = b43_switch_band(wl, conf->channel); + err = b43_switch_band(wl, conf->chandef.chan); if (err) goto out_unlock_mutex; @@ -3882,8 +3882,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) /* Switch to the requested channel. * The firmware takes care of races with the TX handler. */ - if (conf->channel->hw_value != phy->channel) - b43_switch_channel(dev, conf->channel->hw_value); + if (conf->chandef.chan->hw_value != phy->channel) + b43_switch_channel(dev, conf->chandef.chan->hw_value); dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); @@ -5006,7 +5006,7 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = dev->stats.link_noise; 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 @@ #include "radio_2059.h" #include "main.h" +/* Force values to keep compatibility with wl */ +enum ht_rssi_type { + HT_RSSI_W1 = 0, + HT_RSSI_W2 = 1, + HT_RSSI_NB = 2, + HT_RSSI_IQ = 3, + HT_RSSI_TSSI_2G = 4, + HT_RSSI_TSSI_5G = 5, + HT_RSSI_TBD = 6, +}; + /************************************************** * Radio 2059. **************************************************/ @@ -37,8 +48,9 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_radio2059 *e) { - u8 i; - u16 routing; + static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3, }; + u16 r; + int core; b43_radio_write(dev, 0x16, e->radio_syn16); b43_radio_write(dev, 0x17, e->radio_syn17); @@ -53,25 +65,17 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, b43_radio_write(dev, 0x41, e->radio_syn41); b43_radio_write(dev, 0x43, e->radio_syn43); b43_radio_write(dev, 0x47, e->radio_syn47); - b43_radio_write(dev, 0x4a, e->radio_syn4a); - b43_radio_write(dev, 0x58, e->radio_syn58); - b43_radio_write(dev, 0x5a, e->radio_syn5a); - b43_radio_write(dev, 0x6a, e->radio_syn6a); - b43_radio_write(dev, 0x6d, e->radio_syn6d); - b43_radio_write(dev, 0x6e, e->radio_syn6e); - b43_radio_write(dev, 0x92, e->radio_syn92); - b43_radio_write(dev, 0x98, e->radio_syn98); - - for (i = 0; i < 2; i++) { - routing = i ? R2059_RXRX1 : R2059_TXRX0; - b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); - b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); - b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); - b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a); - b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d); - b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e); - b43_radio_write(dev, routing | 0x92, e->radio_rxtx92); - b43_radio_write(dev, routing | 0x98, e->radio_rxtx98); + + for (core = 0; core < 3; core++) { + r = routing[core]; + b43_radio_write(dev, r | 0x4a, e->radio_rxtx4a); + b43_radio_write(dev, r | 0x58, e->radio_rxtx58); + b43_radio_write(dev, r | 0x5a, e->radio_rxtx5a); + b43_radio_write(dev, r | 0x6a, e->radio_rxtx6a); + b43_radio_write(dev, r | 0x6d, e->radio_rxtx6d); + b43_radio_write(dev, r | 0x6e, e->radio_rxtx6e); + b43_radio_write(dev, r | 0x92, e->radio_rxtx92); + b43_radio_write(dev, r | 0x98, e->radio_rxtx98); } udelay(50); @@ -87,7 +91,7 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, static void b43_radio_2059_init(struct b43_wldev *dev) { - const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; + const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 }; const u16 radio_values[3][2] = { { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, }; @@ -106,17 +110,17 @@ static void b43_radio_2059_init(struct b43_wldev *dev) b43_radio_mask(dev, 0xc0, ~0x0080); if (1) { /* FIXME */ - b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); + b43_radio_set(dev, R2059_C3 | 0x4, 0x1); udelay(10); - b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); - b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); + b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1); + b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2); - b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); + b43_radio_set(dev, R2059_C3 | 0x4, 0x2); udelay(100); - b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); + b43_radio_mask(dev, R2059_C3 | 0x4, ~0x2); for (i = 0; i < 10000; i++) { - if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { + if (b43_radio_read(dev, R2059_C3 | 0x145) & 1) { i = 0; break; } @@ -125,7 +129,7 @@ static void b43_radio_2059_init(struct b43_wldev *dev) if (i) b43err(dev->wl, "radio 0x945 timeout\n"); - b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); + b43_radio_mask(dev, R2059_C3 | 0x4, ~0x1); b43_radio_set(dev, 0xa, 0x60); for (i = 0; i < 3; i++) { @@ -390,14 +394,14 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev) **************************************************/ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, - u8 rssi_type) + enum ht_rssi_type rssi_type) { static const u16 ctl_regs[3][2] = { { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, }, { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, }, { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, }, }; - static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, }; + static const u16 radio_r[] = { R2059_C1, R2059_C2, R2059_C3, }; int core; if (core_sel == 0) { @@ -411,13 +415,13 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, continue; switch (rssi_type) { - case 4: + case HT_RSSI_TSSI_2G: b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8); b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10); b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9); b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10); - b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1); + b43_radio_set(dev, R2059_C3 | 0xbf, 0x1); b43_radio_write(dev, radio_r[core] | 0x159, 0x11); break; @@ -429,8 +433,8 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, } } -static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, - u8 nsamp) +static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, enum ht_rssi_type type, + s32 *buf, u8 nsamp) { u16 phy_regs_values[12]; 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) static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1, B43_PHY_HT_TXPCTL_CMD_C2, B43_PHY_HT_TXPCTL_CMD_C3 }; + static const u16 status_regs[3] = { B43_PHY_HT_TX_PCTL_STATUS_C1, + B43_PHY_HT_TX_PCTL_STATUS_C2, + B43_PHY_HT_TX_PCTL_STATUS_C3 }; int i; if (!enable) { if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { /* We disable enabled TX pwr ctl, save it's state */ - /* - * TODO: find the registers. On N-PHY they were 0x1ed - * and 0x1ee, we need 3 such a registers for HT-PHY - */ + for (i = 0; i < 3; i++) + phy_ht->tx_pwr_idx[i] = + b43_phy_read(dev, status_regs[i]); } b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); } else { @@ -536,13 +542,25 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; + static const u16 base[] = { 0x840, 0x860, 0x880 }; + u16 save_regs[3][3]; s32 rssi_buf[6]; + int core; + + for (core = 0; core < 3; core++) { + save_regs[core][1] = b43_phy_read(dev, base[core] + 6); + save_regs[core][2] = b43_phy_read(dev, base[core] + 7); + save_regs[core][0] = b43_phy_read(dev, base[core] + 0); - /* TODO */ + b43_phy_write(dev, base[core] + 6, 0); + b43_phy_mask(dev, base[core] + 7, ~0xF); /* 0xF? Or just 0x6? */ + b43_phy_set(dev, base[core] + 0, 0x0400); + b43_phy_set(dev, base[core] + 0, 0x1000); + } b43_phy_ht_tx_tone(dev); udelay(20); - b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1); + b43_phy_ht_poll_rssi(dev, HT_RSSI_TSSI_2G, rssi_buf, 1); b43_phy_ht_stop_playback(dev); b43_phy_ht_reset_cca(dev); @@ -550,7 +568,23 @@ static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff; phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff; - /* TODO */ + for (core = 0; core < 3; core++) { + b43_phy_write(dev, base[core] + 0, save_regs[core][0]); + b43_phy_write(dev, base[core] + 6, save_regs[core][1]); + b43_phy_write(dev, base[core] + 7, save_regs[core][2]); + } +} + +static void b43_phy_ht_tssi_setup(struct b43_wldev *dev) +{ + static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3, }; + int core; + + /* 0x159 is probably TX_SSI_MUX or TSSIG (by comparing to N-PHY) */ + for (core = 0; core < 3; core++) { + b43_radio_set(dev, 0x8bf, 0x1); + b43_radio_write(dev, routing[core] | 0x0159, 0x0011); + } } 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) b43_phy_ht_tx_power_ctl(dev, false); b43_phy_ht_tx_power_ctl_idle_tssi(dev); b43_phy_ht_tx_power_ctl_setup(dev); + b43_phy_ht_tssi_setup(dev); b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); return 0; @@ -1011,8 +1046,9 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { - struct ieee80211_channel *channel = dev->wl->hw->conf.channel; - enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 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 @@ #define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ #define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ #define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ +#define B43_PHY_HT_EST_PWR_C1 0x118 +#define B43_PHY_HT_EST_PWR_C2 0x119 +#define B43_PHY_HT_EST_PWR_C3 0x11A #define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */ #define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */ #define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */ @@ -53,6 +56,8 @@ #define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0 #define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */ #define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8 +#define B43_PHY_HT_TX_PCTL_STATUS_C1 0x1ED +#define B43_PHY_HT_TX_PCTL_STATUS_C2 0x1EE #define B43_PHY_HT_TXPCTL_CMD_C2 0x222 #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F #define B43_PHY_HT_RSSI_C1 0x219 @@ -97,6 +102,7 @@ #define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */ #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 +#define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169) #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) 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) static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { - struct ieee80211_channel *channel = dev->wl->hw->conf.channel; - enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 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) b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || - (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && - (sprom->boardflags_lo & B43_BFL_FEM))) { + (dev->dev->board_type == SSB_BOARD_BU4312) || + (dev->phy.rev == 0 && (sprom->boardflags_lo & B43_BFL_FEM))) { b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); 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 { B43_RFSEQ_UPDATE_GAINU, }; -enum b43_nphy_rssi_type { - B43_NPHY_RSSI_X = 0, - B43_NPHY_RSSI_Y, - B43_NPHY_RSSI_Z, - B43_NPHY_RSSI_PWRDET, - B43_NPHY_RSSI_TSSI_I, - B43_NPHY_RSSI_TSSI_Q, - B43_NPHY_RSSI_TBD, +enum n_intc_override { + N_INTC_OVERRIDE_OFF = 0, + N_INTC_OVERRIDE_TRSW = 1, + N_INTC_OVERRIDE_PA = 2, + N_INTC_OVERRIDE_EXT_LNA_PU = 3, + N_INTC_OVERRIDE_EXT_LNA_GAIN = 4, +}; + +enum n_rssi_type { + N_RSSI_W1 = 0, + N_RSSI_W2, + N_RSSI_NB, + N_RSSI_IQ, + N_RSSI_TSSI_2G, + N_RSSI_TSSI_5G, + N_RSSI_TBD, +}; + +enum n_rail_type { + N_RAIL_I = 0, + N_RAIL_Q = 1, }; 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) } /************************************************** - * RF (just without b43_nphy_rf_control_intc_override) + * RF (just without b43_nphy_rf_ctl_intc_override) **************************************************/ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ @@ -128,9 +141,9 @@ ok: } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */ -static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field, - u16 value, u8 core, bool off, - u8 override) +static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field, + u16 value, u8 core, bool off, + u8 override) { const struct nphy_rf_control_override_rev7 *e; u16 en_addrs[3][2] = { @@ -168,8 +181,8 @@ static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field, } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ -static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, - u16 value, u8 core, bool off) +static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field, + u16 value, u8 core, bool off) { int i; u8 index = fls(field); @@ -244,14 +257,14 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ -static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, - u16 value, u8 core) +static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev, + enum n_intc_override intc_override, + u16 value, u8 core) { u8 i, j; u16 reg, tmp, val; B43_WARN_ON(dev->phy.rev < 3); - B43_WARN_ON(field > 4); for (i = 0; i < 2; i++) { 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, B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; b43_phy_set(dev, reg, 0x400); - switch (field) { - case 0: + switch (intc_override) { + case N_INTC_OVERRIDE_OFF: b43_phy_write(dev, reg, 0); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); break; - case 1: + case N_INTC_OVERRIDE_TRSW: if (!i) { b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, 0xFC3F, (value << 6)); @@ -307,7 +320,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 0xFFFE); } break; - case 2: + case N_INTC_OVERRIDE_PA: if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { tmp = 0x0020; val = value << 5; @@ -317,7 +330,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, } b43_phy_maskset(dev, reg, ~tmp, val); break; - case 3: + case N_INTC_OVERRIDE_EXT_LNA_PU: if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { tmp = 0x0001; val = value; @@ -327,7 +340,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, } b43_phy_maskset(dev, reg, ~tmp, val); break; - case 4: + case N_INTC_OVERRIDE_EXT_LNA_GAIN: if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { tmp = 0x0002; val = value << 1; @@ -1011,7 +1024,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) if (sprom->revision < 4) workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM - && dev->dev->board_type == 0x46D + && dev->dev->board_type == SSB_BOARD_CB2_4321 && dev->dev->board_rev >= 0x41); else workaround = @@ -1207,8 +1220,9 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, - s8 offset, u8 core, u8 rail, - enum b43_nphy_rssi_type type) + s8 offset, u8 core, + enum n_rail_type rail, + enum n_rssi_type rssi_type) { u16 tmp; bool core1or5 = (core == 1) || (core == 5); @@ -1217,63 +1231,74 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, offset = clamp_val(offset, -32, 31); tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); - if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); - if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); - if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); - if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); - - if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); - if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); - if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); - if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); - - if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); - if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); - if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); - if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); - - if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); - if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); - if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); - if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); - - if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); - if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); - if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); - if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); - - if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); - if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); - - if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q)) - b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); - if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q)) - b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); + switch (rssi_type) { + case N_RSSI_NB: + if (core1or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); + if (core1or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); + if (core2or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); + if (core2or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); + break; + case N_RSSI_W1: + if (core1or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); + if (core1or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); + if (core2or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); + if (core2or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); + break; + case N_RSSI_W2: + if (core1or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); + if (core1or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); + if (core2or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); + if (core2or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); + break; + case N_RSSI_TBD: + if (core1or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); + if (core1or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); + if (core2or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); + if (core2or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); + break; + case N_RSSI_IQ: + if (core1or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); + if (core1or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); + if (core2or5 && rail == N_RAIL_I) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); + if (core2or5 && rail == N_RAIL_Q) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); + break; + case N_RSSI_TSSI_2G: + if (core1or5) + b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); + if (core2or5) + b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); + break; + case N_RSSI_TSSI_5G: + if (core1or5) + b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); + if (core2or5) + b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); + break; + } } -static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, + enum n_rssi_type rssi_type) { u8 i; u16 reg, val; @@ -1296,7 +1321,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); - if (type < 3) { + if (rssi_type == N_RSSI_W1 || + rssi_type == N_RSSI_W2 || + rssi_type == N_RSSI_NB) { reg = (i == 0) ? B43_NPHY_AFECTL_C1 : B43_NPHY_AFECTL_C2; @@ -1307,9 +1334,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) B43_NPHY_RFCTL_LUT_TRSW_UP2; b43_phy_maskset(dev, reg, 0xFFC3, 0); - if (type == 0) + if (rssi_type == N_RSSI_W1) val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; - else if (type == 1) + else if (rssi_type == N_RSSI_W2) val = 16; else val = 32; @@ -1320,9 +1347,9 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) B43_NPHY_TXF_40CO_B32S1; b43_phy_set(dev, reg, 0x0020); } else { - if (type == 6) + if (rssi_type == N_RSSI_TBD) val = 0x0100; - else if (type == 3) + else if (rssi_type == N_RSSI_IQ) val = 0x0200; else val = 0x0300; @@ -1334,7 +1361,8 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) b43_phy_maskset(dev, reg, 0xFCFF, val); b43_phy_maskset(dev, reg, 0xF3FF, val << 2); - if (type != 3 && type != 6) { + if (rssi_type != N_RSSI_IQ && + rssi_type != N_RSSI_TBD) { enum ieee80211_band band = b43_current_band(dev->wl); @@ -1344,7 +1372,7 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) val = 0x11; reg = (i == 0) ? 0x2000 : 0x3000; reg |= B2055_PADDRV; - b43_radio_write16(dev, reg, val); + b43_radio_write(dev, reg, val); reg = (i == 0) ? B43_NPHY_AFECTL_OVER1 : @@ -1356,33 +1384,43 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) } } -static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, + enum n_rssi_type rssi_type) { u16 val; + bool rssi_w1_w2_nb = false; - if (type < 3) + switch (rssi_type) { + case N_RSSI_W1: + case N_RSSI_W2: + case N_RSSI_NB: val = 0; - else if (type == 6) + rssi_w1_w2_nb = true; + break; + case N_RSSI_TBD: val = 1; - else if (type == 3) + break; + case N_RSSI_IQ: val = 2; - else + break; + default: val = 3; + } val = (val << 12) | (val << 14); b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); - if (type < 3) { + if (rssi_w1_w2_nb) { b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, - (type + 1) << 4); + (rssi_type + 1) << 4); b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, - (type + 1) << 4); + (rssi_type + 1) << 4); } if (code == 0) { b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); - if (type < 3) { + if (rssi_w1_w2_nb) { b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, ~(B43_NPHY_RFCTL_CMD_RXEN | B43_NPHY_RFCTL_CMD_CORESEL)); @@ -1398,7 +1436,7 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) } } else { b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); - if (type < 3) { + if (rssi_w1_w2_nb) { b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, ~(B43_NPHY_RFCTL_CMD_RXEN | B43_NPHY_RFCTL_CMD_CORESEL), @@ -1418,7 +1456,8 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ -static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, + enum n_rssi_type type) { if (dev->phy.rev >= 3) 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) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ -static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) +static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, + enum n_rssi_type rssi_type, u8 *buf) { int i; for (i = 0; i < 2; i++) { - if (type == 2) { + if (rssi_type == N_RSSI_NB) { if (i == 0) { b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, 0xFC, buf[0]); @@ -1455,8 +1495,8 @@ static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ -static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, - u8 nsamp) +static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type, + s32 *buf, u8 nsamp) { int i; int out; @@ -1487,7 +1527,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, save_regs_phy[8] = 0; } - b43_nphy_rssi_select(dev, 5, type); + b43_nphy_rssi_select(dev, 5, rssi_type); if (dev->phy.rev < 2) { 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) u16 r; /* routing */ u8 rx_core_state; - u8 core, i, j; + int core, i, j, vcm; class = b43_nphy_classifier(dev, 0, 0); b43_nphy_classifier(dev, 7, 4); @@ -1586,19 +1626,19 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); - b43_nphy_rf_control_intc_override(dev, 0, 0, 7); - b43_nphy_rf_control_intc_override(dev, 1, 1, 7); - b43_nphy_rf_control_override(dev, 0x1, 0, 0, false); - b43_nphy_rf_control_override(dev, 0x2, 1, 0, false); - b43_nphy_rf_control_override(dev, 0x80, 1, 0, false); - b43_nphy_rf_control_override(dev, 0x40, 1, 0, false); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7); + b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false); + b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false); + b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false); + b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false); if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - b43_nphy_rf_control_override(dev, 0x20, 0, 0, false); - b43_nphy_rf_control_override(dev, 0x10, 1, 0, false); + b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false); + b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false); } else { - b43_nphy_rf_control_override(dev, 0x10, 0, 0, false); - b43_nphy_rf_control_override(dev, 0x20, 1, 0, false); + b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false); + b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false); } 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) if (!(rx_core_state & (1 << core))) continue; r = core ? B2056_RX1 : B2056_RX0; - b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2); - b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2); - for (i = 0; i < 8; i++) { + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_I, + N_RSSI_NB); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_Q, + N_RSSI_NB); + + /* Grab RSSI results for every possible VCM */ + for (vcm = 0; vcm < 8; vcm++) { b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, - i << 2); - b43_nphy_poll_rssi(dev, 2, results[i], 8); + vcm << 2); + b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8); } + + /* Find out which VCM got the best results */ for (i = 0; i < 4; i += 2) { - s32 curr; + s32 currd; s32 mind = 0x100000; s32 minpoll = 249; u8 minvcm = 0; if (2 * core != i) continue; - for (j = 0; j < 8; j++) { - curr = results[j][i] * results[j][i] + - results[j][i + 1] * results[j][i]; - if (curr < mind) { - mind = curr; - minvcm = j; + for (vcm = 0; vcm < 8; vcm++) { + currd = results[vcm][i] * results[vcm][i] + + results[vcm][i + 1] * results[vcm][i]; + if (currd < mind) { + mind = currd; + minvcm = vcm; } - if (results[j][i] < minpoll) - minpoll = results[j][i]; + if (results[vcm][i] < minpoll) + minpoll = results[vcm][i]; } vcm_final = minvcm; results_min[i] = minpoll; } + + /* Select the best VCM */ b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, vcm_final << 2); + for (i = 0; i < 4; i++) { if (core != i / 2) continue; @@ -1647,16 +1696,19 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) offset[i] = -32; b43_nphy_scale_offset_rssi(dev, 0, offset[i], (i / 2 == 0) ? 1 : 2, - (i % 2 == 0) ? 0 : 1, - 2); + (i % 2 == 0) ? N_RAIL_I : N_RAIL_Q, + N_RSSI_NB); } } + for (core = 0; core < 2; core++) { if (!(rx_core_state & (1 << core))) continue; for (i = 0; i < 2; i++) { - b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i); - b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, + N_RAIL_I, i); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, + N_RAIL_Q, i); b43_nphy_poll_rssi(dev, i, poll_results, 8); for (j = 0; j < 4; j++) { if (j / 2 == core) { @@ -1696,8 +1748,13 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; } - rssical_radio_regs[0] = b43_radio_read(dev, 0x602B); - rssical_radio_regs[0] = b43_radio_read(dev, 0x702B); + if (dev->phy.rev >= 7) { + } else { + rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 | + B2056_RX_RSSI_MISC); + rssical_radio_regs[1] = b43_radio_read(dev, B2056_RX1 | + B2056_RX_RSSI_MISC); + } rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); 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) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ -static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) +static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type) { - int i, j; + int i, j, vcm; u8 state[4]; u8 code, val; u16 class, override; @@ -1743,10 +1800,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) s32 results[4][4] = { }; s32 miniq[4][2] = { }; - if (type == 2) { + if (type == N_RSSI_NB) { code = 0; val = 6; - } else if (type < 2) { + } else if (type == N_RSSI_W1 || type == N_RSSI_W2) { code = 25; val = 4; } else { @@ -1765,63 +1822,63 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) override = 0x110; regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); - regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX); + regs_save_radio[0] = b43_radio_read(dev, B2055_C1_PD_RXTX); b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); - b43_radio_write16(dev, B2055_C1_PD_RXTX, val); + b43_radio_write(dev, B2055_C1_PD_RXTX, val); regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); - regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX); + regs_save_radio[1] = b43_radio_read(dev, B2055_C2_PD_RXTX); b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); - b43_radio_write16(dev, B2055_C2_PD_RXTX, val); + b43_radio_write(dev, B2055_C2_PD_RXTX, val); - state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07; - state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07; + state[0] = b43_radio_read(dev, B2055_C1_PD_RSSIMISC) & 0x07; + state[1] = b43_radio_read(dev, B2055_C2_PD_RSSIMISC) & 0x07; b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); - state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07; - state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07; + state[2] = b43_radio_read(dev, B2055_C1_SP_RSSI) & 0x07; + state[3] = b43_radio_read(dev, B2055_C2_SP_RSSI) & 0x07; b43_nphy_rssi_select(dev, 5, type); - b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type); - b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type); + b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_I, type); + b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_Q, type); - for (i = 0; i < 4; i++) { + for (vcm = 0; vcm < 4; vcm++) { u8 tmp[4]; for (j = 0; j < 4; j++) - tmp[j] = i; - if (type != 1) + tmp[j] = vcm; + if (type != N_RSSI_W2) b43_nphy_set_rssi_2055_vcm(dev, type, tmp); - b43_nphy_poll_rssi(dev, type, results[i], 8); - if (type < 2) + b43_nphy_poll_rssi(dev, type, results[vcm], 8); + if (type == N_RSSI_W1 || type == N_RSSI_W2) for (j = 0; j < 2; j++) - miniq[i][j] = min(results[i][2 * j], - results[i][2 * j + 1]); + miniq[vcm][j] = min(results[vcm][2 * j], + results[vcm][2 * j + 1]); } for (i = 0; i < 4; i++) { s32 mind = 0x100000; u8 minvcm = 0; s32 minpoll = 249; - s32 curr; - for (j = 0; j < 4; j++) { - if (type == 2) - curr = abs(results[j][i]); + s32 currd; + for (vcm = 0; vcm < 4; vcm++) { + if (type == N_RSSI_NB) + currd = abs(results[vcm][i] - code * 8); else - curr = abs(miniq[j][i / 2] - code * 8); + currd = abs(miniq[vcm][i / 2] - code * 8); - if (curr < mind) { - mind = curr; - minvcm = j; + if (currd < mind) { + mind = currd; + minvcm = vcm; } - if (results[j][i] < minpoll) - minpoll = results[j][i]; + if (results[vcm][i] < minpoll) + minpoll = results[vcm][i]; } results_min[i] = minpoll; vcm_final[i] = minvcm; } - if (type != 1) + if (type != N_RSSI_W2) b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); for (i = 0; i < 4; i++) { @@ -1836,7 +1893,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) offset[i] = code - 32; core = (i / 2) ? 2 : 1; - rail = (i % 2) ? 1 : 0; + rail = (i % 2) ? N_RAIL_Q : N_RAIL_I; b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, type); @@ -1847,37 +1904,37 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) switch (state[2]) { case 1: - b43_nphy_rssi_select(dev, 1, 2); + b43_nphy_rssi_select(dev, 1, N_RSSI_NB); break; case 4: - b43_nphy_rssi_select(dev, 1, 0); + b43_nphy_rssi_select(dev, 1, N_RSSI_W1); break; case 2: - b43_nphy_rssi_select(dev, 1, 1); + b43_nphy_rssi_select(dev, 1, N_RSSI_W2); break; default: - b43_nphy_rssi_select(dev, 1, 1); + b43_nphy_rssi_select(dev, 1, N_RSSI_W2); break; } switch (state[3]) { case 1: - b43_nphy_rssi_select(dev, 2, 2); + b43_nphy_rssi_select(dev, 2, N_RSSI_NB); break; case 4: - b43_nphy_rssi_select(dev, 2, 0); + b43_nphy_rssi_select(dev, 2, N_RSSI_W1); break; default: - b43_nphy_rssi_select(dev, 2, 1); + b43_nphy_rssi_select(dev, 2, N_RSSI_W2); break; } b43_nphy_rssi_select(dev, 0, type); b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); - b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); + b43_radio_write(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); - b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); + b43_radio_write(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); b43_nphy_classifier(dev, 7, class); b43_nphy_write_clip_detection(dev, clip_state); @@ -1895,9 +1952,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev) if (dev->phy.rev >= 3) { b43_nphy_rev3_rssi_cal(dev); } else { - b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z); - b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X); - b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y); + b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB); + b43_nphy_rev2_rssi_cal(dev, N_RSSI_W1); + b43_nphy_rev2_rssi_cal(dev, N_RSSI_W2); } } @@ -1930,10 +1987,8 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); /* Set Clip 2 detect */ - b43_phy_set(dev, B43_NPHY_C1_CGAINI, - B43_NPHY_C1_CGAINI_CL2DETECT); - b43_phy_set(dev, B43_NPHY_C2_CGAINI, - B43_NPHY_C2_CGAINI_CL2DETECT); + b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT); + b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT); b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, 0x17); @@ -1967,22 +2022,22 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); - b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); - b43_phy_write(dev, 0x2A7, e->init_gain); + b43_phy_write(dev, B43_NPHY_REV3_C1_INITGAIN_A, e->init_gain); + b43_phy_write(dev, B43_NPHY_REV3_C2_INITGAIN_A, e->init_gain); + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, e->rfseq_init); - /* TODO: check defines. Do not match variables names */ - b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); - b43_phy_write(dev, 0x2A9, e->cliphi_gain); - b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); - b43_phy_write(dev, 0x2AB, e->clipmd_gain); - b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); - b43_phy_write(dev, 0x2AD, e->cliplo_gain); - - b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); - b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); - b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); + b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_HIGAIN_A, e->cliphi_gain); + b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_HIGAIN_A, e->cliphi_gain); + b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_MEDGAIN_A, e->clipmd_gain); + b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_MEDGAIN_A, e->clipmd_gain); + b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_A, e->cliplo_gain); + b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_A, e->cliplo_gain); + + b43_phy_maskset(dev, B43_NPHY_CRSMINPOWER0, 0xFF00, e->crsmin); + b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERL0, 0xFF00, e->crsminl); + b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERU0, 0xFF00, e->crsminu); b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, @@ -2164,8 +2219,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000); } if (phy->rev <= 8) { - b43_phy_write(dev, 0x23F, 0x1B0); - b43_phy_write(dev, 0x240, 0x1B0); + b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0); + b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0); } if (phy->rev >= 8) b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72); @@ -2182,8 +2237,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); - b43_phy_maskset(dev, 0x299, 0x3FFF, 0x4000); - b43_phy_maskset(dev, 0x29D, 0x3FFF, 0x4000); + b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000); + b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000); lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154); lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159); @@ -2260,11 +2315,11 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16), rx2tx_lut_40_11n); } - b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, false, 2); + b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2); } b43_phy_write(dev, 0x32F, 0x3); if (phy->radio_rev == 4 || phy->radio_rev == 6) - b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, false, 0); + b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0); if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) { if (sprom->revision && @@ -2450,8 +2505,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) u16 tmp16; u32 tmp32; - b43_phy_write(dev, 0x23f, 0x1f8); - b43_phy_write(dev, 0x240, 0x1f8); + b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1f8); + b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1f8); tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); tmp32 &= 0xffffff; @@ -2464,8 +2519,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); - b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); - b43_phy_write(dev, 0x2AE, 0x000C); + b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_B, 0x000C); + b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_B, 0x000C); /* TX to RX */ 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) 0x2 : 0x9C40; b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); - b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); + b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700); if (!dev->phy.is_40mhz) { b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); @@ -2542,18 +2597,18 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) } /* Dropped probably-always-true condition */ - b43_phy_write(dev, 0x224, 0x03eb); - b43_phy_write(dev, 0x225, 0x03eb); - b43_phy_write(dev, 0x226, 0x0341); - b43_phy_write(dev, 0x227, 0x0341); - b43_phy_write(dev, 0x228, 0x042b); - b43_phy_write(dev, 0x229, 0x042b); - b43_phy_write(dev, 0x22a, 0x0381); - b43_phy_write(dev, 0x22b, 0x0381); - b43_phy_write(dev, 0x22c, 0x042b); - b43_phy_write(dev, 0x22d, 0x042b); - b43_phy_write(dev, 0x22e, 0x0381); - b43_phy_write(dev, 0x22f, 0x0381); + b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb); + b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb); + b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); + b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); + b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b); + b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b); + b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH0, 0x0381); + b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH1, 0x0381); + b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH0, 0x042b); + b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH1, 0x042b); + b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH0, 0x0381); + b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH1, 0x0381); if (dev->phy.rev >= 6 && sprom->boardflags2_lo & B43_BFL2_SINGLEANT_CCK) ; /* TODO: 0x0080000000000000 HF */ @@ -2572,7 +2627,7 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || - dev->dev->board_type == 0x8B) { + dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93) { delays1[0] = 0x1; delays1[5] = 0x14; } @@ -3120,21 +3175,21 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) b43_nphy_ipa_internal_tssi_setup(dev); if (phy->rev >= 7) - b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, false, 0); + b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0); else if (phy->rev >= 3) - b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false); + b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false); b43_nphy_stop_playback(dev); b43_nphy_tx_tone(dev, 0xFA0, 0, false, false); udelay(20); - tmp = b43_nphy_poll_rssi(dev, 4, rssi, 1); + tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1); b43_nphy_stop_playback(dev); - b43_nphy_rssi_select(dev, 0, 0); + b43_nphy_rssi_select(dev, 0, N_RSSI_W1); if (phy->rev >= 7) - b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, true, 0); + b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0); else if (phy->rev >= 3) - b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true); + b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true); if (phy->rev >= 3) { 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) b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); } - b43_nphy_rf_control_intc_override(dev, 2, 0, 3); - b43_nphy_rf_control_override(dev, 8, 0, 3, false); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 0, 3); + b43_nphy_rf_ctl_override(dev, 8, 0, 3, false); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); if (core == 0) { @@ -3584,8 +3639,10 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) rxval = 4; txval = 2; } - b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1)); - b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core)); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, rxval, + core + 1); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, txval, + 2 - core); } #endif @@ -3847,9 +3904,13 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; } - /* TODO use some definitions */ - b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]); - b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]); + if (dev->phy.rev >= 7) { + } else { + b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3, + rssical_radio_regs[0]); + b43_radio_maskset(dev, B2056_RX1 | B2056_RX_RSSI_MISC, 0xE3, + rssical_radio_regs[1]); + } b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]); 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) tmp = (i == 0) ? 0x2000 : 0x3000; offset = i * 11; - save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL); - save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL); - save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS); - save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS); - save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS); - save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV); - save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1); - save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2); - save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL); - save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC); - save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1); + save[offset + 0] = b43_radio_read(dev, B2055_CAL_RVARCTL); + save[offset + 1] = b43_radio_read(dev, B2055_CAL_LPOCTL); + save[offset + 2] = b43_radio_read(dev, B2055_CAL_TS); + save[offset + 3] = b43_radio_read(dev, B2055_CAL_RCCALRTS); + save[offset + 4] = b43_radio_read(dev, B2055_CAL_RCALRTS); + save[offset + 5] = b43_radio_read(dev, B2055_PADDRV); + save[offset + 6] = b43_radio_read(dev, B2055_XOCTL1); + save[offset + 7] = b43_radio_read(dev, B2055_XOCTL2); + save[offset + 8] = b43_radio_read(dev, B2055_XOREGUL); + save[offset + 9] = b43_radio_read(dev, B2055_XOMISC); + save[offset + 10] = b43_radio_read(dev, B2055_PLL_LFC1); if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A); - b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); - b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); - b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); - b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); + b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x0A); + b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40); + b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55); + b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0); + b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0); if (nphy->ipa5g_on) { - b43_radio_write16(dev, tmp | B2055_PADDRV, 4); - b43_radio_write16(dev, tmp | B2055_XOCTL1, 1); + b43_radio_write(dev, tmp | B2055_PADDRV, 4); + b43_radio_write(dev, tmp | B2055_XOCTL1, 1); } else { - b43_radio_write16(dev, tmp | B2055_PADDRV, 0); - b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F); + b43_radio_write(dev, tmp | B2055_PADDRV, 0); + b43_radio_write(dev, tmp | B2055_XOCTL1, 0x2F); } - b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); + b43_radio_write(dev, tmp | B2055_XOCTL2, 0); } else { - b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06); - b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); - b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); - b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); - b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); - b43_radio_write16(dev, tmp | B2055_XOCTL1, 0); + b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x06); + b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40); + b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55); + b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0); + b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0); + b43_radio_write(dev, tmp | B2055_XOCTL1, 0); if (nphy->ipa2g_on) { - b43_radio_write16(dev, tmp | B2055_PADDRV, 6); - b43_radio_write16(dev, tmp | B2055_XOCTL2, + b43_radio_write(dev, tmp | B2055_PADDRV, 6); + b43_radio_write(dev, tmp | B2055_XOCTL2, (dev->phy.rev < 5) ? 0x11 : 0x01); } else { - b43_radio_write16(dev, tmp | B2055_PADDRV, 0); - b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); + b43_radio_write(dev, tmp | B2055_PADDRV, 0); + b43_radio_write(dev, tmp | B2055_XOCTL2, 0); } } - b43_radio_write16(dev, tmp | B2055_XOREGUL, 0); - b43_radio_write16(dev, tmp | B2055_XOMISC, 0); - b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0); + b43_radio_write(dev, tmp | B2055_XOREGUL, 0); + b43_radio_write(dev, tmp | B2055_XOMISC, 0); + b43_radio_write(dev, tmp | B2055_PLL_LFC1, 0); } } else { - save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); - b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); + save[0] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL1); + b43_radio_write(dev, B2055_C1_TX_RF_IQCAL1, 0x29); - save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2); - b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54); + save[1] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL2); + b43_radio_write(dev, B2055_C1_TX_RF_IQCAL2, 0x54); - save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1); - b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29); + save[2] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL1); + b43_radio_write(dev, B2055_C2_TX_RF_IQCAL1, 0x29); - save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2); - b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54); + save[3] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL2); + b43_radio_write(dev, B2055_C2_TX_RF_IQCAL2, 0x54); - save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX); - save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX); + save[3] = b43_radio_read(dev, B2055_C1_PWRDET_RXTX); + save[4] = b43_radio_read(dev, B2055_C2_PWRDET_RXTX); if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ)) { - b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04); - b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04); + b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x04); + b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x04); } else { - b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20); - b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20); + b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x20); + b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x20); } if (dev->phy.rev < 2) { @@ -4144,9 +4205,9 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); - b43_nphy_rf_control_intc_override(dev, 2, 1, 3); - b43_nphy_rf_control_intc_override(dev, 1, 2, 1); - b43_nphy_rf_control_intc_override(dev, 1, 8, 2); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1); + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2); regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); 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, tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | (cur_lna << 2)); - b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, + b43_nphy_rf_ctl_override(dev, 0x400, tmp[0], 3, false); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); b43_nphy_stop_playback(dev); @@ -4728,7 +4789,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, break; } - b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); + b43_nphy_rf_ctl_override(dev, 0x400, 0, 3, true); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); @@ -4797,18 +4858,6 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) * N-PHY init **************************************************/ -/* - * Upload the N-PHY tables. - * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables - */ -static void b43_nphy_tables_init(struct b43_wldev *dev) -{ - if (dev->phy.rev < 3) - b43_nphy_rev0_1_2_tables_init(dev); - else - b43_nphy_rev3plus_tables_init(dev); -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) { @@ -4958,7 +5007,7 @@ static int b43_phy_initn(struct b43_wldev *dev) if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && - dev->dev->board_type == 0x8B)) + dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93)) b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); else b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); @@ -5100,63 +5149,11 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev, /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) { - struct bcma_drv_cc __maybe_unused *cc; - u32 __maybe_unused pmu_ctl; - switch (dev->dev->bus_type) { #ifdef CONFIG_B43_BCMA case B43_BUS_BCMA: - cc = &dev->dev->bdev->bus->drv_cc; - if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) { - if (avoid) { - bcma_chipco_pll_write(cc, 0x0, 0x11500010); - bcma_chipco_pll_write(cc, 0x1, 0x000C0C06); - bcma_chipco_pll_write(cc, 0x2, 0x0F600a08); - bcma_chipco_pll_write(cc, 0x3, 0x00000000); - bcma_chipco_pll_write(cc, 0x4, 0x2001E920); - bcma_chipco_pll_write(cc, 0x5, 0x88888815); - } else { - bcma_chipco_pll_write(cc, 0x0, 0x11100010); - bcma_chipco_pll_write(cc, 0x1, 0x000c0c06); - bcma_chipco_pll_write(cc, 0x2, 0x03000a08); - bcma_chipco_pll_write(cc, 0x3, 0x00000000); - bcma_chipco_pll_write(cc, 0x4, 0x200005c0); - bcma_chipco_pll_write(cc, 0x5, 0x88888815); - } - pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD; - } else if (dev->dev->chip_id == 0x4716) { - if (avoid) { - bcma_chipco_pll_write(cc, 0x0, 0x11500060); - bcma_chipco_pll_write(cc, 0x1, 0x080C0C06); - bcma_chipco_pll_write(cc, 0x2, 0x0F600000); - bcma_chipco_pll_write(cc, 0x3, 0x00000000); - bcma_chipco_pll_write(cc, 0x4, 0x2001E924); - bcma_chipco_pll_write(cc, 0x5, 0x88888815); - } else { - bcma_chipco_pll_write(cc, 0x0, 0x11100060); - bcma_chipco_pll_write(cc, 0x1, 0x080c0c06); - bcma_chipco_pll_write(cc, 0x2, 0x03000000); - bcma_chipco_pll_write(cc, 0x3, 0x00000000); - bcma_chipco_pll_write(cc, 0x4, 0x200005c0); - bcma_chipco_pll_write(cc, 0x5, 0x88888815); - } - pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD | - BCMA_CC_PMU_CTL_NOILPONW; - } else if (dev->dev->chip_id == 0x4322 || - dev->dev->chip_id == 0x4340 || - dev->dev->chip_id == 0x4341) { - bcma_chipco_pll_write(cc, 0x0, 0x11100070); - bcma_chipco_pll_write(cc, 0x1, 0x1014140a); - bcma_chipco_pll_write(cc, 0x5, 0x88888854); - if (avoid) - bcma_chipco_pll_write(cc, 0x2, 0x05201828); - else - bcma_chipco_pll_write(cc, 0x2, 0x05001828); - pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD; - } else { - return; - } - bcma_cc_set32(cc, BCMA_CC_PMU_CTL, pmu_ctl); + bcma_pmu_spuravoid_pllupdate(&dev->dev->bdev->bus->drv_cc, + avoid); break; #endif #ifdef CONFIG_B43_SSB @@ -5527,8 +5524,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) static int b43_nphy_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { - struct ieee80211_channel *channel = dev->wl->hw->conf.channel; - enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 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 @@ #define B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT 7 #define B43_NPHY_C1_INITGAIN_TRRX 0x1000 /* TR RX index */ #define B43_NPHY_C1_INITGAIN_TRTX 0x2000 /* TR TX index */ +#define B43_NPHY_REV3_C1_INITGAIN_A B43_PHY_N(0x020) #define B43_NPHY_C1_CLIP1_HIGAIN B43_PHY_N(0x021) /* Core 1 clip1 high gain code */ +#define B43_NPHY_REV3_C1_INITGAIN_B B43_PHY_N(0x021) #define B43_NPHY_C1_CLIP1_MEDGAIN B43_PHY_N(0x022) /* Core 1 clip1 medium gain code */ +#define B43_NPHY_REV3_C1_CLIP_HIGAIN_A B43_PHY_N(0x022) #define B43_NPHY_C1_CLIP1_LOGAIN B43_PHY_N(0x023) /* Core 1 clip1 low gain code */ +#define B43_NPHY_REV3_C1_CLIP_HIGAIN_B B43_PHY_N(0x023) #define B43_NPHY_C1_CLIP2_GAIN B43_PHY_N(0x024) /* Core 1 clip2 gain code */ +#define B43_NPHY_REV3_C1_CLIP_MEDGAIN_A B43_PHY_N(0x024) #define B43_NPHY_C1_FILTERGAIN B43_PHY_N(0x025) /* Core 1 filter gain */ #define B43_NPHY_C1_LPF_QHPF_BW B43_PHY_N(0x026) /* Core 1 LPF Q HP F bandwidth */ #define B43_NPHY_C1_CLIPWBTHRES B43_PHY_N(0x027) /* Core 1 clip wideband threshold */ @@ -107,10 +112,15 @@ #define B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT 7 #define B43_NPHY_C2_INITGAIN_TRRX 0x1000 /* TR RX index */ #define B43_NPHY_C2_INITGAIN_TRTX 0x2000 /* TR TX index */ +#define B43_NPHY_REV3_C1_CLIP_MEDGAIN_B B43_PHY_N(0x036) #define B43_NPHY_C2_CLIP1_HIGAIN B43_PHY_N(0x037) /* Core 2 clip1 high gain code */ +#define B43_NPHY_REV3_C1_CLIP_LOGAIN_A B43_PHY_N(0x037) #define B43_NPHY_C2_CLIP1_MEDGAIN B43_PHY_N(0x038) /* Core 2 clip1 medium gain code */ +#define B43_NPHY_REV3_C1_CLIP_LOGAIN_B B43_PHY_N(0x038) #define B43_NPHY_C2_CLIP1_LOGAIN B43_PHY_N(0x039) /* Core 2 clip1 low gain code */ +#define B43_NPHY_REV3_C1_CLIP2_GAIN_A B43_PHY_N(0x039) #define B43_NPHY_C2_CLIP2_GAIN B43_PHY_N(0x03A) /* Core 2 clip2 gain code */ +#define B43_NPHY_REV3_C1_CLIP2_GAIN_B B43_PHY_N(0x03A) #define B43_NPHY_C2_FILTERGAIN B43_PHY_N(0x03B) /* Core 2 filter gain */ #define B43_NPHY_C2_LPF_QHPF_BW B43_PHY_N(0x03C) /* Core 2 LPF Q HP F bandwidth */ #define B43_NPHY_C2_CLIPWBTHRES B43_PHY_N(0x03D) /* Core 2 clip wideband threshold */ @@ -706,10 +716,146 @@ #define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power control init */ #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 +#define B43_NPHY_ED_CRSEN B43_PHY_N(0x223) +#define B43_NPHY_ED_CRS40ASSERTTHRESH0 B43_PHY_N(0x224) +#define B43_NPHY_ED_CRS40ASSERTTHRESH1 B43_PHY_N(0x225) +#define B43_NPHY_ED_CRS40DEASSERTTHRESH0 B43_PHY_N(0x226) +#define B43_NPHY_ED_CRS40DEASSERTTHRESH1 B43_PHY_N(0x227) +#define B43_NPHY_ED_CRS20LASSERTTHRESH0 B43_PHY_N(0x228) +#define B43_NPHY_ED_CRS20LASSERTTHRESH1 B43_PHY_N(0x229) +#define B43_NPHY_ED_CRS20LDEASSERTTHRESH0 B43_PHY_N(0x22A) +#define B43_NPHY_ED_CRS20LDEASSERTTHRESH1 B43_PHY_N(0x22B) +#define B43_NPHY_ED_CRS20UASSERTTHRESH0 B43_PHY_N(0x22C) +#define B43_NPHY_ED_CRS20UASSERTTHRESH1 B43_PHY_N(0x22D) +#define B43_NPHY_ED_CRS20UDEASSERTTHRESH0 B43_PHY_N(0x22E) +#define B43_NPHY_ED_CRS20UDEASSERTTHRESH1 B43_PHY_N(0x22F) +#define B43_NPHY_ED_CRS B43_PHY_N(0x230) +#define B43_NPHY_TIMEOUTEN B43_PHY_N(0x231) +#define B43_NPHY_OFDMPAYDECODETIMEOUTLEN B43_PHY_N(0x232) +#define B43_NPHY_CCKPAYDECODETIMEOUTLEN B43_PHY_N(0x233) +#define B43_NPHY_NONPAYDECODETIMEOUTLEN B43_PHY_N(0x234) +#define B43_NPHY_TIMEOUTSTATUS B43_PHY_N(0x235) +#define B43_NPHY_RFCTRLCORE0GPIO0 B43_PHY_N(0x236) +#define B43_NPHY_RFCTRLCORE0GPIO1 B43_PHY_N(0x237) +#define B43_NPHY_RFCTRLCORE0GPIO2 B43_PHY_N(0x238) +#define B43_NPHY_RFCTRLCORE0GPIO3 B43_PHY_N(0x239) +#define B43_NPHY_RFCTRLCORE1GPIO0 B43_PHY_N(0x23A) +#define B43_NPHY_RFCTRLCORE1GPIO1 B43_PHY_N(0x23B) +#define B43_NPHY_RFCTRLCORE1GPIO2 B43_PHY_N(0x23C) +#define B43_NPHY_RFCTRLCORE1GPIO3 B43_PHY_N(0x23D) +#define B43_NPHY_BPHYTESTCONTROL B43_PHY_N(0x23E) +/* REV3+ */ +#define B43_NPHY_FORCEFRONT0 B43_PHY_N(0x23F) +#define B43_NPHY_FORCEFRONT1 B43_PHY_N(0x240) +#define B43_NPHY_NORMVARHYSTTH B43_PHY_N(0x241) +#define B43_NPHY_TXCCKERROR B43_PHY_N(0x242) +#define B43_NPHY_AFESEQINITDACGAIN B43_PHY_N(0x243) +#define B43_NPHY_TXANTSWLUT B43_PHY_N(0x244) +#define B43_NPHY_CORECONFIG B43_PHY_N(0x245) +#define B43_NPHY_ANTENNADIVDWELLTIME B43_PHY_N(0x246) +#define B43_NPHY_ANTENNACCKDIVDWELLTIME B43_PHY_N(0x247) +#define B43_NPHY_ANTENNADIVBACKOFFGAIN B43_PHY_N(0x248) +#define B43_NPHY_ANTENNADIVMINGAIN B43_PHY_N(0x249) +#define B43_NPHY_BRDSEL_NORMVARHYSTTH B43_PHY_N(0x24A) +#define B43_NPHY_RXANTSWITCHCTRL B43_PHY_N(0x24B) +#define B43_NPHY_ENERGYDROPTIMEOUTLEN2 B43_PHY_N(0x24C) +#define B43_NPHY_ML_LOG_TXEVM0 B43_PHY_N(0x250) +#define B43_NPHY_ML_LOG_TXEVM1 B43_PHY_N(0x251) +#define B43_NPHY_ML_LOG_TXEVM2 B43_PHY_N(0x252) +#define B43_NPHY_ML_LOG_TXEVM3 B43_PHY_N(0x253) +#define B43_NPHY_ML_LOG_TXEVM4 B43_PHY_N(0x254) +#define B43_NPHY_ML_LOG_TXEVM5 B43_PHY_N(0x255) +#define B43_NPHY_ML_LOG_TXEVM6 B43_PHY_N(0x256) +#define B43_NPHY_ML_LOG_TXEVM7 B43_PHY_N(0x257) +#define B43_NPHY_ML_SCALE_TWEAK B43_PHY_N(0x258) +#define B43_NPHY_MLUA B43_PHY_N(0x259) +#define B43_NPHY_ZFUA B43_PHY_N(0x25A) +#define B43_NPHY_CHANUPSYM01 B43_PHY_N(0x25B) +#define B43_NPHY_CHANUPSYM2 B43_PHY_N(0x25C) +#define B43_NPHY_RXSTRNFILT20NUM00 B43_PHY_N(0x25D) +#define B43_NPHY_RXSTRNFILT20NUM01 B43_PHY_N(0x25E) +#define B43_NPHY_RXSTRNFILT20NUM02 B43_PHY_N(0x25F) +#define B43_NPHY_RXSTRNFILT20DEN00 B43_PHY_N(0x260) +#define B43_NPHY_RXSTRNFILT20DEN01 B43_PHY_N(0x261) +#define B43_NPHY_RXSTRNFILT20NUM10 B43_PHY_N(0x262) +#define B43_NPHY_RXSTRNFILT20NUM11 B43_PHY_N(0x263) +#define B43_NPHY_RXSTRNFILT20NUM12 B43_PHY_N(0x264) +#define B43_NPHY_RXSTRNFILT20DEN10 B43_PHY_N(0x265) +#define B43_NPHY_RXSTRNFILT20DEN11 B43_PHY_N(0x266) +#define B43_NPHY_RXSTRNFILT40NUM00 B43_PHY_N(0x267) +#define B43_NPHY_RXSTRNFILT40NUM01 B43_PHY_N(0x268) +#define B43_NPHY_RXSTRNFILT40NUM02 B43_PHY_N(0x269) +#define B43_NPHY_RXSTRNFILT40DEN00 B43_PHY_N(0x26A) +#define B43_NPHY_RXSTRNFILT40DEN01 B43_PHY_N(0x26B) +#define B43_NPHY_RXSTRNFILT40NUM10 B43_PHY_N(0x26C) +#define B43_NPHY_RXSTRNFILT40NUM11 B43_PHY_N(0x26D) +#define B43_NPHY_RXSTRNFILT40NUM12 B43_PHY_N(0x26E) +#define B43_NPHY_RXSTRNFILT40DEN10 B43_PHY_N(0x26F) +#define B43_NPHY_RXSTRNFILT40DEN11 B43_PHY_N(0x270) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD1 B43_PHY_N(0x271) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD2 B43_PHY_N(0x272) +#define B43_NPHY_CRSHIGHLOWPOWTHRESHOLD B43_PHY_N(0x273) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD1L B43_PHY_N(0x274) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD2L B43_PHY_N(0x275) +#define B43_NPHY_CRSHIGHLOWPOWTHRESHOLDL B43_PHY_N(0x276) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD1U B43_PHY_N(0x277) +#define B43_NPHY_CRSHIGHPOWTHRESHOLD2U B43_PHY_N(0x278) +#define B43_NPHY_CRSHIGHLOWPOWTHRESHOLDU B43_PHY_N(0x279) +#define B43_NPHY_CRSACIDETECTTHRESH B43_PHY_N(0x27A) +#define B43_NPHY_CRSACIDETECTTHRESHL B43_PHY_N(0x27B) +#define B43_NPHY_CRSACIDETECTTHRESHU B43_PHY_N(0x27C) +#define B43_NPHY_CRSMINPOWER0 B43_PHY_N(0x27D) +#define B43_NPHY_CRSMINPOWER1 B43_PHY_N(0x27E) +#define B43_NPHY_CRSMINPOWER2 B43_PHY_N(0x27F) +#define B43_NPHY_CRSMINPOWERL0 B43_PHY_N(0x280) +#define B43_NPHY_CRSMINPOWERL1 B43_PHY_N(0x281) +#define B43_NPHY_CRSMINPOWERL2 B43_PHY_N(0x282) +#define B43_NPHY_CRSMINPOWERU0 B43_PHY_N(0x283) +#define B43_NPHY_CRSMINPOWERU1 B43_PHY_N(0x284) +#define B43_NPHY_CRSMINPOWERU2 B43_PHY_N(0x285) +#define B43_NPHY_STRPARAM B43_PHY_N(0x286) +#define B43_NPHY_STRPARAML B43_PHY_N(0x287) +#define B43_NPHY_STRPARAMU B43_PHY_N(0x288) +#define B43_NPHY_BPHYCRSMINPOWER0 B43_PHY_N(0x289) +#define B43_NPHY_BPHYCRSMINPOWER1 B43_PHY_N(0x28A) +#define B43_NPHY_BPHYCRSMINPOWER2 B43_PHY_N(0x28B) +#define B43_NPHY_BPHYFILTDEN0COEF B43_PHY_N(0x28C) +#define B43_NPHY_BPHYFILTDEN1COEF B43_PHY_N(0x28D) +#define B43_NPHY_BPHYFILTDEN2COEF B43_PHY_N(0x28E) +#define B43_NPHY_BPHYFILTNUM0COEF B43_PHY_N(0x28F) +#define B43_NPHY_BPHYFILTNUM1COEF B43_PHY_N(0x290) +#define B43_NPHY_BPHYFILTNUM2COEF B43_PHY_N(0x291) +#define B43_NPHY_BPHYFILTNUM01COEF2 B43_PHY_N(0x292) +#define B43_NPHY_BPHYFILTBYPASS B43_PHY_N(0x293) +#define B43_NPHY_SGILTRNOFFSET B43_PHY_N(0x294) +#define B43_NPHY_RADAR_T2_MIN B43_PHY_N(0x295) +#define B43_NPHY_TXPWRCTRLDAMPING B43_PHY_N(0x296) #define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */ #define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */ +#define B43_NPHY_EPS_OVERRIDEI_0 B43_PHY_N(0x299) +#define B43_NPHY_EPS_OVERRIDEQ_0 B43_PHY_N(0x29A) #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ +#define B43_NPHY_EPS_OVERRIDEI_1 B43_PHY_N(0x29D) +#define B43_NPHY_EPS_OVERRIDEQ_1 B43_PHY_N(0x29E) +#define B43_NPHY_PAPD_CAL_ADDRESS B43_PHY_N(0x29F) +#define B43_NPHY_PAPD_CAL_YREFEPSILON B43_PHY_N(0x2A0) +#define B43_NPHY_PAPD_CAL_SETTLE B43_PHY_N(0x2A1) +#define B43_NPHY_PAPD_CAL_CORRELATE B43_PHY_N(0x2A2) +#define B43_NPHY_PAPD_CAL_SHIFTS0 B43_PHY_N(0x2A3) +#define B43_NPHY_PAPD_CAL_SHIFTS1 B43_PHY_N(0x2A4) +#define B43_NPHY_SAMPLE_START_ADDR B43_PHY_N(0x2A5) +#define B43_NPHY_RADAR_ADC_TO_DBM B43_PHY_N(0x2A6) +#define B43_NPHY_REV3_C2_INITGAIN_A B43_PHY_N(0x2A7) +#define B43_NPHY_REV3_C2_INITGAIN_B B43_PHY_N(0x2A8) +#define B43_NPHY_REV3_C2_CLIP_HIGAIN_A B43_PHY_N(0x2A9) +#define B43_NPHY_REV3_C2_CLIP_HIGAIN_B B43_PHY_N(0x2AA) +#define B43_NPHY_REV3_C2_CLIP_MEDGAIN_A B43_PHY_N(0x2AB) +#define B43_NPHY_REV3_C2_CLIP_MEDGAIN_B B43_PHY_N(0x2AC) +#define B43_NPHY_REV3_C2_CLIP_LOGAIN_A B43_PHY_N(0x2AD) +#define B43_NPHY_REV3_C2_CLIP_LOGAIN_B B43_PHY_N(0x2AE) +#define B43_NPHY_REV3_C2_CLIP2_GAIN_A B43_PHY_N(0x2AF) +#define B43_NPHY_REV3_C2_CLIP2_GAIN_B B43_PHY_N(0x2B0) #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ #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 @@ #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ - r20, r21, r22, r23, r24, r25, r26, r27, r28) \ + r20) \ .radio_syn16 = r00, \ .radio_syn17 = r01, \ .radio_syn22 = r02, \ @@ -41,22 +41,14 @@ .radio_syn41 = r10, \ .radio_syn43 = r11, \ .radio_syn47 = r12, \ - .radio_syn4a = r13, \ - .radio_syn58 = r14, \ - .radio_syn5a = r15, \ - .radio_syn6a = r16, \ - .radio_syn6d = r17, \ - .radio_syn6e = r18, \ - .radio_syn92 = r19, \ - .radio_syn98 = r20, \ - .radio_rxtx4a = r21, \ - .radio_rxtx58 = r22, \ - .radio_rxtx5a = r23, \ - .radio_rxtx6a = r24, \ - .radio_rxtx6d = r25, \ - .radio_rxtx6e = r26, \ - .radio_rxtx92 = r27, \ - .radio_rxtx98 = r28 + .radio_rxtx4a = r13, \ + .radio_rxtx58 = r14, \ + .radio_rxtx5a = r15, \ + .radio_rxtx6a = r16, \ + .radio_rxtx6d = r17, \ + .radio_rxtx6e = r18, \ + .radio_rxtx92 = r19, \ + .radio_rxtx98 = r20 #define PHYREGS(r0, r1, r2, r3, r4, r5) \ .phy_regs.bw1 = r0, \ @@ -70,91 +62,78 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi { .freq = 2412, RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), }, { .freq = 2417, RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), }, { .freq = 2422, RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), }, { .freq = 2427, RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), }, { .freq = 2432, RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), }, { .freq = 2437, RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), }, { .freq = 2442, RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), }, { .freq = 2447, RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), }, { .freq = 2452, RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), }, { .freq = 2457, RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), }, { .freq = 2462, RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), }, { .freq = 2467, RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), }, { .freq = 2472, RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03, 0x00, 0x00, 0x00, 0xf0, 0x00), PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), }, 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 @@ #include "phy_ht.h" -#define R2059_SYN 0x000 -#define R2059_TXRX0 0x400 -#define R2059_RXRX1 0x800 +#define R2059_C1 0x000 +#define R2059_C2 0x400 +#define R2059_C3 0x800 #define R2059_ALL 0xC00 /* Values for various registers uploaded on channel switching */ @@ -28,14 +28,6 @@ struct b43_phy_ht_channeltab_e_radio2059 { u8 radio_syn41; u8 radio_syn43; u8 radio_syn47; - u8 radio_syn4a; - u8 radio_syn58; - u8 radio_syn5a; - u8 radio_syn6a; - u8 radio_syn6d; - u8 radio_syn6e; - u8 radio_syn92; - u8 radio_syn98; u8 radio_rxtx4a; u8 radio_rxtx58; 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[] = { /* volatile tables, PHY revision >= 3 */ /* indexed by antswctl2g */ -static const u16 b43_ntab_antswctl2g_r3[4][32] = { +static const u16 b43_ntab_antswctl_r3[4][32] = { { 0x0082, 0x0082, 0x0211, 0x0222, 0x0328, 0x0000, 0x0000, 0x0000, 0x0144, 0x0000, @@ -3095,9 +3095,55 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, } #define ntab_upload(dev, offset, data) do { \ - b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \ + b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ } while (0) -void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) + +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev) +{ + struct ssb_sprom *sprom = dev->dev->bus_sprom; + u8 antswlut; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) + antswlut = sprom->fem.ghz5.antswlut; + else + antswlut = sprom->fem.ghz2.antswlut; + + /* Static tables */ + ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3); + ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3); + ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); + ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); + ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); + ntab_upload(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); + ntab_upload(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3); + ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); + ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); + ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); + ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3); + ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3); + ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); + ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); + ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); + ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3); + ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3); + ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3); + ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3); + ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3); + ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3); + ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3); + ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3); + ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3); + ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3); + + /* Volatile tables */ + if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3)) + ntab_upload(dev, B43_NTAB_ANT_SW_CTL_R3, + b43_ntab_antswctl_r3[antswlut]); + else + B43_WARN_ON(1); +} + +static void b43_nphy_tables_init_rev0(struct b43_wldev *dev) { /* Static tables */ 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) ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); } -#define ntab_upload_r3(dev, offset, data) do { \ - b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ - } while (0) -void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */ +void b43_nphy_tables_init(struct b43_wldev *dev) { - struct ssb_sprom *sprom = dev->dev->bus_sprom; - - /* Static tables */ - ntab_upload_r3(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3); - ntab_upload_r3(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3); - ntab_upload_r3(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); - ntab_upload_r3(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); - ntab_upload_r3(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); - ntab_upload_r3(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); - ntab_upload_r3(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3); - ntab_upload_r3(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); - ntab_upload_r3(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); - ntab_upload_r3(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); - ntab_upload_r3(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3); - ntab_upload_r3(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3); - ntab_upload_r3(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); - ntab_upload_r3(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); - ntab_upload_r3(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); - ntab_upload_r3(dev, B43_NTAB_C0_ESTPLT_R3, - b43_ntab_estimatepowerlt0_r3); - ntab_upload_r3(dev, B43_NTAB_C1_ESTPLT_R3, - b43_ntab_estimatepowerlt1_r3); - ntab_upload_r3(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3); - ntab_upload_r3(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3); - ntab_upload_r3(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3); - ntab_upload_r3(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3); - ntab_upload_r3(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3); - ntab_upload_r3(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3); - ntab_upload_r3(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3); - ntab_upload_r3(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3); - - /* Volatile tables */ - if (sprom->fem.ghz2.antswlut < ARRAY_SIZE(b43_ntab_antswctl2g_r3)) - ntab_upload_r3(dev, B43_NTAB_ANT_SW_CTL_R3, - b43_ntab_antswctl2g_r3[sprom->fem.ghz2.antswlut]); + if (dev->phy.rev >= 3) + b43_nphy_tables_init_rev3(dev); else - B43_WARN_ON(1); + b43_nphy_tables_init_rev0(dev); } /* 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( #define B43_NTAB_NOISEVAR11_SIZE 256 #define B43_NTAB_C0_ESTPLT B43_NTAB8 (0x1A, 0x000) /* Estimate Power Lookup Table Core 0 */ #define B43_NTAB_C0_ESTPLT_SIZE 64 -#define B43_NTAB_C1_ESTPLT B43_NTAB8 (0x1B, 0x000) /* Estimate Power Lookup Table Core 1 */ -#define B43_NTAB_C1_ESTPLT_SIZE 64 #define B43_NTAB_C0_ADJPLT B43_NTAB8 (0x1A, 0x040) /* Adjust Power Lookup Table Core 0 */ #define B43_NTAB_C0_ADJPLT_SIZE 128 -#define B43_NTAB_C1_ADJPLT B43_NTAB8 (0x1B, 0x040) /* Adjust Power Lookup Table Core 1 */ -#define B43_NTAB_C1_ADJPLT_SIZE 128 #define B43_NTAB_C0_GAINCTL B43_NTAB32(0x1A, 0x0C0) /* Gain Control Lookup Table Core 0 */ #define B43_NTAB_C0_GAINCTL_SIZE 128 -#define B43_NTAB_C1_GAINCTL B43_NTAB32(0x1B, 0x0C0) /* Gain Control Lookup Table Core 1 */ -#define B43_NTAB_C1_GAINCTL_SIZE 128 #define B43_NTAB_C0_IQLT B43_NTAB32(0x1A, 0x140) /* IQ Lookup Table Core 0 */ #define B43_NTAB_C0_IQLT_SIZE 128 -#define B43_NTAB_C1_IQLT B43_NTAB32(0x1B, 0x140) /* IQ Lookup Table Core 1 */ -#define B43_NTAB_C1_IQLT_SIZE 128 #define B43_NTAB_C0_LOFEEDTH B43_NTAB16(0x1A, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 0 */ #define B43_NTAB_C0_LOFEEDTH_SIZE 128 +#define B43_NTAB_C1_ESTPLT B43_NTAB8 (0x1B, 0x000) /* Estimate Power Lookup Table Core 1 */ +#define B43_NTAB_C1_ESTPLT_SIZE 64 +#define B43_NTAB_C1_ADJPLT B43_NTAB8 (0x1B, 0x040) /* Adjust Power Lookup Table Core 1 */ +#define B43_NTAB_C1_ADJPLT_SIZE 128 +#define B43_NTAB_C1_GAINCTL B43_NTAB32(0x1B, 0x0C0) /* Gain Control Lookup Table Core 1 */ +#define B43_NTAB_C1_GAINCTL_SIZE 128 +#define B43_NTAB_C1_IQLT B43_NTAB32(0x1B, 0x140) /* IQ Lookup Table Core 1 */ +#define B43_NTAB_C1_IQLT_SIZE 128 #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ #define B43_NTAB_C1_LOFEEDTH_SIZE 128 @@ -154,15 +154,17 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( #define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 0) /* channel estimate */ #define B43_NTAB_FRAMELT_R3 B43_NTAB8(24, 0) /* frame lookup */ #define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8(26, 0) /* estimated power lookup 0 */ -#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8(27, 0) /* estimated power lookup 1 */ #define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8(26, 64) /* adjusted power lookup 0 */ -#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8(27, 64) /* adjusted power lookup 1 */ #define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */ -#define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */ #define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */ -#define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */ #define B43_NTAB_C0_LOFEEDTH_R3 B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0 */ +#define B43_NTAB_C0_PAPD_COMP_R3 B43_NTAB16(26, 576) +#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8(27, 0) /* estimated power lookup 1 */ +#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8(27, 64) /* adjusted power lookup 1 */ +#define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */ +#define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */ #define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */ +#define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576) #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 #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); void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, const void *_data); -void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); -void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); +void b43_nphy_tables_init(struct b43_wldev *dev); const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); 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, goto out_unlock_mutex; /* Switch the PHY mode (if necessary). */ - switch (conf->channel->band) { + switch (conf->chandef.chan->band) { case IEEE80211_BAND_2GHZ: if (phy->type == B43legacy_PHYTYPE_B) new_phymode = B43legacy_PHYMODE_B; @@ -2748,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, /* Switch to the requested channel. * The firmware takes care of races with the TX handler. */ - if (conf->channel->hw_value != phy->channel) - b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); + if (conf->chandef.chan->hw_value != phy->channel) + b43legacy_radio_selectchannel(dev, conf->chandef.chan->hw_value, + 0); dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); @@ -3558,7 +3559,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = dev->stats.link_noise; 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 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to use the driver for a SDIO wireless card. -config BRCMFMAC_SDIO_OOB - bool "Out of band interrupt support for SDIO interface chipset" - depends on BRCMFMAC_SDIO - ---help--- - This option enables out-of-band interrupt support for Broadcom - SDIO Wifi chipset using fullmac in order to gain better - performance and deep sleep wake up capability on certain - platforms. Say N if you are unsure. - config BRCMFMAC_USB bool "USB bus interface support for FullMAC driver" 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 += \ p2p.o \ dhd_cdc.o \ dhd_common.o \ - dhd_linux.o + dhd_linux.o \ + btcoex.o brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ dhd_sdio.o \ 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 @@ #include <linux/mmc/sdio.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/card.h> +#include <linux/platform_data/brcmfmac-sdio.h> #include <defs.h> #include <brcm_hw_ids.h> @@ -37,16 +38,15 @@ #define SDIOH_API_ACCESS_RETRY_LIMIT 2 -#ifdef CONFIG_BRCMFMAC_SDIO_OOB -static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) + +static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) { struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - brcmf_dbg(INTR, "oob intr triggered\n"); + brcmf_dbg(INTR, "OOB intr triggered\n"); - /* - * out-of-band interrupt is level-triggered which won't + /* out-of-band interrupt is level-triggered which won't * be cleared until dpc */ if (sdiodev->irq_en) { @@ -59,72 +59,12 @@ static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) return IRQ_HANDLED; } -int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) -{ - int ret = 0; - u8 data; - unsigned long flags; - - brcmf_dbg(SDIO, "Entering: irq %d\n", sdiodev->irq); - - ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, - sdiodev->irq_flags, "brcmf_oob_intr", - &sdiodev->func[1]->dev); - if (ret != 0) - return ret; - spin_lock_init(&sdiodev->irq_en_lock); - spin_lock_irqsave(&sdiodev->irq_en_lock, flags); - sdiodev->irq_en = true; - spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); - - ret = enable_irq_wake(sdiodev->irq); - if (ret != 0) - return ret; - sdiodev->irq_wake = true; - - sdio_claim_host(sdiodev->func[1]); - - /* must configure SDIO_CCCR_IENx to enable irq */ - data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); - data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); - - /* redirect, configure and enable io for interrupt signal */ - data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; - if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH) - data |= SDIO_SEPINT_ACT_HI; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); - - sdio_release_host(sdiodev->func[1]); - - return 0; -} - -int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) -{ - brcmf_dbg(SDIO, "Entering\n"); - - sdio_claim_host(sdiodev->func[1]); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); - sdio_release_host(sdiodev->func[1]); - - if (sdiodev->irq_wake) { - disable_irq_wake(sdiodev->irq); - sdiodev->irq_wake = false; - } - free_irq(sdiodev->irq, &sdiodev->func[1]->dev); - sdiodev->irq_en = false; - - return 0; -} -#else /* CONFIG_BRCMFMAC_SDIO_OOB */ -static void brcmf_sdio_irqhandler(struct sdio_func *func) +static void brcmf_sdio_ib_irqhandler(struct sdio_func *func) { struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - brcmf_dbg(INTR, "ib intr triggered\n"); + brcmf_dbg(INTR, "IB intr triggered\n"); brcmf_sdbrcm_isr(sdiodev->bus); } @@ -136,12 +76,56 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) { - brcmf_dbg(SDIO, "Entering\n"); + int ret = 0; + u8 data; + unsigned long flags; - sdio_claim_host(sdiodev->func[1]); - sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler); - sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); - sdio_release_host(sdiodev->func[1]); + if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { + brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", + sdiodev->pdata->oob_irq_nr); + ret = request_irq(sdiodev->pdata->oob_irq_nr, + brcmf_sdio_oob_irqhandler, + sdiodev->pdata->oob_irq_flags, + "brcmf_oob_intr", + &sdiodev->func[1]->dev); + if (ret != 0) { + brcmf_err("request_irq failed %d\n", ret); + return ret; + } + sdiodev->oob_irq_requested = true; + spin_lock_init(&sdiodev->irq_en_lock); + spin_lock_irqsave(&sdiodev->irq_en_lock, flags); + sdiodev->irq_en = true; + spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); + + ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr); + if (ret != 0) { + brcmf_err("enable_irq_wake failed %d\n", ret); + return ret; + } + sdiodev->irq_wake = true; + + sdio_claim_host(sdiodev->func[1]); + + /* must configure SDIO_CCCR_IENx to enable irq */ + data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); + data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; + brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); + + /* redirect, configure and enable io for interrupt signal */ + data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; + if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) + data |= SDIO_SEPINT_ACT_HI; + brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); + + sdio_release_host(sdiodev->func[1]); + } else { + brcmf_dbg(SDIO, "Entering\n"); + sdio_claim_host(sdiodev->func[1]); + sdio_claim_irq(sdiodev->func[1], brcmf_sdio_ib_irqhandler); + sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); + sdio_release_host(sdiodev->func[1]); + } return 0; } @@ -150,14 +134,31 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(SDIO, "Entering\n"); - sdio_claim_host(sdiodev->func[1]); - sdio_release_irq(sdiodev->func[2]); - sdio_release_irq(sdiodev->func[1]); - sdio_release_host(sdiodev->func[1]); + if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { + sdio_claim_host(sdiodev->func[1]); + brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); + sdio_release_host(sdiodev->func[1]); + + if (sdiodev->oob_irq_requested) { + sdiodev->oob_irq_requested = false; + if (sdiodev->irq_wake) { + disable_irq_wake(sdiodev->pdata->oob_irq_nr); + sdiodev->irq_wake = false; + } + free_irq(sdiodev->pdata->oob_irq_nr, + &sdiodev->func[1]->dev); + sdiodev->irq_en = false; + } + } else { + sdio_claim_host(sdiodev->func[1]); + sdio_release_irq(sdiodev->func[2]); + sdio_release_irq(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + } return 0; } -#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) @@ -457,36 +458,80 @@ done: return err; } -int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, - u8 *buf, uint nbytes) +int +brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, + u8 *data, uint size) { - struct sk_buff *mypkt; - bool write = rw ? SDIOH_WRITE : SDIOH_READ; - int err; + int bcmerror = 0; + struct sk_buff *pkt; + u32 sdaddr; + uint dsize; + + dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); + pkt = dev_alloc_skb(dsize); + if (!pkt) { + brcmf_err("dev_alloc_skb failed: len %d\n", dsize); + return -EIO; + } + pkt->priority = 0; - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + /* Determine initial transfer parameters */ + sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; + if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) + dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); + else + dsize = size; - mypkt = brcmu_pkt_buf_get_skb(nbytes); - if (!mypkt) { - brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", - nbytes); - return -EIO; + sdio_claim_host(sdiodev->func[1]); + + /* Do the transfer(s) */ + while (size) { + /* Set the backplane window to include the start address */ + bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address); + if (bcmerror) + break; + + brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", + write ? "write" : "read", dsize, + sdaddr, address & SBSDIO_SBWINDOW_MASK); + + sdaddr &= SBSDIO_SB_OFT_ADDR_MASK; + sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + skb_put(pkt, dsize); + if (write) + memcpy(pkt->data, data, dsize); + bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, + write, SDIO_FUNC_1, + sdaddr, pkt); + if (bcmerror) { + brcmf_err("membytes transfer failed\n"); + break; + } + if (!write) + memcpy(data, pkt->data, dsize); + skb_trim(pkt, dsize); + + /* Adjust for next transfer (if any) */ + size -= dsize; + if (size) { + data += dsize; + address += dsize; + sdaddr = 0; + dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); + } } - /* For a write, copy the buffer data into the packet. */ - if (write) - memcpy(mypkt->data, buf, nbytes); + dev_kfree_skb(pkt); - err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write, - SDIO_FUNC_1, addr, mypkt); + /* Return the window to backplane enumeration space for core access */ + if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad)) + brcmf_err("FAILED to set window back to 0x%x\n", + sdiodev->sbwad); - /* For a read, copy the packet data back to the buffer. */ - if (!err && !write) - memcpy(buf, mypkt->data, nbytes); + sdio_release_host(sdiodev->func[1]); - brcmu_pkt_buf_free_skb(mypkt); - return err; + return bcmerror; } 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 @@ #include <linux/sched.h> /* request_irq() */ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/platform_data/brcmfmac-sdio.h> #include <net/cfg80211.h> #include <defs.h> @@ -40,32 +41,30 @@ #define DMA_ALIGN_MASK 0x03 +#define SDIO_DEVICE_ID_BROADCOM_43143 43143 #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 +#define SDIO_DEVICE_ID_BROADCOM_4335 0x4335 #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 /* devices we support, null terminated */ static const struct sdio_device_id brcmf_sdmmc_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335)}, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); -#ifdef CONFIG_BRCMFMAC_SDIO_OOB -static struct list_head oobirq_lh; -struct brcmf_sdio_oobirq { - unsigned int irq; - unsigned long flags; - struct list_head list; -}; -#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ +static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; + static bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) @@ -424,33 +423,6 @@ void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) } -#ifdef CONFIG_BRCMFMAC_SDIO_OOB -static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) -{ - struct brcmf_sdio_oobirq *oobirq_entry; - - if (list_empty(&oobirq_lh)) { - brcmf_err("no valid oob irq resource\n"); - return -ENXIO; - } - - oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq, - list); - - sdiodev->irq = oobirq_entry->irq; - sdiodev->irq_flags = oobirq_entry->flags; - list_del(&oobirq_entry->list); - kfree(oobirq_entry); - - return 0; -} -#else -static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) -{ - return 0; -} -#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ - static int brcmf_ops_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { @@ -491,15 +463,13 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, dev_set_drvdata(&func->dev, bus_if); dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); sdiodev->dev = &sdiodev->func[1]->dev; + sdiodev->pdata = brcmfmac_sdio_pdata; atomic_set(&sdiodev->suspend, false); init_waitqueue_head(&sdiodev->request_byte_wait); init_waitqueue_head(&sdiodev->request_word_wait); init_waitqueue_head(&sdiodev->request_chain_wait); init_waitqueue_head(&sdiodev->request_buffer_wait); - err = brcmf_sdio_getintrcfg(sdiodev); - if (err) - goto fail; brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); err = brcmf_sdio_probe(sdiodev); @@ -594,7 +564,7 @@ static const struct dev_pm_ops brcmf_sdio_pm_ops = { static struct sdio_driver brcmf_sdmmc_driver = { .probe = brcmf_ops_sdio_probe, .remove = brcmf_ops_sdio_remove, - .name = "brcmfmac", + .name = BRCMFMAC_SDIO_PDATA_NAME, .id_table = brcmf_sdmmc_ids, #ifdef CONFIG_PM_SLEEP .drv = { @@ -603,72 +573,51 @@ static struct sdio_driver brcmf_sdmmc_driver = { #endif /* CONFIG_PM_SLEEP */ }; -#ifdef CONFIG_BRCMFMAC_SDIO_OOB static int brcmf_sdio_pd_probe(struct platform_device *pdev) { - struct resource *res; - struct brcmf_sdio_oobirq *oobirq_entry; - int i, ret; + int ret; - INIT_LIST_HEAD(&oobirq_lh); + brcmf_dbg(SDIO, "Enter\n"); - for (i = 0; ; i++) { - res = platform_get_resource(pdev, IORESOURCE_IRQ, i); - if (!res) - break; + brcmfmac_sdio_pdata = pdev->dev.platform_data; - oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq), - GFP_KERNEL); - if (!oobirq_entry) - return -ENOMEM; - oobirq_entry->irq = res->start; - oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK; - list_add_tail(&oobirq_entry->list, &oobirq_lh); - } - if (i == 0) - return -ENXIO; + if (brcmfmac_sdio_pdata->power_on) + brcmfmac_sdio_pdata->power_on(); ret = sdio_register_driver(&brcmf_sdmmc_driver); - if (ret) brcmf_err("sdio_register_driver failed: %d\n", ret); return ret; } -static struct platform_driver brcmf_sdio_pd = { - .probe = brcmf_sdio_pd_probe, - .driver = { - .name = "brcmf_sdio_pd" - } -}; - -void brcmf_sdio_exit(void) +static int brcmf_sdio_pd_remove(struct platform_device *pdev) { brcmf_dbg(SDIO, "Enter\n"); + if (brcmfmac_sdio_pdata->power_off) + brcmfmac_sdio_pdata->power_off(); + sdio_unregister_driver(&brcmf_sdmmc_driver); - platform_driver_unregister(&brcmf_sdio_pd); + return 0; } -void brcmf_sdio_init(void) -{ - int ret; - - brcmf_dbg(SDIO, "Enter\n"); - - ret = platform_driver_register(&brcmf_sdio_pd); +static struct platform_driver brcmf_sdio_pd = { + .remove = brcmf_sdio_pd_remove, + .driver = { + .name = BRCMFMAC_SDIO_PDATA_NAME + } +}; - if (ret) - brcmf_err("platform_driver_register failed: %d\n", ret); -} -#else void brcmf_sdio_exit(void) { brcmf_dbg(SDIO, "Enter\n"); - sdio_unregister_driver(&brcmf_sdmmc_driver); + if (brcmfmac_sdio_pdata) + platform_driver_unregister(&brcmf_sdio_pd); + else + sdio_unregister_driver(&brcmf_sdmmc_driver); } void brcmf_sdio_init(void) @@ -677,9 +626,12 @@ void brcmf_sdio_init(void) brcmf_dbg(SDIO, "Enter\n"); - ret = sdio_register_driver(&brcmf_sdmmc_driver); + ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); + if (ret == -ENODEV) { + brcmf_dbg(SDIO, "No platform data available, registering without.\n"); + ret = sdio_register_driver(&brcmf_sdmmc_driver); + } if (ret) - brcmf_err("sdio_register_driver failed: %d\n", ret); + brcmf_err("driver registration failed: %d\n", ret); } -#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 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <linux/slab.h> +#include <linux/netdevice.h> +#include <net/cfg80211.h> + +#include <brcmu_wifi.h> +#include <brcmu_utils.h> +#include <defs.h> +#include <dhd.h> +#include <dhd_dbg.h> +#include "fwil.h" +#include "fwil_types.h" +#include "btcoex.h" +#include "p2p.h" +#include "wl_cfg80211.h" + +/* T1 start SCO/eSCO priority suppression */ +#define BRCMF_BTCOEX_OPPR_WIN_TIME 2000 + +/* BT registers values during DHCP */ +#define BRCMF_BT_DHCP_REG50 0x8022 +#define BRCMF_BT_DHCP_REG51 0 +#define BRCMF_BT_DHCP_REG64 0 +#define BRCMF_BT_DHCP_REG65 0 +#define BRCMF_BT_DHCP_REG71 0 +#define BRCMF_BT_DHCP_REG66 0x2710 +#define BRCMF_BT_DHCP_REG41 0x33 +#define BRCMF_BT_DHCP_REG68 0x190 + +/* number of samples for SCO detection */ +#define BRCMF_BT_SCO_SAMPLES 12 + +/** +* enum brcmf_btcoex_state - BT coex DHCP state machine states +* @BRCMF_BT_DHCP_IDLE: DCHP is idle +* @BRCMF_BT_DHCP_START: DHCP started, wait before +* boosting wifi priority +* @BRCMF_BT_DHCP_OPPR_WIN: graceful DHCP opportunity ended, +* boost wifi priority +* @BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT: wifi priority boost end, +* restore defaults +*/ +enum brcmf_btcoex_state { + BRCMF_BT_DHCP_IDLE, + BRCMF_BT_DHCP_START, + BRCMF_BT_DHCP_OPPR_WIN, + BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT +}; + +/** + * struct brcmf_btcoex_info - BT coex related information + * @vif: interface for which request was done. + * @timer: timer for DHCP state machine + * @timeout: configured timeout. + * @timer_on: DHCP timer active + * @dhcp_done: DHCP finished before T1/T2 timer expiration + * @bt_state: DHCP state machine state + * @work: DHCP state machine work + * @cfg: driver private data for cfg80211 interface + * @reg66: saved value of btc_params 66 + * @reg41: saved value of btc_params 41 + * @reg68: saved value of btc_params 68 + * @saved_regs_part1: flag indicating regs 66,41,68 + * have been saved + * @reg51: saved value of btc_params 51 + * @reg64: saved value of btc_params 64 + * @reg65: saved value of btc_params 65 + * @reg71: saved value of btc_params 71 + * @saved_regs_part1: flag indicating regs 50,51,64,65,71 + * have been saved + */ +struct brcmf_btcoex_info { + struct brcmf_cfg80211_vif *vif; + struct timer_list timer; + u16 timeout; + bool timer_on; + bool dhcp_done; + enum brcmf_btcoex_state bt_state; + struct work_struct work; + struct brcmf_cfg80211_info *cfg; + u32 reg66; + u32 reg41; + u32 reg68; + bool saved_regs_part1; + u32 reg50; + u32 reg51; + u32 reg64; + u32 reg65; + u32 reg71; + bool saved_regs_part2; +}; + +/** + * brcmf_btcoex_params_write() - write btc_params firmware variable + * @ifp: interface + * @addr: btc_params register number + * @data: data to write + */ +static s32 brcmf_btcoex_params_write(struct brcmf_if *ifp, u32 addr, u32 data) +{ + struct { + __le32 addr; + __le32 data; + } reg_write; + + reg_write.addr = cpu_to_le32(addr); + reg_write.data = cpu_to_le32(data); + return brcmf_fil_iovar_data_set(ifp, "btc_params", + ®_write, sizeof(reg_write)); +} + +/** + * brcmf_btcoex_params_read() - read btc_params firmware variable + * @ifp: interface + * @addr: btc_params register number + * @data: read data + */ +static s32 brcmf_btcoex_params_read(struct brcmf_if *ifp, u32 addr, u32 *data) +{ + *data = addr; + + return brcmf_fil_iovar_int_get(ifp, "btc_params", data); +} + +/** + * brcmf_btcoex_boost_wifi() - control BT SCO/eSCO parameters + * @btci: BT coex info + * @trump_sco: + * true - set SCO/eSCO parameters for compatibility + * during DHCP window + * false - restore saved parameter values + * + * Enhanced BT COEX settings for eSCO compatibility during DHCP window + */ +static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci, + bool trump_sco) +{ + struct brcmf_if *ifp = btci->cfg->pub->iflist[0]; + + if (trump_sco && !btci->saved_regs_part2) { + /* this should reduce eSCO agressive + * retransmit w/o breaking it + */ + + /* save current */ + brcmf_dbg(TRACE, "new SCO/eSCO coex algo {save & override}\n"); + brcmf_btcoex_params_read(ifp, 50, &btci->reg50); + brcmf_btcoex_params_read(ifp, 51, &btci->reg51); + brcmf_btcoex_params_read(ifp, 64, &btci->reg64); + brcmf_btcoex_params_read(ifp, 65, &btci->reg65); + brcmf_btcoex_params_read(ifp, 71, &btci->reg71); + + btci->saved_regs_part2 = true; + brcmf_dbg(TRACE, + "saved bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", + btci->reg50, btci->reg51, btci->reg64, + btci->reg65, btci->reg71); + + /* pacify the eSco */ + brcmf_btcoex_params_write(ifp, 50, BRCMF_BT_DHCP_REG50); + brcmf_btcoex_params_write(ifp, 51, BRCMF_BT_DHCP_REG51); + brcmf_btcoex_params_write(ifp, 64, BRCMF_BT_DHCP_REG64); + brcmf_btcoex_params_write(ifp, 65, BRCMF_BT_DHCP_REG65); + brcmf_btcoex_params_write(ifp, 71, BRCMF_BT_DHCP_REG71); + + } else if (btci->saved_regs_part2) { + /* restore previously saved bt params */ + brcmf_dbg(TRACE, "Do new SCO/eSCO coex algo {restore}\n"); + brcmf_btcoex_params_write(ifp, 50, btci->reg50); + brcmf_btcoex_params_write(ifp, 51, btci->reg51); + brcmf_btcoex_params_write(ifp, 64, btci->reg64); + brcmf_btcoex_params_write(ifp, 65, btci->reg65); + brcmf_btcoex_params_write(ifp, 71, btci->reg71); + + brcmf_dbg(TRACE, + "restored bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", + btci->reg50, btci->reg51, btci->reg64, + btci->reg65, btci->reg71); + + btci->saved_regs_part2 = false; + } else { + brcmf_err("attempted to restore not saved BTCOEX params\n"); + } +} + +/** + * brcmf_btcoex_is_sco_active() - check if SCO/eSCO is active + * @ifp: interface + * + * return: true if SCO/eSCO session is active + */ +static bool brcmf_btcoex_is_sco_active(struct brcmf_if *ifp) +{ + int ioc_res = 0; + bool res = false; + int sco_id_cnt = 0; + u32 param27; + int i; + + for (i = 0; i < BRCMF_BT_SCO_SAMPLES; i++) { + ioc_res = brcmf_btcoex_params_read(ifp, 27, ¶m27); + + if (ioc_res < 0) { + brcmf_err("ioc read btc params error\n"); + break; + } + + brcmf_dbg(TRACE, "sample[%d], btc_params 27:%x\n", i, param27); + + if ((param27 & 0x6) == 2) { /* count both sco & esco */ + sco_id_cnt++; + } + + if (sco_id_cnt > 2) { + brcmf_dbg(TRACE, + "sco/esco detected, pkt id_cnt:%d samples:%d\n", + sco_id_cnt, i); + res = true; + break; + } + } + brcmf_dbg(TRACE, "exit: result=%d\n", res); + return res; +} + +/** + * btcmf_btcoex_save_part1() - save first step parameters. + */ +static void btcmf_btcoex_save_part1(struct brcmf_btcoex_info *btci) +{ + struct brcmf_if *ifp = btci->vif->ifp; + + if (!btci->saved_regs_part1) { + /* Retrieve and save original reg value */ + brcmf_btcoex_params_read(ifp, 66, &btci->reg66); + brcmf_btcoex_params_read(ifp, 41, &btci->reg41); + brcmf_btcoex_params_read(ifp, 68, &btci->reg68); + btci->saved_regs_part1 = true; + brcmf_dbg(TRACE, + "saved btc_params regs (66,41,68) 0x%x 0x%x 0x%x\n", + btci->reg66, btci->reg41, + btci->reg68); + } +} + +/** + * brcmf_btcoex_restore_part1() - restore first step parameters. + */ +static void brcmf_btcoex_restore_part1(struct brcmf_btcoex_info *btci) +{ + struct brcmf_if *ifp; + + if (btci->saved_regs_part1) { + btci->saved_regs_part1 = false; + ifp = btci->vif->ifp; + brcmf_btcoex_params_write(ifp, 66, btci->reg66); + brcmf_btcoex_params_write(ifp, 41, btci->reg41); + brcmf_btcoex_params_write(ifp, 68, btci->reg68); + brcmf_dbg(TRACE, + "restored btc_params regs {66,41,68} 0x%x 0x%x 0x%x\n", + btci->reg66, btci->reg41, + btci->reg68); + } +} + +/** + * brcmf_btcoex_timerfunc() - BT coex timer callback + */ +static void brcmf_btcoex_timerfunc(ulong data) +{ + struct brcmf_btcoex_info *bt_local = (struct brcmf_btcoex_info *)data; + brcmf_dbg(TRACE, "enter\n"); + + bt_local->timer_on = false; + schedule_work(&bt_local->work); +} + +/** + * brcmf_btcoex_handler() - BT coex state machine work handler + * @work: work + */ +static void brcmf_btcoex_handler(struct work_struct *work) +{ + struct brcmf_btcoex_info *btci; + btci = container_of(work, struct brcmf_btcoex_info, work); + if (btci->timer_on) { + btci->timer_on = false; + del_timer_sync(&btci->timer); + } + + switch (btci->bt_state) { + case BRCMF_BT_DHCP_START: + /* DHCP started provide OPPORTUNITY window + to get DHCP address + */ + brcmf_dbg(TRACE, "DHCP started\n"); + btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN; + if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) { + mod_timer(&btci->timer, btci->timer.expires); + } else { + btci->timeout -= BRCMF_BTCOEX_OPPR_WIN_TIME; + mod_timer(&btci->timer, + jiffies + + msecs_to_jiffies(BRCMF_BTCOEX_OPPR_WIN_TIME)); + } + btci->timer_on = true; + break; + + case BRCMF_BT_DHCP_OPPR_WIN: + if (btci->dhcp_done) { + brcmf_dbg(TRACE, "DHCP done before T1 expiration\n"); + goto idle; + } + + /* DHCP is not over yet, start lowering BT priority */ + brcmf_dbg(TRACE, "DHCP T1:%d expired\n", + BRCMF_BTCOEX_OPPR_WIN_TIME); + brcmf_btcoex_boost_wifi(btci, true); + + btci->bt_state = BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT; + mod_timer(&btci->timer, + jiffies + msecs_to_jiffies(btci->timeout)); + btci->timer_on = true; + break; + + case BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT: + if (btci->dhcp_done) + brcmf_dbg(TRACE, "DHCP done before T2 expiration\n"); + else + brcmf_dbg(TRACE, "DHCP T2:%d expired\n", + BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT); + + goto idle; + + default: + brcmf_err("invalid state=%d !!!\n", btci->bt_state); + goto idle; + } + + return; + +idle: + btci->bt_state = BRCMF_BT_DHCP_IDLE; + btci->timer_on = false; + brcmf_btcoex_boost_wifi(btci, false); + cfg80211_crit_proto_stopped(&btci->vif->wdev, GFP_KERNEL); + brcmf_btcoex_restore_part1(btci); + btci->vif = NULL; +} + +/** + * brcmf_btcoex_attach() - initialize BT coex data + * @cfg: driver private cfg80211 data + * + * return: 0 on success + */ +int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_btcoex_info *btci = NULL; + brcmf_dbg(TRACE, "enter\n"); + + btci = kmalloc(sizeof(struct brcmf_btcoex_info), GFP_KERNEL); + if (!btci) + return -ENOMEM; + + btci->bt_state = BRCMF_BT_DHCP_IDLE; + + /* Set up timer for BT */ + btci->timer_on = false; + btci->timeout = BRCMF_BTCOEX_OPPR_WIN_TIME; + init_timer(&btci->timer); + btci->timer.data = (ulong)btci; + btci->timer.function = brcmf_btcoex_timerfunc; + btci->cfg = cfg; + btci->saved_regs_part1 = false; + btci->saved_regs_part2 = false; + + INIT_WORK(&btci->work, brcmf_btcoex_handler); + + cfg->btcoex = btci; + return 0; +} + +/** + * brcmf_btcoex_detach - clean BT coex data + * @cfg: driver private cfg80211 data + */ +void brcmf_btcoex_detach(struct brcmf_cfg80211_info *cfg) +{ + brcmf_dbg(TRACE, "enter\n"); + + if (!cfg->btcoex) + return; + + if (cfg->btcoex->timer_on) { + cfg->btcoex->timer_on = false; + del_timer_sync(&cfg->btcoex->timer); + } + + cancel_work_sync(&cfg->btcoex->work); + + brcmf_btcoex_boost_wifi(cfg->btcoex, false); + brcmf_btcoex_restore_part1(cfg->btcoex); + + kfree(cfg->btcoex); + cfg->btcoex = NULL; +} + +static void brcmf_btcoex_dhcp_start(struct brcmf_btcoex_info *btci) +{ + struct brcmf_if *ifp = btci->vif->ifp; + + btcmf_btcoex_save_part1(btci); + /* set new regs values */ + brcmf_btcoex_params_write(ifp, 66, BRCMF_BT_DHCP_REG66); + brcmf_btcoex_params_write(ifp, 41, BRCMF_BT_DHCP_REG41); + brcmf_btcoex_params_write(ifp, 68, BRCMF_BT_DHCP_REG68); + btci->dhcp_done = false; + btci->bt_state = BRCMF_BT_DHCP_START; + schedule_work(&btci->work); + brcmf_dbg(TRACE, "enable BT DHCP Timer\n"); +} + +static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci) +{ + /* Stop any bt timer because DHCP session is done */ + btci->dhcp_done = true; + if (btci->timer_on) { + brcmf_dbg(TRACE, "disable BT DHCP Timer\n"); + btci->timer_on = false; + del_timer_sync(&btci->timer); + + /* schedule worker if transition to IDLE is needed */ + if (btci->bt_state != BRCMF_BT_DHCP_IDLE) { + brcmf_dbg(TRACE, "bt_state:%d\n", + btci->bt_state); + schedule_work(&btci->work); + } + } else { + /* Restore original values */ + brcmf_btcoex_restore_part1(btci); + } +} + +/** + * brcmf_btcoex_set_mode - set BT coex mode + * @cfg: driver private cfg80211 data + * @mode: Wifi-Bluetooth coexistence mode + * + * return: 0 on success + */ +int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, + enum brcmf_btcoex_mode mode, u16 duration) +{ + struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); + struct brcmf_btcoex_info *btci = cfg->btcoex; + struct brcmf_if *ifp = cfg->pub->iflist[0]; + + switch (mode) { + case BRCMF_BTCOEX_DISABLED: + brcmf_dbg(TRACE, "DHCP session starts\n"); + if (btci->bt_state != BRCMF_BT_DHCP_IDLE) + return -EBUSY; + /* Start BT timer only for SCO connection */ + if (brcmf_btcoex_is_sco_active(ifp)) { + btci->timeout = duration; + btci->vif = vif; + brcmf_btcoex_dhcp_start(btci); + } + break; + + case BRCMF_BTCOEX_ENABLED: + brcmf_dbg(TRACE, "DHCP session ends\n"); + if (btci->bt_state != BRCMF_BT_DHCP_IDLE && + vif == btci->vif) { + brcmf_btcoex_dhcp_end(btci); + } + break; + default: + brcmf_dbg(TRACE, "Unknown mode, ignored\n"); + } + return 0; +} 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 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef WL_BTCOEX_H_ +#define WL_BTCOEX_H_ + +enum brcmf_btcoex_mode { + BRCMF_BTCOEX_DISABLED, + BRCMF_BTCOEX_ENABLED +}; + +int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg); +void brcmf_btcoex_detach(struct brcmf_cfg80211_info *cfg); +int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, + enum brcmf_btcoex_mode mode, u16 duration); + +#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 @@ /******************************************************************************* * IO codes that are interpreted by dongle firmware ******************************************************************************/ +#define BRCMF_C_GET_VERSION 1 #define BRCMF_C_UP 2 #define BRCMF_C_DOWN 3 #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, /* this is P2P_DEVICE interface */ brcmf_dbg(INFO, "allocate non-netdev interface\n"); ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); + if (!ifp) + return ERR_PTR(-ENOMEM); } else { brcmf_dbg(INFO, "allocate netdev interface\n"); /* Allocate netdev, including space for private structure */ ndev = alloc_netdev(sizeof(*ifp), name, ether_setup); - if (!ndev) { - brcmf_err("OOM - alloc_netdev\n"); + if (!ndev) return ERR_PTR(-ENOMEM); - } ifp = netdev_priv(ndev); ifp->ndev = ndev; @@ -899,7 +899,10 @@ int brcmf_bus_start(struct device *dev) goto fail; drvr->fw_signals = true; - (void)brcmf_fws_init(drvr); + ret = brcmf_fws_init(drvr); + if (ret < 0) + goto fail; + brcmf_fws_add_interface(ifp); 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 @@ #include <linux/bcma/bcma.h> #include <linux/debugfs.h> #include <linux/vmalloc.h> +#include <linux/platform_data/brcmfmac-sdio.h> #include <asm/unaligned.h> #include <defs.h> #include <brcmu_wifi.h> @@ -324,6 +325,9 @@ MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME); */ #define BRCMF_IDLE_INTERVAL 1 +#define KSO_WAIT_US 50 +#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) + /* * Conversion of 802.1D priority to precedence level */ @@ -333,95 +337,6 @@ static uint prio2prec(u32 prio) (prio^2) : prio; } -/* core registers */ -struct sdpcmd_regs { - u32 corecontrol; /* 0x00, rev8 */ - u32 corestatus; /* rev8 */ - u32 PAD[1]; - u32 biststatus; /* rev8 */ - - /* PCMCIA access */ - u16 pcmciamesportaladdr; /* 0x010, rev8 */ - u16 PAD[1]; - u16 pcmciamesportalmask; /* rev8 */ - u16 PAD[1]; - u16 pcmciawrframebc; /* rev8 */ - u16 PAD[1]; - u16 pcmciaunderflowtimer; /* rev8 */ - u16 PAD[1]; - - /* interrupt */ - u32 intstatus; /* 0x020, rev8 */ - u32 hostintmask; /* rev8 */ - u32 intmask; /* rev8 */ - u32 sbintstatus; /* rev8 */ - u32 sbintmask; /* rev8 */ - u32 funcintmask; /* rev4 */ - u32 PAD[2]; - u32 tosbmailbox; /* 0x040, rev8 */ - u32 tohostmailbox; /* rev8 */ - u32 tosbmailboxdata; /* rev8 */ - u32 tohostmailboxdata; /* rev8 */ - - /* synchronized access to registers in SDIO clock domain */ - u32 sdioaccess; /* 0x050, rev8 */ - u32 PAD[3]; - - /* PCMCIA frame control */ - u8 pcmciaframectrl; /* 0x060, rev8 */ - u8 PAD[3]; - u8 pcmciawatermark; /* rev8 */ - u8 PAD[155]; - - /* interrupt batching control */ - u32 intrcvlazy; /* 0x100, rev8 */ - u32 PAD[3]; - - /* counters */ - u32 cmd52rd; /* 0x110, rev8 */ - u32 cmd52wr; /* rev8 */ - u32 cmd53rd; /* rev8 */ - u32 cmd53wr; /* rev8 */ - u32 abort; /* rev8 */ - u32 datacrcerror; /* rev8 */ - u32 rdoutofsync; /* rev8 */ - u32 wroutofsync; /* rev8 */ - u32 writebusy; /* rev8 */ - u32 readwait; /* rev8 */ - u32 readterm; /* rev8 */ - u32 writeterm; /* rev8 */ - u32 PAD[40]; - u32 clockctlstatus; /* rev8 */ - u32 PAD[7]; - - u32 PAD[128]; /* DMA engines */ - - /* SDIO/PCMCIA CIS region */ - char cis[512]; /* 0x400-0x5ff, rev6 */ - - /* PCMCIA function control registers */ - char pcmciafcr[256]; /* 0x600-6ff, rev6 */ - u16 PAD[55]; - - /* PCMCIA backplane access */ - u16 backplanecsr; /* 0x76E, rev6 */ - u16 backplaneaddr0; /* rev6 */ - u16 backplaneaddr1; /* rev6 */ - u16 backplaneaddr2; /* rev6 */ - u16 backplaneaddr3; /* rev6 */ - u16 backplanedata0; /* rev6 */ - u16 backplanedata1; /* rev6 */ - u16 backplanedata2; /* rev6 */ - u16 backplanedata3; /* rev6 */ - u16 PAD[31]; - - /* sprom "size" & "blank" info */ - u16 spromstatus; /* 0x7BE, rev2 */ - u32 PAD[464]; - - u16 PAD[0x80]; -}; - #ifdef DEBUG /* Device console log buffer state */ struct brcmf_console { @@ -588,12 +503,14 @@ struct brcmf_sdio { bool txoff; /* Transmit flow-controlled */ struct brcmf_sdio_count sdcnt; + bool sr_enabled; /* SaveRestore enabled */ + bool sleeping; /* SDIO bus sleeping */ }; /* clkstate */ #define CLK_NONE 0 #define CLK_SDONLY 1 -#define CLK_PENDING 2 /* Not used yet */ +#define CLK_PENDING 2 #define CLK_AVAIL 3 #ifdef DEBUG @@ -601,7 +518,7 @@ static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; #endif /* DEBUG */ -#define SDIO_DRIVE_STRENGTH 6 /* in milliamps */ +#define DEFAULT_SDIO_DRIVE_STRENGTH 6 /* in milliamps */ #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL) @@ -665,6 +582,62 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) return ret; } +static int +brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) +{ + u8 wr_val = 0, rd_val, cmp_val, bmask; + int err = 0; + int try_cnt = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); + /* 1st KSO write goes to AOS wake up core if device is asleep */ + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + wr_val, &err); + if (err) { + brcmf_err("SDIO_AOS KSO write error: %d\n", err); + return err; + } + + if (on) { + /* device WAKEUP through KSO: + * write bit 0 & read back until + * both bits 0 (kso bit) & 1 (dev on status) are set + */ + cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | + SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK; + bmask = cmp_val; + usleep_range(2000, 3000); + } else { + /* Put device to sleep, turn off KSO */ + cmp_val = 0; + /* only check for bit0, bit1(dev on status) may not + * get cleared right away + */ + bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK; + } + + do { + /* reliable KSO bit set/clr: + * the sdiod sleep write access is synced to PMU 32khz clk + * just one write attempt may fail, + * read it back until it matches written value + */ + rd_val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + &err); + if (((rd_val & bmask) == cmp_val) && !err) + break; + brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n", + try_cnt, MAX_KSO_ATTEMPTS, err); + udelay(KSO_WAIT_US); + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + wr_val, &err); + } while (try_cnt++ < MAX_KSO_ATTEMPTS); + + return err; +} + #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) #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) clkctl = 0; + if (bus->sr_enabled) { + bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY); + return 0; + } + if (on) { /* Request HT Avail */ clkreq = @@ -856,6 +834,63 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) return 0; } +static int +brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) +{ + int err = 0; + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(SDIO, "request %s currently %s\n", + (sleep ? "SLEEP" : "WAKE"), + (bus->sleeping ? "SLEEP" : "WAKE")); + + /* If SR is enabled control bus state with KSO */ + if (bus->sr_enabled) { + /* Done if we're already in the requested state */ + if (sleep == bus->sleeping) + goto end; + + /* Going to sleep */ + if (sleep) { + /* Don't sleep if something is pending */ + if (atomic_read(&bus->intstatus) || + atomic_read(&bus->ipend) > 0 || + (!atomic_read(&bus->fcstate) && + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && + data_ok(bus))) + return -EBUSY; + err = brcmf_sdbrcm_kso_control(bus, false); + /* disable watchdog */ + if (!err) + brcmf_sdbrcm_wd_timer(bus, 0); + } else { + bus->idlecount = 0; + err = brcmf_sdbrcm_kso_control(bus, true); + } + if (!err) { + /* Change state */ + bus->sleeping = sleep; + brcmf_dbg(SDIO, "new state %s\n", + (sleep ? "SLEEP" : "WAKE")); + } else { + brcmf_err("error while changing bus sleep state %d\n", + err); + return err; + } + } + +end: + /* control clocks */ + if (sleep) { + if (!bus->sr_enabled) + brcmf_sdbrcm_clkctl(bus, CLK_NONE, pendok); + } else { + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, pendok); + } + + return err; + +} + static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) { u32 intstatus = 0; @@ -1960,7 +1995,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) sdio_claim_host(bus->sdiodev->func[1]); /* Enable clock for device interrupts */ - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_bus_sleep(bus, false, false); /* Disable and clear interrupts at the chip level also */ w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); @@ -2012,23 +2047,19 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) bus->tx_seq = bus->rx_seq = 0; } -#ifdef CONFIG_BRCMFMAC_SDIO_OOB static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) { unsigned long flags; - spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); - if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { - enable_irq(bus->sdiodev->irq); - bus->sdiodev->irq_en = true; + if (bus->sdiodev->oob_irq_requested) { + spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); + if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { + enable_irq(bus->sdiodev->pdata->oob_irq_nr); + bus->sdiodev->irq_en = true; + } + spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); } - spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); -} -#else -static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) -{ } -#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) { @@ -2096,7 +2127,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) sdio_claim_host(bus->sdiodev->func[1]); /* If waiting for HTAVAIL, check status */ - if (bus->clkstate == CLK_PENDING) { + if (!bus->sr_enabled && bus->clkstate == CLK_PENDING) { u8 clkctl, devctl = 0; #ifdef DEBUG @@ -2142,7 +2173,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) } /* Make sure backplane clock is on */ - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); + brcmf_sdbrcm_bus_sleep(bus, false, true); /* Pending interrupt indicates new device status */ if (atomic_read(&bus->ipend) > 0) { @@ -2288,8 +2319,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) if ((bus->clkstate != CLK_PENDING) && bus->idletime == BRCMF_IDLE_IMMEDIATE) { bus->activity = false; + brcmf_dbg(SDIO, "idle state\n"); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); + brcmf_sdbrcm_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func[1]); } } @@ -2362,69 +2394,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) return ret; } -static int -brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data, - uint size) -{ - int bcmerror = 0; - u32 sdaddr; - uint dsize; - - /* Determine initial transfer parameters */ - sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; - if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) - dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); - else - dsize = size; - - sdio_claim_host(bus->sdiodev->func[1]); - - /* Set the backplane window to include the start address */ - bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address); - if (bcmerror) { - brcmf_err("window change failed\n"); - goto xfer_done; - } - - /* Do the transfer(s) */ - while (size) { - brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", - write ? "write" : "read", dsize, - sdaddr, address & SBSDIO_SBWINDOW_MASK); - bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write, - sdaddr, data, dsize); - if (bcmerror) { - brcmf_err("membytes transfer failed\n"); - break; - } - - /* Adjust for next transfer (if any) */ - size -= dsize; - if (size) { - data += dsize; - address += dsize; - bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, - address); - if (bcmerror) { - brcmf_err("window change failed\n"); - break; - } - sdaddr = 0; - dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); - } - } - -xfer_done: - /* Return the window to backplane enumeration space for core access */ - if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad)) - brcmf_err("FAILED to set window back to 0x%x\n", - bus->sdiodev->sbwad); - - sdio_release_host(bus->sdiodev->func[1]); - - return bcmerror; -} - #ifdef DEBUG #define CONSOLE_LINE_MAX 192 @@ -2441,8 +2410,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) /* Read console log struct */ addr = bus->console_addr + offsetof(struct rte_console, log_le); - rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le, - sizeof(c->log_le)); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le, + sizeof(c->log_le)); if (rv < 0) return rv; @@ -2467,7 +2436,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) /* Read the console buffer */ addr = le32_to_cpu(c->log_le.buf); - rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize); if (rv < 0) return rv; @@ -2592,7 +2561,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) /* Make sure backplane clock is on */ sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_bus_sleep(bus, false, false); sdio_release_host(bus->sdiodev->func[1]); /* 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) bus->activity = false; sdio_claim_host(bus->sdiodev->func[1]); + brcmf_dbg(INFO, "idle\n"); brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); sdio_release_host(bus->sdiodev->func[1]); } else { @@ -2679,16 +2649,15 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, struct sdpcm_shared_le sh_le; __le32 addr_le; - shaddr = bus->ramsize - 4; + shaddr = bus->ci->rambase + bus->ramsize - 4; /* * Read last word in socram to determine * address of sdpcm_shared structure */ sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - rv = brcmf_sdbrcm_membytes(bus, false, shaddr, - (u8 *)&addr_le, 4); + brcmf_sdbrcm_bus_sleep(bus, false, false); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); sdio_release_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2708,8 +2677,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, } /* Read hndrte_shared structure */ - rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, - sizeof(struct sdpcm_shared_le)); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, + sizeof(struct sdpcm_shared_le)); if (rv < 0) return rv; @@ -2745,22 +2714,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, /* obtain console information from device memory */ addr = sh->console_addr + offsetof(struct rte_console, log_le); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_ptr = le32_to_cpu(sh_val); addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_size = le32_to_cpu(sh_val); addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_index = le32_to_cpu(sh_val); @@ -2774,8 +2743,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, /* obtain the console data from device */ conbuf[console_size] = '\0'; - rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf, - console_size); + rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf, + console_size); if (rv < 0) goto done; @@ -2812,8 +2781,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, return 0; } - error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, - sizeof(struct brcmf_trap_info)); + error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr, + sizeof(struct brcmf_trap_info)); if (error < 0) return error; @@ -2856,14 +2825,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, sdio_claim_host(bus->sdiodev->func[1]); if (sh->assert_file_addr != 0) { - error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, - (u8 *)file, 80); + error = brcmf_sdio_ramrw(bus->sdiodev, false, + sh->assert_file_addr, (u8 *)file, 80); if (error < 0) return error; } if (sh->assert_exp_addr != 0) { - error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, - (u8 *)expr, 80); + error = brcmf_sdio_ramrw(bus->sdiodev, false, + sh->assert_exp_addr, (u8 *)expr, 80); if (error < 0) return error; } @@ -3021,84 +2990,8 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) return rxlen ? (int)rxlen : -ETIMEDOUT; } -static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) -{ - int bcmerror = 0; - u32 varaddr; - u32 varsizew; - __le32 varsizew_le; -#ifdef DEBUG - char *nvram_ularray; -#endif /* DEBUG */ - - /* Even if there are no vars are to be written, we still - need to set the ramsize. */ - varaddr = (bus->ramsize - 4) - bus->varsz; - - if (bus->vars) { - /* Write the vars list */ - bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, - bus->vars, bus->varsz); -#ifdef DEBUG - /* Verify NVRAM bytes */ - brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", - bus->varsz); - nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC); - if (!nvram_ularray) - return -ENOMEM; - - /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, bus->varsz); - - /* Read the vars list to temp buffer for comparison */ - bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr, - nvram_ularray, bus->varsz); - if (bcmerror) { - brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", - bcmerror, bus->varsz, varaddr); - } - /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(bus->vars, nvram_ularray, bus->varsz)) - brcmf_err("Downloaded NVRAM image is corrupted\n"); - else - brcmf_err("Download/Upload/Compare of NVRAM ok\n"); - - kfree(nvram_ularray); -#endif /* DEBUG */ - } - - /* adjust to the user specified RAM */ - brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize); - brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n", - varaddr, bus->varsz); - - /* - * Determine the length token: - * Varsize, converted to words, in lower 16-bits, checksum - * in upper 16-bits. - */ - if (bcmerror) { - varsizew = 0; - varsizew_le = cpu_to_le32(0); - } else { - varsizew = bus->varsz / 4; - varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); - varsizew_le = cpu_to_le32(varsizew); - } - - brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n", - bus->varsz, varsizew); - - /* Write the length token to the last word */ - bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4), - (u8 *)&varsizew_le, 4); - - return bcmerror; -} - -static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) +static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) { - int bcmerror = 0; struct chip_info *ci = bus->ci; /* 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) if (enter) { bus->alp_only = true; - ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); - - ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM); - - /* Clear the top bit of memory */ - if (bus->ramsize) { - u32 zeros = 0; - brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4, - (u8 *)&zeros, 4); - } + brcmf_sdio_chip_enter_download(bus->sdiodev, ci); } else { - if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { - brcmf_err("SOCRAM core is down after reset?\n"); - bcmerror = -EBADE; - goto fail; - } - - bcmerror = brcmf_sdbrcm_write_vars(bus); - if (bcmerror) { - brcmf_err("no vars written to RAM\n"); - bcmerror = 0; - } - - w_sdreg32(bus, 0xFFFFFFFF, - offsetof(struct sdpcmd_regs, intstatus)); - - ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); + if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars, + bus->varsz)) + return false; /* Allow HT Clock now that the ARM is running. */ bus->alp_only = false; bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; } -fail: - return bcmerror; + + return true; } 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) static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) { - int offset = 0; + int offset; uint len; u8 *memblock = NULL, *memptr; int ret; + u8 idx; brcmf_dbg(INFO, "Enter\n"); @@ -3180,10 +3052,15 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) memptr += (BRCMF_SDALIGN - ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); + offset = bus->ci->rambase; + /* Download image */ - while ((len = - brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { - ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len); + len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4); + if (BRCMF_MAX_CORENUM != idx) + memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec)); + while (len) { + ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len); if (ret) { brcmf_err("error %d on writing %d membytes at 0x%08x\n", ret, MEMBLOCK, offset); @@ -3191,6 +3068,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) } offset += MEMBLOCK; + len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); } err: @@ -3298,7 +3176,7 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) int bcmerror = -1; /* Keep arm in reset */ - if (brcmf_sdbrcm_download_state(bus, true)) { + if (!brcmf_sdbrcm_download_state(bus, true)) { brcmf_err("error placing ARM core in reset\n"); goto err; } @@ -3314,7 +3192,7 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) } /* Take arm out of reset */ - if (brcmf_sdbrcm_download_state(bus, false)) { + if (!brcmf_sdbrcm_download_state(bus, false)) { brcmf_err("error getting out of ARM core reset\n"); goto err; } @@ -3325,6 +3203,103 @@ err: return bcmerror; } +static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) +{ + u32 addr, reg; + + brcmf_dbg(TRACE, "Enter\n"); + + /* old chips with PMU version less than 17 don't support save restore */ + if (bus->ci->pmurev < 17) + return false; + + /* read PMU chipcontrol register 3*/ + addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); + brcmf_sdio_regwl(bus->sdiodev, addr, 3, NULL); + addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); + reg = brcmf_sdio_regrl(bus->sdiodev, addr, NULL); + + return (bool)reg; +} + +static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) +{ + int err = 0; + u8 val; + + brcmf_dbg(TRACE, "Enter\n"); + + val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, + &err); + if (err) { + brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); + return; + } + + val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, + val, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); + return; + } + + /* Add CMD14 Support */ + brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, + (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | + SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), + &err); + if (err) { + brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); + return; + } + + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HT, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); + return; + } + + /* set flag */ + bus->sr_enabled = true; + brcmf_dbg(INFO, "SR enabled\n"); +} + +/* enable KSO bit */ +static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) +{ + u8 val; + int err = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + /* KSO bit added in SDIO core rev 12 */ + if (bus->ci->c_inf[1].rev < 12) + return 0; + + val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + &err); + if (err) { + brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); + return err; + } + + if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { + val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << + SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + val, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); + return err; + } + } + + return 0; +} + + static bool brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) { @@ -3423,8 +3398,13 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) ret = -ENODEV; } - /* Restore previous clock setting */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); + if (brcmf_sdbrcm_sr_capable(bus)) { + brcmf_sdbrcm_sr_init(bus); + } else { + /* Restore previous clock setting */ + brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + saveclk, &err); + } if (ret == 0) { ret = brcmf_sdio_intr_register(bus->sdiodev); @@ -3485,7 +3465,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) brcmf_dbg(TIMER, "Enter\n"); /* Poll period: check device if appropriate. */ - if (bus->poll && (++bus->polltick >= bus->pollrate)) { + if (!bus->sr_enabled && + bus->poll && (++bus->polltick >= bus->pollrate)) { u32 intstatus = 0; /* Reset poll tick */ @@ -3536,7 +3517,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->console.count -= bus->console_interval; sdio_claim_host(bus->sdiodev->func[1]); /* Make sure backplane clock is on */ - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_bus_sleep(bus, false, false); if (brcmf_sdbrcm_readconsole(bus) < 0) /* stop on error */ bus->console_interval = 0; @@ -3553,8 +3534,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->activity = false; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); } else { + brcmf_dbg(SDIO, "idle\n"); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); + brcmf_sdbrcm_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func[1]); } } @@ -3565,6 +3547,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) static bool brcmf_sdbrcm_chipmatch(u16 chipid) { + if (chipid == BCM43143_CHIP_ID) + return true; if (chipid == BCM43241_CHIP_ID) return true; if (chipid == BCM4329_CHIP_ID) @@ -3573,6 +3557,8 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid) return true; if (chipid == BCM4334_CHIP_ID) return true; + if (chipid == BCM4335_CHIP_ID) + return true; return false; } @@ -3650,7 +3636,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) int err = 0; int reg_addr; u32 reg_val; - u8 idx; + u32 drivestrength; bus->alp_only = true; @@ -3686,8 +3672,16 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) goto fail; } - brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, - SDIO_DRIVE_STRENGTH); + if (brcmf_sdbrcm_kso_init(bus)) { + brcmf_err("error enabling KSO\n"); + goto fail; + } + + if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) + drivestrength = bus->sdiodev->pdata->drive_strength; + else + drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; + brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); /* Get info on the SOCRAM cores... */ bus->ramsize = bus->ci->ramsize; @@ -3696,12 +3690,37 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) goto fail; } - /* Set core control so an SDIO reset does a backplane reset */ - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); - reg_addr = bus->ci->c_inf[idx].base + - offsetof(struct sdpcmd_regs, corecontrol); - reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); - brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); + /* Set card control so an SDIO card reset does a WLAN backplane reset */ + reg_val = brcmf_sdio_regrb(bus->sdiodev, + SDIO_CCCR_BRCM_CARDCTRL, &err); + if (err) + goto fail; + + reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; + + brcmf_sdio_regwb(bus->sdiodev, + SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + if (err) + goto fail; + + /* set PMUControl so a backplane reset does PMU state reload */ + reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base, + pmucontrol); + reg_val = brcmf_sdio_regrl(bus->sdiodev, + reg_addr, + &err); + if (err) + goto fail; + + reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); + + brcmf_sdio_regwl(bus->sdiodev, + reg_addr, + reg_val, + &err); + if (err) + goto fail; + sdio_release_host(bus->sdiodev->func[1]); @@ -3755,6 +3774,10 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) bus->use_rxchain = false; bus->sd_rxchain = false; + /* SR state */ + bus->sleeping = false; + bus->sr_enabled = false; + return true; } 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 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/err.h> +#include <linux/jiffies.h> #include <uapi/linux/nl80211.h> #include <net/cfg80211.h> @@ -31,8 +32,11 @@ #include "dhd_dbg.h" #include "dhd_bus.h" #include "fwil.h" +#include "fwil_types.h" #include "fweh.h" #include "fwsignal.h" +#include "p2p.h" +#include "wl_cfg80211.h" /** * DOC: Firmware Signalling @@ -144,6 +148,9 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 +#define BRCMF_FWS_RET_OK_NOSCHEDULE 0 +#define BRCMF_FWS_RET_OK_SCHEDULE 1 + /** * enum brcmf_fws_skb_state - indicates processing state of skb. * @@ -265,6 +272,9 @@ struct brcmf_skbuff_cb { brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ BRCMF_FWS_TXSTAT_ ## field ## _SHIFT) +/* How long to defer borrowing in jiffies */ +#define BRCMF_FWS_BORROW_DEFER_PERIOD (HZ / 10) + /** * enum brcmf_fws_fifo - fifo indices used by dongle firmware. * @@ -419,9 +429,11 @@ struct brcmf_fws_info { struct work_struct fws_dequeue_work; u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT]; int fifo_credit[BRCMF_FWS_FIFO_COUNT]; + int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1]; int deq_node_pos[BRCMF_FWS_FIFO_COUNT]; u32 fifo_credit_map; u32 fifo_delay_map; + unsigned long borrow_defer_timestamp; }; /* @@ -678,28 +690,28 @@ brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea) } static struct brcmf_fws_mac_descriptor* -brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, int ifidx, u8 *da) +brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, struct brcmf_if *ifp, + u8 *da) { struct brcmf_fws_mac_descriptor *entry = &fws->desc.other; - struct brcmf_if *ifp; bool multicast; + enum nl80211_iftype iftype; - brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx); + brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx); multicast = is_multicast_ether_addr(da); - ifp = fws->drvr->iflist[ifidx ? ifidx + 1 : 0]; - if (WARN_ON(!ifp)) - goto done; + iftype = brcmf_cfg80211_get_iftype(ifp); /* Multicast destination and P2P clients get the interface entry. * STA gets the interface entry if there is no exact match. For * example, TDLS destinations have their own entry. */ entry = NULL; - if (multicast && ifp->fws_desc) + if ((multicast || iftype == NL80211_IFTYPE_STATION || + iftype == NL80211_IFTYPE_P2P_CLIENT) && ifp->fws_desc) entry = ifp->fws_desc; - if (entry != NULL && multicast) + if (entry != NULL && iftype != NL80211_IFTYPE_STATION) goto done; entry = brcmf_fws_mac_descriptor_lookup(fws, da); @@ -711,26 +723,29 @@ done: return entry; } -static bool brcmf_fws_mac_desc_ready(struct brcmf_fws_mac_descriptor *entry, - int fifo) +static bool brcmf_fws_mac_desc_closed(struct brcmf_fws_info *fws, + struct brcmf_fws_mac_descriptor *entry, + int fifo) { - bool ready; + struct brcmf_fws_mac_descriptor *if_entry; + bool closed; - /* - * destination entry is ready when firmware says it is OPEN - * and there are no packets enqueued for it. + /* for unique destination entries the related interface + * may be closed. */ - ready = entry->state == BRCMF_FWS_STATE_OPEN && - !entry->suppressed && - brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0; - - /* - * Or when the destination entry is CLOSED, but firmware has - * specifically requested packets for this entry. + if (entry->mac_handle) { + if_entry = &fws->desc.iface[entry->interface_id]; + if (if_entry->state == BRCMF_FWS_STATE_CLOSE) + return true; + } + /* an entry is closed when the state is closed and + * the firmware did not request anything. */ - ready = ready || (entry->state == BRCMF_FWS_STATE_CLOSE && - (entry->requested_credit + entry->requested_packet)); - return ready; + closed = entry->state == BRCMF_FWS_STATE_CLOSE && + !entry->requested_credit && !entry->requested_packet; + + /* Or firmware does not allow traffic for given fifo */ + return closed || !(entry->ac_bitmap & BIT(fifo)); } 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, { struct brcmf_if *ifp = fws->drvr->iflist[if_id]; - brcmf_dbg(TRACE, - "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx); if (WARN_ON(!ifp)) return; + brcmf_dbg(TRACE, + "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx); + if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) && pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER) brcmf_txflowblock_if(ifp, @@ -861,9 +877,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) entry = &fws->desc.nodes[mac_handle & 0x1F]; if (type == BRCMF_FWS_TYPE_MACDESC_DEL) { brcmf_dbg(TRACE, "deleting mac %pM idx %d\n", addr, ifidx); - if (entry->occupied) + if (entry->occupied) { + brcmf_fws_mac_desc_cleanup(fws, entry, -1); brcmf_fws_clear_mac_descriptor(entry); - else + } else fws->stats.mac_update_failed++; return 0; } @@ -914,12 +931,13 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws, entry->requested_credit = 0; if (type == BRCMF_FWS_TYPE_MAC_OPEN) { entry->state = BRCMF_FWS_STATE_OPEN; + return BRCMF_FWS_RET_OK_SCHEDULE; } else { entry->state = BRCMF_FWS_STATE_CLOSE; for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++) brcmf_fws_tim_update(fws, entry, i); } - return 0; + return BRCMF_FWS_RET_OK_NOSCHEDULE; } 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, switch (type) { case BRCMF_FWS_TYPE_INTERFACE_OPEN: entry->state = BRCMF_FWS_STATE_OPEN; - return 0; + return BRCMF_FWS_RET_OK_SCHEDULE; case BRCMF_FWS_TYPE_INTERFACE_CLOSE: entry->state = BRCMF_FWS_STATE_CLOSE; - return 0; + return BRCMF_FWS_RET_OK_NOSCHEDULE; default: ret = -EINVAL; break; @@ -979,15 +997,40 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type, entry->requested_packet = data[0]; entry->ac_bitmap = data[2]; - return 0; + return BRCMF_FWS_RET_OK_SCHEDULE; } static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, u8 fifo, u8 credits) { + int lender_ac; + int *borrowed; + int *fifo_credit; + if (!credits) return; + if ((fifo == BRCMF_FWS_FIFO_AC_BE) && + (fws->credits_borrowed[0])) { + for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0; + lender_ac--) { + borrowed = &fws->credits_borrowed[lender_ac]; + if (*borrowed) { + fws->fifo_credit_map |= (1 << lender_ac); + fifo_credit = &fws->fifo_credit[lender_ac]; + if (*borrowed >= credits) { + *borrowed -= credits; + *fifo_credit += credits; + return; + } else { + credits -= *borrowed; + *fifo_credit += *borrowed; + *borrowed = 0; + } + } + } + } + fws->fifo_credit_map |= 1 << fifo; fws->fifo_credit[fifo] += credits; } @@ -1074,7 +1117,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo) int num_nodes; int node_pos; int prec_out; - int pmsk = 3; + int pmsk; int i; 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) for (i = 0; i < num_nodes; i++) { entry = &table[(node_pos + i) % num_nodes]; - if (!entry->occupied) + if (!entry->occupied || + brcmf_fws_mac_desc_closed(fws, entry, fifo)) continue; if (entry->suppressed) pmsk = 2; + else + pmsk = 3; p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out); if (p == NULL) { if (entry->suppressed) { @@ -1250,7 +1296,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { brcmf_dbg(INFO, "ignored\n"); - return 0; + return BRCMF_FWS_RET_OK_NOSCHEDULE; } brcmf_dbg(TRACE, "enter: data %pM\n", data); @@ -1259,8 +1305,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map, fws->fifo_delay_map); - brcmf_fws_schedule_deq(fws); - return 0; + return BRCMF_FWS_RET_OK_SCHEDULE; } 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, u8 type; u8 len; u8 *data; + s32 status; + s32 err; brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n", ifidx, skb->len, signal_len); @@ -1363,6 +1410,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, data_len = signal_len; signal_data = skb->data; + status = BRCMF_FWS_RET_OK_NOSCHEDULE; while (data_len > 0) { /* extract tlv info */ type = signal_data[0]; @@ -1388,6 +1436,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, if (len != brcmf_fws_get_tlv_len(fws, type)) break; + err = BRCMF_FWS_RET_OK_NOSCHEDULE; switch (type) { case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: case BRCMF_FWS_TYPE_COMP_TXSTATUS: @@ -1398,21 +1447,22 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, break; case BRCMF_FWS_TYPE_MAC_OPEN: case BRCMF_FWS_TYPE_MAC_CLOSE: - brcmf_fws_macdesc_state_indicate(fws, type, data); + err = brcmf_fws_macdesc_state_indicate(fws, type, data); break; case BRCMF_FWS_TYPE_INTERFACE_OPEN: case BRCMF_FWS_TYPE_INTERFACE_CLOSE: - brcmf_fws_interface_state_indicate(fws, type, data); + err = brcmf_fws_interface_state_indicate(fws, type, + data); break; case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: - brcmf_fws_request_indicate(fws, type, data); + err = brcmf_fws_request_indicate(fws, type, data); break; case BRCMF_FWS_TYPE_TXSTATUS: brcmf_fws_txstatus_indicate(fws, data); break; case BRCMF_FWS_TYPE_FIFO_CREDITBACK: - brcmf_fws_fifocreditback_indicate(fws, data); + err = brcmf_fws_fifocreditback_indicate(fws, data); break; case BRCMF_FWS_TYPE_RSSI: brcmf_fws_rssi_indicate(fws, *data); @@ -1426,7 +1476,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, fws->stats.tlv_invalid_type++; break; } - + if (err == BRCMF_FWS_RET_OK_SCHEDULE) + status = BRCMF_FWS_RET_OK_SCHEDULE; signal_data += len + 2; data_len -= len + 2; } @@ -1434,6 +1485,9 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, if (data_len != 0) fws->stats.tlv_parse_failed++; + if (status == BRCMF_FWS_RET_OK_SCHEDULE) + brcmf_fws_schedule_deq(fws); + /* signalling processing result does * not affect the actual ethernet packet. */ @@ -1553,7 +1607,7 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, return rc; } -static int +static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) { /* @@ -1595,7 +1649,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) /* free the hanger slot */ brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout, true); - brcmf_txfinalize(fws->drvr, skb, false); rc = -EINVAL; goto fail; } @@ -1629,11 +1682,31 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb) fail: - if (rc) + if (rc) { + brcmf_txfinalize(fws->drvr, skb, false); fws->stats.rollback_failed++; - else + } else fws->stats.rollback_success++; - return rc; +} + +static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws) +{ + int lender_ac; + + if (time_after(fws->borrow_defer_timestamp, jiffies)) + return -ENAVAIL; + + for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) { + if (fws->fifo_credit[lender_ac]) { + fws->credits_borrowed[lender_ac]++; + fws->fifo_credit[lender_ac]--; + if (fws->fifo_credit[lender_ac] == 0) + fws->fifo_credit_map &= ~(1 << lender_ac); + brcmf_dbg(TRACE, "borrow credit from: %d\n", lender_ac); + return 0; + } + } + return -ENAVAIL; } 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, return 0; } + if (fifo != BRCMF_FWS_FIFO_AC_BE) + fws->borrow_defer_timestamp = jiffies + + BRCMF_FWS_BORROW_DEFER_PERIOD; + if (!(*credit)) { - brcmf_dbg(TRACE, "exit: credits depleted\n"); + /* Try to borrow a credit from other queue */ + if (fifo == BRCMF_FWS_FIFO_AC_BE && + brcmf_fws_borrow_credit(fws) == 0) + return 0; + + brcmf_dbg(TRACE, "exit: ac=%d, credits depleted\n", fifo); return -ENAVAIL; } (*credit)--; @@ -1712,17 +1794,17 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, return rc; rollback: - rc = brcmf_fws_rollback_toq(fws, skb); + brcmf_fws_rollback_toq(fws, skb); return rc; } int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) { struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_fws_info *fws = drvr->fws; struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); struct ethhdr *eh = (struct ethhdr *)(skb->data); ulong flags; - u8 ifidx = ifp->ifidx; int fifo = BRCMF_FWS_FIFO_BCMC; bool multicast = is_multicast_ether_addr(eh->h_dest); @@ -1734,9 +1816,9 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) if (ntohs(eh->h_proto) == ETH_P_PAE) atomic_inc(&ifp->pend_8021x_cnt); - if (!brcmf_fws_fc_active(drvr->fws)) { + if (!brcmf_fws_fc_active(fws)) { /* If the protocol uses a data header, apply it */ - brcmf_proto_hdrpush(drvr, ifidx, 0, skb); + brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb); /* Use bus module to send data frame */ 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) /* set control buffer information */ skcb->if_flags = 0; - skcb->mac = brcmf_fws_find_mac_desc(drvr->fws, ifidx, eh->h_dest); + skcb->mac = brcmf_fws_find_mac_desc(fws, ifp, eh->h_dest); skcb->state = BRCMF_FWS_SKBSTATE_NEW; - brcmf_skb_if_flags_set_field(skb, INDEX, ifidx); + brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); if (!multicast) fifo = brcmf_fws_prio2fifo[skb->priority]; 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) multicast, fifo); brcmf_fws_lock(drvr, flags); - if (!brcmf_fws_mac_desc_ready(skcb->mac, fifo) || + if (skcb->mac->suppressed || + brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) || + brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) || (!multicast && - brcmf_fws_consume_credit(drvr->fws, fifo, skb) < 0)) { + brcmf_fws_consume_credit(fws, fifo, skb) < 0)) { /* enqueue the packet in delayQ */ drvr->fws->fifo_delay_map |= 1 << fifo; - brcmf_fws_enq(drvr->fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); + brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); } else { - brcmf_fws_commit_skb(drvr->fws, fifo, skb); + if (brcmf_fws_commit_skb(fws, fifo, skb)) + if (!multicast) + brcmf_skb_pick_up_credit(fws, fifo, skb); } brcmf_fws_unlock(drvr, flags); return 0; @@ -1799,14 +1885,17 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp) void brcmf_fws_del_interface(struct brcmf_if *ifp) { struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc; + ulong flags; brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx); if (!entry) return; + brcmf_fws_lock(ifp->drvr, flags); ifp->fws_desc = NULL; brcmf_fws_clear_mac_descriptor(entry); brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx); + brcmf_fws_unlock(ifp->drvr, flags); } static void brcmf_fws_dequeue_worker(struct work_struct *worker) @@ -1826,14 +1915,29 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) fws->fifo_credit[fifo]); for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) { skb = brcmf_fws_deq(fws, fifo); - if (!skb) + if (!skb || brcmf_fws_commit_skb(fws, fifo, skb)) break; - if (!brcmf_fws_commit_skb(fws, fifo, skb) && - brcmf_skbcb(skb)->if_flags & + if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) credit++; } - fws->fifo_credit[fifo] -= credit; + if ((fifo == BRCMF_FWS_FIFO_AC_BE) && + (credit == fws->fifo_credit[fifo])) { + fws->fifo_credit[fifo] -= credit; + while (brcmf_fws_borrow_credit(fws) == 0) { + skb = brcmf_fws_deq(fws, fifo); + if (!skb) { + brcmf_fws_return_credits(fws, fifo, 1); + break; + } + if (brcmf_fws_commit_skb(fws, fifo, skb)) { + brcmf_fws_return_credits(fws, fifo, 1); + break; + } + } + } else { + fws->fifo_credit[fifo] -= credit; + } } brcmf_fws_unlock(fws->drvr, flags); } @@ -1872,16 +1976,20 @@ int brcmf_fws_init(struct brcmf_pub *drvr) BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; - rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); + rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, + brcmf_fws_notify_credit_map); if (rc < 0) { - brcmf_err("failed to set bdcv2 tlv signaling\n"); + brcmf_err("register credit map handler failed\n"); goto fail; } - if (brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, - brcmf_fws_notify_credit_map)) { - brcmf_err("register credit map handler failed\n"); - goto fail; + /* setting the iovar may fail if feature is unsupported + * so leave the rc as is so driver initialization can + * continue. + */ + if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) { + brcmf_err("failed to set bdcv2 tlv signaling\n"); + goto fail_event; } brcmf_fws_hanger_init(&drvr->fws->hanger); @@ -1897,9 +2005,9 @@ int brcmf_fws_init(struct brcmf_pub *drvr) drvr->fw_signals ? "enabled" : "disabled", tlv); return 0; +fail_event: + brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); fail: - /* disable flow control entirely */ - drvr->fw_signals = false; brcmf_fws_deinit(drvr); return rc; } @@ -1912,6 +2020,14 @@ void brcmf_fws_deinit(struct brcmf_pub *drvr) if (!fws) return; + /* disable firmware signalling entirely + * to avoid using the workqueue. + */ + drvr->fw_signals = false; + + if (drvr->fws->fws_wq) + destroy_workqueue(drvr->fws->fws_wq); + /* cleanup */ brcmf_fws_lock(drvr, flags); 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) /** - * brcmf_p2p_chnr_to_chspec() - convert channel number to chanspec. - * - * @channel: channel number - */ -static u16 brcmf_p2p_chnr_to_chspec(u16 channel) -{ - u16 chanspec; - - chanspec = channel & WL_CHANSPEC_CHAN_MASK; - - if (channel <= CH_MAX_2G_CHANNEL) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - return chanspec; -} - - -/** * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation. * * @ifp: ifp to use for iovars (primary). @@ -837,7 +814,8 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, IEEE80211_CHAN_PASSIVE_SCAN)) continue; - chanspecs[i] = channel_to_chanspec(chan); + chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, + chan); brcmf_dbg(INFO, "%d: chan=%d, channel spec=%x\n", num_nodfs, chan->hw_value, chanspecs[i]); num_nodfs++; @@ -945,8 +923,8 @@ static s32 brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) { struct brcmf_cfg80211_vif *vif; + struct brcmu_chan ch; s32 err = 0; - u16 chanspec; vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; if (!vif) { @@ -961,9 +939,11 @@ brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) goto exit; } - chanspec = brcmf_p2p_chnr_to_chspec(channel); + ch.chnum = channel; + ch.bw = BRCMU_CHAN_BW_20; + p2p->cfg->d11inf.encchspec(&ch); err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN, - chanspec, (u16)duration); + ch.chspec, (u16)duration); if (!err) { set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status); p2p->remain_on_channel_cookie++; @@ -1075,6 +1055,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) u32 channel_cnt; u16 *default_chan_list; u32 i; + struct brcmu_chan ch; brcmf_dbg(TRACE, "Enter\n"); @@ -1089,15 +1070,23 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) err = -ENOMEM; goto exit; } + ch.bw = BRCMU_CHAN_BW_20; if (channel) { + ch.chnum = channel; + p2p->cfg->d11inf.encchspec(&ch); /* insert same channel to the chan_list */ for (i = 0; i < channel_cnt; i++) - default_chan_list[i] = - brcmf_p2p_chnr_to_chspec(channel); + default_chan_list[i] = ch.chspec; } else { - default_chan_list[0] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_1); - default_chan_list[1] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_2); - default_chan_list[2] = brcmf_p2p_chnr_to_chspec(SOCIAL_CHAN_3); + ch.chnum = SOCIAL_CHAN_1; + p2p->cfg->d11inf.encchspec(&ch); + default_chan_list[0] = ch.chspec; + ch.chnum = SOCIAL_CHAN_2; + p2p->cfg->d11inf.encchspec(&ch); + default_chan_list[1] = ch.chspec; + ch.chnum = SOCIAL_CHAN_3; + p2p->cfg->d11inf.encchspec(&ch); + default_chan_list[2] = ch.chspec; } err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list, 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, { struct brcmf_p2p_info *p2p = &cfg->p2p; struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct brcmu_chan ch; u8 *ie; s32 err; u8 p2p_dev_addr[ETH_ALEN]; @@ -1252,8 +1242,12 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, p2p_dev_addr, sizeof(p2p_dev_addr)); if ((err >= 0) && (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) { - afx_hdl->peer_chan = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + if (!bi->ctl_ch) { + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); + bi->ctl_ch = ch.chnum; + } + afx_hdl->peer_chan = bi->ctl_ch; brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", afx_hdl->tx_dst_addr, afx_hdl->peer_chan); complete(&afx_hdl->act_frm_scan); @@ -1360,12 +1354,14 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, u8 *frame = (u8 *)(rxframe + 1); struct brcmf_p2p_pub_act_frame *act_frm; struct brcmf_p2psd_gas_pub_act_frame *sd_act_frm; - u16 chanspec = be16_to_cpu(rxframe->chanspec); + struct brcmu_chan ch; struct ieee80211_mgmt *mgmt_frame; s32 freq; u16 mgmt_type; u8 action; + ch.chspec = be16_to_cpu(rxframe->chanspec); + cfg->d11inf.decchspec(&ch); /* Check if wpa_supplicant has registered for this frame */ brcmf_dbg(INFO, "ifp->vif->mgmt_rx_reg %04x\n", ifp->vif->mgmt_rx_reg); mgmt_type = (IEEE80211_STYPE_ACTION & IEEE80211_FCTL_STYPE) >> 4; @@ -1384,7 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, &p2p->status) && (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { - afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec); + afx_hdl->peer_chan = ch.chnum; brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", afx_hdl->peer_chan); complete(&afx_hdl->act_frm_scan); @@ -1427,8 +1423,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, memcpy(&mgmt_frame->u, frame, mgmt_frame_len); mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); - freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec), - CHSPEC_IS2G(chanspec) ? + freq = ieee80211_channel_to_frequency(ch.chnum, + ch.band == BRCMU_CHAN_BAND_2G ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ); @@ -1854,6 +1850,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, struct brcmf_cfg80211_vif *vif = ifp->vif; struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data; u16 chanspec = be16_to_cpu(rxframe->chanspec); + struct brcmu_chan ch; u8 *mgmt_frame; u32 mgmt_frame_len; s32 freq; @@ -1862,9 +1859,12 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, e->reason); + ch.chspec = be16_to_cpu(rxframe->chanspec); + cfg->d11inf.decchspec(&ch); + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { - afx_hdl->peer_chan = CHSPEC_CHANNEL(chanspec); + afx_hdl->peer_chan = ch.chnum; brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", afx_hdl->peer_chan); complete(&afx_hdl->act_frm_scan); @@ -1889,8 +1889,8 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, mgmt_frame = (u8 *)(rxframe + 1); mgmt_frame_len = e->datalen - sizeof(*rxframe); - freq = ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec), - CHSPEC_IS2G(chanspec) ? + freq = ieee80211_channel_to_frequency(ch.chnum, + ch.band == BRCMU_CHAN_BAND_2G ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ); @@ -2014,21 +2014,19 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p, { struct brcmf_if *ifp; struct brcmf_fil_chan_info_le ci; + struct brcmu_chan ch; s32 err; ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; - *chanspec = 11 & WL_CHANSPEC_CHAN_MASK; + ch.chnum = 11; err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci)); - if (!err) { - *chanspec = le32_to_cpu(ci.hw_channel) & WL_CHANSPEC_CHAN_MASK; - if (*chanspec < CH_MAX_2G_CHANNEL) - *chanspec |= WL_CHANSPEC_BAND_2G; - else - *chanspec |= WL_CHANSPEC_BAND_5G; - } - *chanspec |= WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; + if (!err) + ch.chnum = le32_to_cpu(ci.hw_channel); + ch.bw = BRCMU_CHAN_BW_20; + p2p->cfg->d11inf.encchspec(&ch); + *chanspec = ch.chspec; } /** 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 @@ #define BCM4329_CORE_ARM_BASE 0x18002000 #define BCM4329_RAMSIZE 0x48000 +/* bcm43143 */ +/* SDIO device core */ +#define BCM43143_CORE_BUS_BASE 0x18002000 +/* internal memory core */ +#define BCM43143_CORE_SOCRAM_BASE 0x18004000 +/* ARM Cortex M3 core, ID 0x82a */ +#define BCM43143_CORE_ARM_BASE 0x18003000 +#define BCM43143_RAMSIZE 0x70000 + #define SBCOREREV(sbidh) \ ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ ((sbidh) & SSB_IDHIGH_RCLO)) @@ -52,6 +61,9 @@ #define CIB_REV_MASK 0xff000000 #define CIB_REV_SHIFT 24 +/* ARM CR4 core specific control flag bits */ +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 + #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) /* SDIO Pad drive strength to select value mappings */ struct sdiod_drive_str { @@ -70,6 +82,14 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = { {0, 0x1} }; +/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ +static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { + {16, 0x7}, + {12, 0x5}, + {8, 0x3}, + {4, 0x1} +}; + u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) { @@ -149,7 +169,7 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct chip_info *ci, u16 coreid, u32 core_bits) { u32 regdata, base; u8 idx; @@ -235,7 +255,7 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct chip_info *ci, u16 coreid, u32 core_bits) { u8 idx; u32 regdata; @@ -249,19 +269,36 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, if ((regdata & BCMA_RESET_CTL_RESET) != 0) return; - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + /* ensure no pending backplane operation + * 300uc should be sufficient for backplane ops to be finish + * extra 10ms is taken into account for firmware load stage + * after 10300us carry on disabling the core anyway + */ + SPINWAIT(brcmf_sdio_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_ST, + NULL), 10300); + regdata = brcmf_sdio_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_ST, NULL); - udelay(10); + if (regdata) + brcmf_err("disabling core 0x%x with reset status %x\n", + coreid, regdata); brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, BCMA_RESET_CTL_RESET, NULL); udelay(1); + + brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + core_bits, NULL); + regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + NULL); + usleep_range(10, 20); + } static void brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct chip_info *ci, u16 coreid, u32 core_bits) { u32 regdata; u8 idx; @@ -272,7 +309,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, * Must do the disable sequence first to work for * arbitrary current core state. */ - brcmf_sdio_sb_coredisable(sdiodev, ci, coreid); + brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); /* * Now do the initialization sequence. @@ -325,7 +362,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct chip_info *ci, u16 coreid, u32 core_bits) { u8 idx; u32 regdata; @@ -333,31 +370,69 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); /* must disable first to work for arbitrary current core state */ - brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); + brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); /* now do initialization sequence */ brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); + core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, NULL); brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 0, NULL); + regdata = brcmf_sdio_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + NULL); udelay(1); brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - BCMA_IOCTL_CLK, NULL); + core_bits | BCMA_IOCTL_CLK, NULL); regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, NULL); udelay(1); } +#ifdef DEBUG +/* safety check for chipinfo */ +static int brcmf_sdio_chip_cichk(struct chip_info *ci) +{ + u8 core_idx; + + /* check RAM core presence for ARM CM3 core */ + core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); + if (BRCMF_MAX_CORENUM != core_idx) { + core_idx = brcmf_sdio_chip_getinfidx(ci, + BCMA_CORE_INTERNAL_MEM); + if (BRCMF_MAX_CORENUM == core_idx) { + brcmf_err("RAM core not provided with ARM CM3 core\n"); + return -ENODEV; + } + } + + /* check RAM base for ARM CR4 core */ + core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4); + if (BRCMF_MAX_CORENUM != core_idx) { + if (ci->rambase == 0) { + brcmf_err("RAM base not provided with ARM CR4 core\n"); + return -ENOMEM; + } + } + + return 0; +} +#else /* DEBUG */ +static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) +{ + return 0; +} +#endif + static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u32 regs) { u32 regdata; + int ret; - /* - * Get CC core rev + /* Get CC core rev * Chipid is assume to be at offset 0 from regs arg * For different chiptypes or old sdio hosts w/o chipcommon, * other ways of recognition should be added here. @@ -375,6 +450,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, /* Address of cores for new chips should be added here */ switch (ci->chip) { + case BCM43143_CHIP_ID: + ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; + ci->c_inf[0].cib = 0x2b000000; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; + ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; + ci->c_inf[1].cib = 0x18000000; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; + ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; + ci->c_inf[2].cib = 0x14000000; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; + ci->c_inf[3].cib = 0x07000000; + ci->ramsize = BCM43143_RAMSIZE; + break; case BCM43241_CHIP_ID: ci->c_inf[0].wrapbase = 0x18100000; ci->c_inf[0].cib = 0x2a084411; @@ -435,11 +527,29 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].cib = 0x07004211; ci->ramsize = 0x80000; break; + case BCM4335_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x2b084411; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18005000; + ci->c_inf[1].wrapbase = 0x18105000; + ci->c_inf[1].cib = 0x0f004211; + ci->c_inf[2].id = BCMA_CORE_ARM_CR4; + ci->c_inf[2].base = 0x18002000; + ci->c_inf[2].wrapbase = 0x18102000; + ci->c_inf[2].cib = 0x01084411; + ci->ramsize = 0xc0000; + ci->rambase = 0x180000; + break; default: brcmf_err("chipid 0x%x is not supported\n", ci->chip); return -ENODEV; } + ret = brcmf_sdio_chip_cichk(ci); + if (ret) + return ret; + switch (ci->socitype) { case SOCI_SB: ci->iscoreup = brcmf_sdio_sb_iscoreup; @@ -539,7 +649,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, * Make sure any on-chip ARM is off (in case strapping is wrong), * or downloaded code was already running. */ - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); + ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); } int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, @@ -600,21 +710,37 @@ void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u32 drivestrength) { - struct sdiod_drive_str *str_tab = NULL; - u32 str_mask = 0; - u32 str_shift = 0; + const struct sdiod_drive_str *str_tab = NULL; + u32 str_mask; + u32 str_shift; char chn[8]; u32 base = ci->c_inf[0].base; + u32 i; + u32 drivestrength_sel = 0; + u32 cc_data_temp; + u32 addr; if (!(ci->c_inf[0].caps & CC_CAP_PMU)) return; switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): - str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8; + str_tab = sdiod_drvstr_tab1_1v8; str_mask = 0x00003800; str_shift = 11; break; + case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): + /* note: 43143 does not support tristate */ + i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; + if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) { + str_tab = sdiod_drvstr_tab2_3v3; + str_mask = 0x00000007; + str_shift = 0; + } else + brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n", + brcmf_sdio_chip_name(ci->chip, chn, 8), + drivestrength); + break; default: brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", brcmf_sdio_chip_name(ci->chip, chn, 8), @@ -623,30 +749,207 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } if (str_tab != NULL) { - u32 drivestrength_sel = 0; - u32 cc_data_temp; - int i; - for (i = 0; str_tab[i].strength != 0; i++) { if (drivestrength >= str_tab[i].strength) { drivestrength_sel = str_tab[i].sel; break; } } - - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), - 1, NULL); - cc_data_temp = - brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, chipcontrol_addr), - NULL); + addr = CORE_CC_REG(base, chipcontrol_addr); + brcmf_sdio_regwl(sdiodev, addr, 1, NULL); + cc_data_temp = brcmf_sdio_regrl(sdiodev, addr, NULL); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr), - cc_data_temp, NULL); + brcmf_sdio_regwl(sdiodev, addr, cc_data_temp, NULL); - brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", - drivestrength, cc_data_temp); + brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", + str_tab[i].strength, drivestrength, cc_data_temp); } } + +#ifdef DEBUG +static bool +brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, + char *nvram_dat, uint nvram_sz) +{ + char *nvram_ularray; + int err; + bool ret = true; + + /* read back and verify */ + brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz); + nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL); + /* do not proceed while no memory but */ + if (!nvram_ularray) + return true; + + /* Upload image to verify downloaded contents. */ + memset(nvram_ularray, 0xaa, nvram_sz); + + /* Read the vars list to temp buffer for comparison */ + err = brcmf_sdio_ramrw(sdiodev, false, nvram_addr, nvram_ularray, + nvram_sz); + if (err) { + brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", + err, nvram_sz, nvram_addr); + } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) { + brcmf_err("Downloaded NVRAM image is corrupted\n"); + ret = false; + } + kfree(nvram_ularray); + + return ret; +} +#else /* DEBUG */ +static inline bool +brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, + char *nvram_dat, uint nvram_sz) +{ + return true; +} +#endif /* DEBUG */ + +static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, + char *nvram_dat, uint nvram_sz) +{ + int err; + u32 nvram_addr; + u32 token; + __le32 token_le; + + nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase; + + /* Write the vars list */ + err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); + if (err) { + brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n", + err, nvram_sz, nvram_addr); + return false; + } + + if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr, + nvram_dat, nvram_sz)) + return false; + + /* generate token: + * nvram size, converted to words, in lower 16-bits, checksum + * in upper 16-bits. + */ + token = nvram_sz / 4; + token = (~token << 16) | (token & 0x0000FFFF); + token_le = cpu_to_le32(token); + + brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize); + brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n", + nvram_addr, nvram_sz, token); + + /* Write the length token to the last word */ + if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), + (u8 *)&token_le, 4)) + return false; + + return true; +} + +static void +brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci) +{ + u32 zeros = 0; + + ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); + ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); + + /* clear length token */ + brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); +} + +static bool +brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, + char *nvram_dat, uint nvram_sz) +{ + u8 core_idx; + u32 reg_addr; + + if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { + brcmf_err("SOCRAM core is down after reset?\n"); + return false; + } + + if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) + return false; + + /* clear all interrupts */ + core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); + reg_addr = ci->c_inf[core_idx].base; + reg_addr += offsetof(struct sdpcmd_regs, intstatus); + brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); + + return true; +} + +static inline void +brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci) +{ + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, + ARMCR4_BCMA_IOCTL_CPUHALT); +} + +static bool +brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, + char *nvram_dat, uint nvram_sz) +{ + u8 core_idx; + u32 reg_addr; + + if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) + return false; + + /* clear all interrupts */ + core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); + reg_addr = ci->c_inf[core_idx].base; + reg_addr += offsetof(struct sdpcmd_regs, intstatus); + brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + + /* Write reset vector to address 0 */ + brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, + sizeof(ci->rst_vec)); + + /* restore ARM */ + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); + + return true; +} + +void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci) +{ + u8 arm_core_idx; + + arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); + if (BRCMF_MAX_CORENUM != arm_core_idx) { + brcmf_sdio_chip_cm3_enterdl(sdiodev, ci); + return; + } + + brcmf_sdio_chip_cr4_enterdl(sdiodev, ci); +} + +bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, char *nvram_dat, + uint nvram_sz) +{ + u8 arm_core_idx; + + arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); + if (BRCMF_MAX_CORENUM != arm_core_idx) + return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, + nvram_sz); + + return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); +} 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 { u32 pmurev; u32 pmucaps; u32 ramsize; + u32 rambase; + u32 rst_vec; /* reset vertor for ARM CR4 core */ bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u16 coreid); u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u16 coreid); void (*coredisable)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid); + struct chip_info *ci, u16 coreid, u32 core_bits); void (*resetcore)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid); + struct chip_info *ci, u16 coreid, u32 core_bits); }; struct sbconfig { @@ -124,6 +126,95 @@ struct sbconfig { u32 sbidhigh; /* identification */ }; +/* sdio core registers */ +struct sdpcmd_regs { + u32 corecontrol; /* 0x00, rev8 */ + u32 corestatus; /* rev8 */ + u32 PAD[1]; + u32 biststatus; /* rev8 */ + + /* PCMCIA access */ + u16 pcmciamesportaladdr; /* 0x010, rev8 */ + u16 PAD[1]; + u16 pcmciamesportalmask; /* rev8 */ + u16 PAD[1]; + u16 pcmciawrframebc; /* rev8 */ + u16 PAD[1]; + u16 pcmciaunderflowtimer; /* rev8 */ + u16 PAD[1]; + + /* interrupt */ + u32 intstatus; /* 0x020, rev8 */ + u32 hostintmask; /* rev8 */ + u32 intmask; /* rev8 */ + u32 sbintstatus; /* rev8 */ + u32 sbintmask; /* rev8 */ + u32 funcintmask; /* rev4 */ + u32 PAD[2]; + u32 tosbmailbox; /* 0x040, rev8 */ + u32 tohostmailbox; /* rev8 */ + u32 tosbmailboxdata; /* rev8 */ + u32 tohostmailboxdata; /* rev8 */ + + /* synchronized access to registers in SDIO clock domain */ + u32 sdioaccess; /* 0x050, rev8 */ + u32 PAD[3]; + + /* PCMCIA frame control */ + u8 pcmciaframectrl; /* 0x060, rev8 */ + u8 PAD[3]; + u8 pcmciawatermark; /* rev8 */ + u8 PAD[155]; + + /* interrupt batching control */ + u32 intrcvlazy; /* 0x100, rev8 */ + u32 PAD[3]; + + /* counters */ + u32 cmd52rd; /* 0x110, rev8 */ + u32 cmd52wr; /* rev8 */ + u32 cmd53rd; /* rev8 */ + u32 cmd53wr; /* rev8 */ + u32 abort; /* rev8 */ + u32 datacrcerror; /* rev8 */ + u32 rdoutofsync; /* rev8 */ + u32 wroutofsync; /* rev8 */ + u32 writebusy; /* rev8 */ + u32 readwait; /* rev8 */ + u32 readterm; /* rev8 */ + u32 writeterm; /* rev8 */ + u32 PAD[40]; + u32 clockctlstatus; /* rev8 */ + u32 PAD[7]; + + u32 PAD[128]; /* DMA engines */ + + /* SDIO/PCMCIA CIS region */ + char cis[512]; /* 0x400-0x5ff, rev6 */ + + /* PCMCIA function control registers */ + char pcmciafcr[256]; /* 0x600-6ff, rev6 */ + u16 PAD[55]; + + /* PCMCIA backplane access */ + u16 backplanecsr; /* 0x76E, rev6 */ + u16 backplaneaddr0; /* rev6 */ + u16 backplaneaddr1; /* rev6 */ + u16 backplaneaddr2; /* rev6 */ + u16 backplaneaddr3; /* rev6 */ + u16 backplanedata0; /* rev6 */ + u16 backplanedata1; /* rev6 */ + u16 backplanedata2; /* rev6 */ + u16 backplanedata3; /* rev6 */ + u16 PAD[31]; + + /* sprom "size" & "blank" info */ + u16 spromstatus; /* 0x7BE, rev2 */ + u32 PAD[464]; + + u16 PAD[0x80]; +}; + extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, struct chip_info **ci_ptr, u32 regs); 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, struct chip_info *ci, u32 drivestrength); extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); - +extern void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci); +extern bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, char *nvram_dat, + uint nvram_sz); #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 @@ #define SBSDIO_NUM_FUNCTION 3 /* function 0 vendor specific CCCR registers */ -#define SDIO_CCCR_BRCM_SEPINT 0xf2 +#define SDIO_CCCR_BRCM_CARDCAP 0xf0 +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 +#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 +#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 +#define SDIO_CCCR_BRCM_SEPINT 0xf2 #define SDIO_SEPINT_MASK 0x01 #define SDIO_SEPINT_OE 0x02 @@ -97,9 +103,23 @@ #define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count High */ #define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C +/* MesBusyCtl (rev 11) */ +#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D +/* Sdio Core Rev 12 */ +#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1 +#define SBSDIO_FUNC1_SLEEPCSR 0x1001F +#define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1 #define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ +#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001F /* f1 misc register end */ /* function 1 OCP space */ @@ -154,13 +174,11 @@ struct brcmf_sdio_dev { wait_queue_head_t request_buffer_wait; struct device *dev; struct brcmf_bus *bus_if; -#ifdef CONFIG_BRCMFMAC_SDIO_OOB - unsigned int irq; /* oob interrupt number */ - unsigned long irq_flags; /* board specific oob flags */ + struct brcmfmac_sdio_platform_data *pdata; + bool oob_irq_requested; bool irq_en; /* irq enable flags */ spinlock_t irq_en_lock; bool irq_wake; /* irq wake enable flags */ -#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ }; /* Register/deregister interrupt handler. */ @@ -224,6 +242,8 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, */ extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, u8 *buf, uint nbytes); +extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, + u32 address, u8 *data, uint size); /* Issue an abort to the specified function */ 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 @@ #include "tracepoint.h" #include "fwil_types.h" #include "p2p.h" +#include "btcoex.h" #include "wl_cfg80211.h" #include "fwil.h" @@ -334,22 +335,16 @@ static u8 brcmf_mw_to_qdbm(u16 mw) return qdbm; } -u16 channel_to_chanspec(struct ieee80211_channel *ch) +u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, + struct ieee80211_channel *ch) { - u16 chanspec; - - chanspec = ieee80211_frequency_to_channel(ch->center_freq); - chanspec &= WL_CHANSPEC_CHAN_MASK; - - if (ch->band == IEEE80211_BAND_2GHZ) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; + struct brcmu_chan ch_inf; - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq); + ch_inf.bw = BRCMU_CHAN_BW_20; + d11inf->encchspec(&ch_inf); - return chanspec; + return ch_inf.chspec; } /* Traverse a string of 1-byte tag/1-byte length/variable-length value @@ -680,7 +675,8 @@ done: return err; } -static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, +static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, + struct brcmf_scan_params_le *params_le, struct cfg80211_scan_request *request) { u32 n_ssids; @@ -712,7 +708,8 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, n_channels); if (n_channels > 0) { for (i = 0; i < n_channels; i++) { - chanspec = channel_to_chanspec(request->channels[i]); + chanspec = channel_to_chanspec(&cfg->d11inf, + request->channels[i]); brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n", request->channels[i]->hw_value, chanspec); 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, goto exit; } BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN); - brcmf_escan_prep(¶ms->params_le, request); + brcmf_escan_prep(cfg, ¶ms->params_le, request); params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); params->action = cpu_to_le16(action); params->sync_id = cpu_to_le16(0x1234); @@ -860,6 +857,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, cfg->scan_status); return -EAGAIN; } + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { + brcmf_err("Scanning suppressed: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); return -EAGAIN; @@ -1050,6 +1052,7 @@ static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); s32 err = 0; brcmf_dbg(TRACE, "Enter\n"); @@ -1063,6 +1066,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); } clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); + clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); + brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); brcmf_dbg(TRACE, "Exit\n"); } @@ -1182,7 +1187,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, params->chandef.chan->center_freq); if (params->channel_fixed) { /* adding chanspec */ - chanspec = channel_to_chanspec(params->chandef.chan); + chanspec = channel_to_chanspec(&cfg->d11inf, + params->chandef.chan); join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec); join_params.params_le.chanspec_num = cpu_to_le32(1); @@ -1572,7 +1578,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, if (chan) { cfg->channel = ieee80211_frequency_to_channel(chan->center_freq); - chanspec = channel_to_chanspec(chan); + chanspec = channel_to_chanspec(&cfg->d11inf, chan); brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n", cfg->channel, chan->center_freq, chanspec); } else { @@ -2231,6 +2237,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, struct ieee80211_channel *notify_channel; struct cfg80211_bss *bss; struct ieee80211_supported_band *band; + struct brcmu_chan ch; s32 err = 0; u16 channel; u32 freq; @@ -2245,8 +2252,12 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, return 0; } - channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + if (!bi->ctl_ch) { + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); + bi->ctl_ch = ch.chnum; + } + channel = bi->ctl_ch; if (channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -2321,9 +2332,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, struct brcmf_bss_info_le *bi = NULL; struct ieee80211_supported_band *band; struct cfg80211_bss *bss; + struct brcmu_chan ch; u8 *buf = NULL; s32 err = 0; - u16 channel; u32 freq; u16 notify_capability; u16 notify_interval; @@ -2350,15 +2361,15 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, bi = (struct brcmf_bss_info_le *)(buf + 4); - channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); - if (channel <= CH_MAX_2G_CHANNEL) + if (ch.band == BRCMU_CHAN_BAND_2G) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else band = wiphy->bands[IEEE80211_BAND_5GHZ]; - freq = ieee80211_channel_to_frequency(channel, band->band); + freq = ieee80211_channel_to_frequency(ch.chnum, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); notify_capability = le16_to_cpu(bi->capability); @@ -2367,7 +2378,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, notify_ielen = le32_to_cpu(bi->ie_length); notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; - brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq); + brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq); brcmf_dbg(CONN, "capability: %X\n", notify_capability); brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "signal: %d\n", notify_signal); @@ -2490,12 +2501,19 @@ static void brcmf_escan_timeout(unsigned long data) } static s32 -brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, +brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg, + struct brcmf_bss_info_le *bss, struct brcmf_bss_info_le *bss_info_le) { + struct brcmu_chan ch_bss, ch_bss_info_le; + + ch_bss.chspec = le16_to_cpu(bss->chanspec); + cfg->d11inf.decchspec(&ch_bss); + ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec); + cfg->d11inf.decchspec(&ch_bss_info_le); + if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) && - (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) == - CHSPEC_BAND(le16_to_cpu(bss->chanspec))) && + ch_bss.band == ch_bss_info_le.band && bss_info_le->SSID_len == bss->SSID_len && !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == @@ -2593,7 +2611,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, bss = bss ? (struct brcmf_bss_info_le *) ((unsigned char *)bss + le32_to_cpu(bss->length)) : list->bss_info_le; - if (brcmf_compare_update_same_bss(bss, bss_info_le)) + if (brcmf_compare_update_same_bss(cfg, bss, + bss_info_le)) goto exit; } memcpy(&(cfg->escan_info.escan_buf[list->buflen]), @@ -3007,6 +3026,11 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); return -EAGAIN; } + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { + brcmf_err("Scanning suppressed: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } if (!request->n_ssids || !request->n_match_sets) { brcmf_err("Invalid sched scan req!! n_ssids:%d\n", @@ -3993,6 +4017,39 @@ exit: return err; } +static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + enum nl80211_crit_proto_id proto, + u16 duration) +{ + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_cfg80211_vif *vif; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + + /* only DHCP support for now */ + if (proto != NL80211_CRIT_PROTO_DHCP) + return -EINVAL; + + /* suppress and abort scanning */ + set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); + brcmf_abort_scanning(cfg); + + return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration); +} + +static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_cfg80211_vif *vif; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + + brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); + clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); +} + static struct cfg80211_ops wl_cfg80211_ops = { .add_virtual_intf = brcmf_cfg80211_add_iface, .del_virtual_intf = brcmf_cfg80211_del_iface, @@ -4029,6 +4086,8 @@ static struct cfg80211_ops wl_cfg80211_ops = { .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, .start_p2p_device = brcmf_p2p_start_device, .stop_p2p_device = brcmf_p2p_stop_device, + .crit_proto_start = brcmf_cfg80211_crit_proto_start, + .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, #ifdef CONFIG_NL80211_TESTMODE .testmode_cmd = brcmf_cfg80211_testmode #endif @@ -4337,9 +4396,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, struct ieee80211_channel *notify_channel = NULL; struct ieee80211_supported_band *band; struct brcmf_bss_info_le *bi; + struct brcmu_chan ch; u32 freq; s32 err = 0; - u32 target_channel; u8 *buf; brcmf_dbg(TRACE, "Enter\n"); @@ -4363,15 +4422,15 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, goto done; bi = (struct brcmf_bss_info_le *)(buf + 4); - target_channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); - if (target_channel <= CH_MAX_2G_CHANNEL) + if (ch.band == BRCMU_CHAN_BAND_2G) band = wiphy->bands[IEEE80211_BAND_2GHZ]; else band = wiphy->bands[IEEE80211_BAND_5GHZ]; - freq = ieee80211_channel_to_frequency(target_channel, band->band); + freq = ieee80211_channel_to_frequency(ch.chnum, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); done: @@ -4725,6 +4784,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, struct brcmf_cfg80211_vif *vif; struct brcmf_if *ifp; s32 err = 0; + s32 io_type; if (!ndev) { brcmf_err("ndev is invalid\n"); @@ -4765,6 +4825,21 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, brcmf_err("P2P initilisation failed (%d)\n", err); goto cfg80211_p2p_attach_out; } + err = brcmf_btcoex_attach(cfg); + if (err) { + brcmf_err("BT-coex initialisation failed (%d)\n", err); + brcmf_p2p_detach(&cfg->p2p); + goto cfg80211_p2p_attach_out; + } + + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, + &io_type); + if (err) { + brcmf_err("Failed to get D11 version (%d)\n", err); + goto cfg80211_p2p_attach_out; + } + cfg->d11inf.io_type = (u8)io_type; + brcmu_d11_attach(&cfg->d11inf); return cfg; @@ -4783,6 +4858,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) struct brcmf_cfg80211_vif *tmp; wl_deinit_priv(cfg); + brcmf_btcoex_detach(cfg); list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { brcmf_free_vif(vif); } @@ -4885,11 +4961,11 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct ieee80211_channel *band_chan_arr; struct brcmf_chanspec_list *list; + struct brcmu_chan ch; s32 err; u8 *pbuf; u32 i, j; u32 total; - u16 chanspec; enum ieee80211_band band; u32 channel; u32 *n_cnt; @@ -4918,42 +4994,30 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) total = le32_to_cpu(list->count); for (i = 0; i < total; i++) { - chanspec = (u16)le32_to_cpu(list->element[i]); - channel = CHSPEC_CHANNEL(chanspec); + ch.chspec = (u16)le32_to_cpu(list->element[i]); + cfg->d11inf.decchspec(&ch); - if (CHSPEC_IS40(chanspec)) { - if (CHSPEC_SB_UPPER(chanspec)) - channel += CH_10MHZ_APART; - else - channel -= CH_10MHZ_APART; - } else if (CHSPEC_IS80(chanspec)) { - brcmf_dbg(INFO, "HT80 center channel : %d\n", - channel); - continue; - } - if (CHSPEC_IS2G(chanspec) && (channel >= CH_MIN_2G_CHANNEL) && - (channel <= CH_MAX_2G_CHANNEL)) { + if (ch.band == BRCMU_CHAN_BAND_2G) { band_chan_arr = __wl_2ghz_channels; array_size = ARRAY_SIZE(__wl_2ghz_channels); n_cnt = &__wl_band_2ghz.n_channels; band = IEEE80211_BAND_2GHZ; ht40_allowed = (bw_cap == WLC_N_BW_40ALL); - } else if (CHSPEC_IS5G(chanspec) && - channel >= CH_MIN_5G_CHANNEL) { + } else if (ch.band == BRCMU_CHAN_BAND_5G) { band_chan_arr = __wl_5ghz_a_channels; array_size = ARRAY_SIZE(__wl_5ghz_a_channels); n_cnt = &__wl_band_5ghz_a.n_channels; band = IEEE80211_BAND_5GHZ; ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); } else { - brcmf_err("Invalid channel Sepc. 0x%x.\n", chanspec); + brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec); continue; } - if (!ht40_allowed && CHSPEC_IS40(chanspec)) + if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40) continue; update = false; for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { - if (band_chan_arr[j].hw_value == channel) { + if (band_chan_arr[j].hw_value == ch.chnum) { update = true; break; } @@ -4964,16 +5028,16 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) index = *n_cnt; if (index < array_size) { band_chan_arr[index].center_freq = - ieee80211_channel_to_frequency(channel, band); - band_chan_arr[index].hw_value = channel; + ieee80211_channel_to_frequency(ch.chnum, band); + band_chan_arr[index].hw_value = ch.chnum; - if (CHSPEC_IS40(chanspec) && ht40_allowed) { + if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) { /* assuming the order is HT20, HT40 Upper, * HT40 lower from chanspecs */ ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; - if (CHSPEC_SB_UPPER(chanspec)) { + if (ch.sb == BRCMU_CHAN_SB_U) { if (ht40_flag == IEEE80211_CHAN_NO_HT40) band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40; @@ -4993,11 +5057,9 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) } else { band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40; - if (band == IEEE80211_BAND_2GHZ) - channel |= WL_CHANSPEC_BAND_2G; - else - channel |= WL_CHANSPEC_BAND_5G; - channel |= WL_CHANSPEC_BW_20; + ch.bw = BRCMU_CHAN_BW_20; + cfg->d11inf.encchspec(&ch); + channel = ch.chspec; err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info", &channel); @@ -5226,6 +5288,13 @@ s32 brcmf_cfg80211_down(struct net_device *ndev) return err; } +enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp) +{ + struct wireless_dev *wdev = &ifp->vif->wdev; + + return wdev->iftype; +} + u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state) { 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 @@ #ifndef _wl_cfg80211_h_ #define _wl_cfg80211_h_ +/* for brcmu_d11inf */ +#include <brcmu_d11.h> + #define WL_NUM_SCAN_MAX 10 #define WL_NUM_PMKIDS_MAX MAXPMKID #define WL_TLV_INFO_MAX 1024 @@ -74,14 +77,16 @@ /** - * enum brcmf_scan_status - dongle scan status + * enum brcmf_scan_status - scan engine status * * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle. * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle. + * @BRCMF_SCAN_STATUS_SUPPRESS: scanning is suppressed in driver. */ enum brcmf_scan_status { BRCMF_SCAN_STATUS_BUSY, BRCMF_SCAN_STATUS_ABORT, + BRCMF_SCAN_STATUS_SUPPRESS, }; /** @@ -346,6 +351,7 @@ struct brcmf_cfg80211_vif_event { * @wiphy: wiphy object for cfg80211 interface. * @conf: dongle configuration. * @p2p: peer-to-peer specific information. + * @btcoex: Bluetooth coexistence information. * @scan_request: cfg80211 scan request object. * @usr_sync: mainly for dongle up/down synchronization. * @bss_list: bss_list holding scanned ap information. @@ -379,6 +385,7 @@ struct brcmf_cfg80211_info { struct wiphy *wiphy; struct brcmf_cfg80211_conf *conf; struct brcmf_p2p_info p2p; + struct brcmf_btcoex_info *btcoex; struct cfg80211_scan_request *scan_request; struct mutex usr_sync; struct brcmf_scan_results *bss_list; @@ -408,6 +415,7 @@ struct brcmf_cfg80211_info { u8 vif_cnt; struct brcmf_cfg80211_vif_event vif_event; struct completion vif_disabled; + struct brcmu_d11inf d11inf; }; /** @@ -474,6 +482,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); s32 brcmf_cfg80211_up(struct net_device *ndev); s32 brcmf_cfg80211_down(struct net_device *ndev); +enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type, @@ -484,7 +493,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, const u8 *vndr_ie_buf, u32 vndr_ie_len); s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key); -u16 channel_to_chanspec(struct ieee80211_channel *ch); +u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, + struct ieee80211_channel *ch); u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state); void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, 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 := \ -Idrivers/net/wireless/brcm80211/brcmsmac/phy \ -Idrivers/net/wireless/brcm80211/include -BRCMSMAC_OFILES := \ +brcmsmac-y := \ mac80211_if.o \ ucode_loader.o \ ampdu.o \ @@ -43,11 +43,6 @@ BRCMSMAC_OFILES := \ brcms_trace_events.o \ debug.o -ifdef CONFIG_BCMA_DRIVER_GPIO -BRCMSMAC_OFILES += led.o -endif +brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o -MODULEPFX := brcmsmac - -obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o -$(MODULEPFX)-objs = $(BRCMSMAC_OFILES) +obj-$(CONFIG_BRCMSMAC) += brcmsmac.o 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, u8 local_constraint_qdbm) { struct brcms_c_info *wlc = wlc_cm->wlc; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; struct txpwr_limits txpwr; 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, struct txpwr_limits *txpwr) { struct brcms_c_info *wlc = wlc_cm->wlc; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; uint i; uint chan; 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) new_int); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - if (conf->channel_type == NL80211_CHAN_HT20 || - conf->channel_type == NL80211_CHAN_NO_HT) + if (conf->chandef.width == NL80211_CHAN_WIDTH_20 || + conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) err = brcms_c_set_channel(wl->wlc, - conf->channel->hw_value); + conf->chandef.chan->hw_value); else err = -ENOTSUPP; } 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) wlc->pub->up = true; if (wlc->bandinit_pending) { - ch = wlc->pub->ieee_hw->conf.channel; + ch = wlc->pub->ieee_hw->conf.chandef.chan; brcms_c_suspend_mac_and_wait(wlc); brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); wlc->bandinit_pending = false; @@ -7919,7 +7919,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) { struct bcma_device *core = wlc->hw->d11core; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; + struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan; u16 chanspec; 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 := \ -Idrivers/net/wireless/brcm80211/brcmutil \ -Idrivers/net/wireless/brcm80211/include -BRCMUTIL_OFILES := \ - utils.o - -MODULEPFX := brcmutil - -obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o -$(MODULEPFX)-objs = $(BRCMUTIL_OFILES) +obj-$(CONFIG_BRCMUTIL) += brcmutil.o +brcmutil-objs = utils.o d11.o 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 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*********************channel spec common functions*********************/ + +#include <linux/module.h> + +#include <brcmu_utils.h> +#include <brcmu_wifi.h> +#include <brcmu_d11.h> + +static void brcmu_d11n_encchspec(struct brcmu_chan *ch) +{ + ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; + + switch (ch->bw) { + case BRCMU_CHAN_BW_20: + ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N; + break; + case BRCMU_CHAN_BW_40: + default: + WARN_ON_ONCE(1); + break; + } + + if (ch->chnum <= CH_MAX_2G_CHANNEL) + ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G; + else + ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G; +} + +static void brcmu_d11ac_encchspec(struct brcmu_chan *ch) +{ + ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; + + switch (ch->bw) { + case BRCMU_CHAN_BW_20: + ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20; + break; + case BRCMU_CHAN_BW_40: + case BRCMU_CHAN_BW_80: + case BRCMU_CHAN_BW_80P80: + case BRCMU_CHAN_BW_160: + default: + WARN_ON_ONCE(1); + break; + } + + if (ch->chnum <= CH_MAX_2G_CHANNEL) + ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; + else + ch->chspec |= BRCMU_CHSPEC_D11AC_BND_5G; +} + +static void brcmu_d11n_decchspec(struct brcmu_chan *ch) +{ + u16 val; + + ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); + + switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { + case BRCMU_CHSPEC_D11N_BW_20: + ch->bw = BRCMU_CHAN_BW_20; + break; + case BRCMU_CHSPEC_D11N_BW_40: + ch->bw = BRCMU_CHAN_BW_40; + val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK; + if (val == BRCMU_CHSPEC_D11N_SB_L) { + ch->sb = BRCMU_CHAN_SB_L; + ch->chnum -= CH_10MHZ_APART; + } else { + ch->sb = BRCMU_CHAN_SB_U; + ch->chnum += CH_10MHZ_APART; + } + break; + default: + WARN_ON_ONCE(1); + break; + } + + switch (ch->chspec & BRCMU_CHSPEC_D11N_BND_MASK) { + case BRCMU_CHSPEC_D11N_BND_5G: + ch->band = BRCMU_CHAN_BAND_5G; + break; + case BRCMU_CHSPEC_D11N_BND_2G: + ch->band = BRCMU_CHAN_BAND_2G; + break; + default: + WARN_ON_ONCE(1); + break; + } +} + +static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) +{ + u16 val; + + ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); + + switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { + case BRCMU_CHSPEC_D11AC_BW_20: + ch->bw = BRCMU_CHAN_BW_20; + break; + case BRCMU_CHSPEC_D11AC_BW_40: + ch->bw = BRCMU_CHAN_BW_40; + val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK; + if (val == BRCMU_CHSPEC_D11AC_SB_L) { + ch->sb = BRCMU_CHAN_SB_L; + ch->chnum -= CH_10MHZ_APART; + } else if (val == BRCMU_CHSPEC_D11AC_SB_U) { + ch->sb = BRCMU_CHAN_SB_U; + ch->chnum += CH_10MHZ_APART; + } else { + WARN_ON_ONCE(1); + } + break; + case BRCMU_CHSPEC_D11AC_BW_80: + ch->bw = BRCMU_CHAN_BW_80; + break; + case BRCMU_CHSPEC_D11AC_BW_8080: + case BRCMU_CHSPEC_D11AC_BW_160: + default: + WARN_ON_ONCE(1); + break; + } + + switch (ch->chspec & BRCMU_CHSPEC_D11AC_BND_MASK) { + case BRCMU_CHSPEC_D11AC_BND_5G: + ch->band = BRCMU_CHAN_BAND_5G; + break; + case BRCMU_CHSPEC_D11AC_BND_2G: + ch->band = BRCMU_CHAN_BAND_2G; + break; + default: + WARN_ON_ONCE(1); + break; + } +} + +void brcmu_d11_attach(struct brcmu_d11inf *d11inf) +{ + if (d11inf->io_type == BRCMU_D11N_IOTYPE) { + d11inf->encchspec = brcmu_d11n_encchspec; + d11inf->decchspec = brcmu_d11n_decchspec; + } else { + d11inf->encchspec = brcmu_d11ac_encchspec; + d11inf->decchspec = brcmu_d11ac_decchspec; + } +} +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) { if (!skb) return; + WARN_ON(skb->next); - if (skb->destructor) - /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if - * destructor exists - */ - dev_kfree_skb_any(skb); - else - /* can free immediately (even in_irq()) if destructor - * does not exist - */ - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); } EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); 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 @@ /* Chipcommon Core Chip IDs */ #define BCM4313_CHIP_ID 0x4313 +#define BCM43143_CHIP_ID 43143 #define BCM43224_CHIP_ID 43224 #define BCM43225_CHIP_ID 43225 #define BCM43235_CHIP_ID 43235 @@ -39,5 +40,6 @@ #define BCM4330_CHIP_ID 0x4330 #define BCM4331_CHIP_ID 0x4331 #define BCM4334_CHIP_ID 0x4334 +#define BCM4335_CHIP_ID 0x4335 #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 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCMU_D11_H_ +#define _BRCMU_D11_H_ + +/* d11 io type */ +#define BRCMU_D11N_IOTYPE 1 +#define BRCMU_D11AC_IOTYPE 2 + +/* A chanspec (channel specification) holds the channel number, band, + * bandwidth and control sideband + */ + +/* chanspec binary format */ + +#define BRCMU_CHSPEC_INVALID 255 +/* bit 0~7 channel number + * for 80+80 channels: bit 0~3 low channel id, bit 4~7 high channel id + */ +#define BRCMU_CHSPEC_CH_MASK 0x00ff +#define BRCMU_CHSPEC_CH_SHIFT 0 +#define BRCMU_CHSPEC_CHL_MASK 0x000f +#define BRCMU_CHSPEC_CHL_SHIFT 0 +#define BRCMU_CHSPEC_CHH_MASK 0x00f0 +#define BRCMU_CHSPEC_CHH_SHIFT 4 + +/* bit 8~16 for dot 11n IO types + * bit 8~9 sideband + * bit 10~11 bandwidth + * bit 12~13 spectral band + * bit 14~15 not used + */ +#define BRCMU_CHSPEC_D11N_SB_MASK 0x0300 +#define BRCMU_CHSPEC_D11N_SB_SHIFT 8 +#define BRCMU_CHSPEC_D11N_SB_L 0x0100 /* control lower */ +#define BRCMU_CHSPEC_D11N_SB_U 0x0200 /* control upper */ +#define BRCMU_CHSPEC_D11N_SB_N 0x0300 /* none */ +#define BRCMU_CHSPEC_D11N_BW_MASK 0x0c00 +#define BRCMU_CHSPEC_D11N_BW_SHIFT 10 +#define BRCMU_CHSPEC_D11N_BW_10 0x0400 +#define BRCMU_CHSPEC_D11N_BW_20 0x0800 +#define BRCMU_CHSPEC_D11N_BW_40 0x0c00 +#define BRCMU_CHSPEC_D11N_BND_MASK 0x3000 +#define BRCMU_CHSPEC_D11N_BND_SHIFT 12 +#define BRCMU_CHSPEC_D11N_BND_5G 0x1000 +#define BRCMU_CHSPEC_D11N_BND_2G 0x2000 + +/* bit 8~16 for dot 11ac IO types + * bit 8~10 sideband + * bit 11~13 bandwidth + * bit 14~15 spectral band + */ +#define BRCMU_CHSPEC_D11AC_SB_MASK 0x0700 +#define BRCMU_CHSPEC_D11AC_SB_SHIFT 8 +#define BRCMU_CHSPEC_D11AC_SB_LLL 0x0000 +#define BRCMU_CHSPEC_D11AC_SB_LLU 0x0100 +#define BRCMU_CHSPEC_D11AC_SB_LUL 0x0200 +#define BRCMU_CHSPEC_D11AC_SB_LUU 0x0300 +#define BRCMU_CHSPEC_D11AC_SB_ULL 0x0400 +#define BRCMU_CHSPEC_D11AC_SB_ULU 0x0500 +#define BRCMU_CHSPEC_D11AC_SB_UUL 0x0600 +#define BRCMU_CHSPEC_D11AC_SB_UUU 0x0700 +#define BRCMU_CHSPEC_D11AC_SB_LL BRCMU_CHSPEC_D11AC_SB_LLL +#define BRCMU_CHSPEC_D11AC_SB_LU BRCMU_CHSPEC_D11AC_SB_LLU +#define BRCMU_CHSPEC_D11AC_SB_UL BRCMU_CHSPEC_D11AC_SB_LUL +#define BRCMU_CHSPEC_D11AC_SB_UU BRCMU_CHSPEC_D11AC_SB_LUU +#define BRCMU_CHSPEC_D11AC_SB_L BRCMU_CHSPEC_D11AC_SB_LLL +#define BRCMU_CHSPEC_D11AC_SB_U BRCMU_CHSPEC_D11AC_SB_LLU +#define BRCMU_CHSPEC_D11AC_BW_MASK 0x3800 +#define BRCMU_CHSPEC_D11AC_BW_SHIFT 11 +#define BRCMU_CHSPEC_D11AC_BW_5 0x0000 +#define BRCMU_CHSPEC_D11AC_BW_10 0x0800 +#define BRCMU_CHSPEC_D11AC_BW_20 0x1000 +#define BRCMU_CHSPEC_D11AC_BW_40 0x1800 +#define BRCMU_CHSPEC_D11AC_BW_80 0x2000 +#define BRCMU_CHSPEC_D11AC_BW_160 0x2800 +#define BRCMU_CHSPEC_D11AC_BW_8080 0x3000 +#define BRCMU_CHSPEC_D11AC_BND_MASK 0xc000 +#define BRCMU_CHSPEC_D11AC_BND_SHIFT 14 +#define BRCMU_CHSPEC_D11AC_BND_2G 0x0000 +#define BRCMU_CHSPEC_D11AC_BND_3G 0x4000 +#define BRCMU_CHSPEC_D11AC_BND_4G 0x8000 +#define BRCMU_CHSPEC_D11AC_BND_5G 0xc000 + +#define BRCMU_CHAN_BAND_2G 0 +#define BRCMU_CHAN_BAND_5G 1 + +enum brcmu_chan_bw { + BRCMU_CHAN_BW_20, + BRCMU_CHAN_BW_40, + BRCMU_CHAN_BW_80, + BRCMU_CHAN_BW_80P80, + BRCMU_CHAN_BW_160, +}; + +enum brcmu_chan_sb { + BRCMU_CHAN_SB_NONE = 0, + BRCMU_CHAN_SB_L, + BRCMU_CHAN_SB_U, + BRCMU_CHAN_SB_LL, + BRCMU_CHAN_SB_LU, + BRCMU_CHAN_SB_UL, + BRCMU_CHAN_SB_UU, + BRCMU_CHAN_SB_LLL, + BRCMU_CHAN_SB_LLU, + BRCMU_CHAN_SB_LUL, + BRCMU_CHAN_SB_LUU, + BRCMU_CHAN_SB_ULL, + BRCMU_CHAN_SB_ULU, + BRCMU_CHAN_SB_UUL, + BRCMU_CHAN_SB_UUU, +}; + +struct brcmu_chan { + u16 chspec; + u8 chnum; + u8 band; + enum brcmu_chan_bw bw; + enum brcmu_chan_sb sb; +}; + +struct brcmu_d11inf { + u8 io_type; + + void (*encchspec)(struct brcmu_chan *ch); + void (*decchspec)(struct brcmu_chan *ch); +}; + +extern void brcmu_d11_attach(struct brcmu_d11inf *d11inf); + +#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 { u32 res_req_timer_sel; u32 res_req_timer; u32 res_req_mask; - u32 PAD; + u32 pmucapabilities_ext; /* 0x64c, pmurev >=15 */ u32 chipcontrol_addr; /* 0x650 */ u32 chipcontrol_data; /* 0x654 */ u32 regcontrol_addr; @@ -214,7 +214,11 @@ struct chipcregs { u32 pllcontrol_data; u32 pmustrapopt; /* 0x668, corerev >= 28 */ u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ - u32 PAD[100]; + u32 retention_ctl; /* 0x670, pmurev >= 15 */ + u32 PAD[3]; + u32 retention_grpidx; /* 0x680 */ + u32 retention_grpctl; /* 0x684 */ + u32 PAD[94]; u16 sromotp[768]; }; @@ -276,6 +280,12 @@ struct chipcregs { #define PCAP5_VC_SHIFT 22 #define PCAP5_CC_MASK 0xf8000000 #define PCAP5_CC_SHIFT 27 +/* pmucapabilites_ext PMU rev >= 15 */ +#define PCAPEXT_SR_SUPPORTED_MASK (1 << 1) +/* retention_ctl PMU rev >= 15 */ +#define PMU_RCTL_MACPHY_DISABLE_MASK (1 << 26) +#define PMU_RCTL_LOGIC_DISABLE_MASK (1 << 27) + /* * 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) static ssize_t store_debug_level(struct device_driver *d, const char *buf, size_t count) { - char *p = (char *)buf; u32 val; + int ret; - if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { - p++; - if (p[0] == 'x' || p[0] == 'X') - p++; - val = simple_strtoul(p, &p, 16); - } else - val = simple_strtoul(p, &p, 10); - if (p == buf) + ret = kstrtou32(buf, 0, &val); + if (ret) IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf); else ipw2100_debug_level = val; @@ -4238,27 +4232,15 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, { struct ipw2100_priv *priv = dev_get_drvdata(d); struct net_device *dev = priv->net_dev; - char buffer[] = "00000000"; - unsigned long len = - (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; unsigned long val; - char *p = buffer; + int ret; (void)dev; /* kill unused-var warning for debug-only code */ IPW_DEBUG_INFO("enter\n"); - strncpy(buffer, buf, len); - buffer[len] = 0; - - if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { - p++; - if (p[0] == 'x' || p[0] == 'X') - p++; - val = simple_strtoul(p, &p, 16); - } else - val = simple_strtoul(p, &p, 10); - if (p == buffer) { + ret = kstrtoul(buf, 0, &val); + if (ret) { IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name); } else { priv->ieee->scan_age = val; @@ -4266,7 +4248,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, } IPW_DEBUG_INFO("exit\n"); - return len; + return strnlen(buf, count); } 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) psta = (struct il3945_sta_priv *)sta->drv_priv; rs_sta = &psta->rs_sta; - sband = hw->wiphy->bands[conf->channel->band]; + sband = hw->wiphy->bands[conf->chandef.chan->band]; rs_sta->il = il; 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, struct il_priv *il = hw->priv; const struct il_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = ch_switch->channel; + struct ieee80211_channel *channel = ch_switch->chandef.chan; struct il_ht_config *ht_conf = &il->current_ht_config; u16 ch; @@ -6094,23 +6094,21 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, il->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - il->ht.enabled = conf_is_ht(conf); - if (il->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - il->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - il->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - il->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - il->ht.is_40mhz = true; - } else { - il->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - il->ht.is_40mhz = false; - } - } else + switch (cfg80211_get_chandef_type(&ch_switch->chandef)) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: il->ht.is_40mhz = false; + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + break; + case NL80211_CHAN_HT40MINUS: + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; + il->ht.is_40mhz = true; + break; + case NL80211_CHAN_HT40PLUS: + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + il->ht.is_40mhz = true; + break; + } if ((le16_to_cpu(il->staging.channel) != ch)) 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) sta_priv = (struct il_station_priv *)sta->drv_priv; lq_sta = &sta_priv->lq_sta; - sband = hw->wiphy->bands[conf->channel->band]; + sband = hw->wiphy->bands[conf->chandef.chan->band]; lq_sta->lq.sta_id = sta_id; 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, cmd.band = band; cmd.expect_beacon = 0; - ch = ch_switch->channel->hw_value; + ch = ch_switch->chandef.chan->hw_value; cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = il->staging.flags; 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) struct il_priv *il = hw->priv; const struct il_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = conf->channel; + struct ieee80211_channel *channel = conf->chandef.chan; struct il_ht_config *ht_conf = &il->current_ht_config; unsigned long flags = 0; 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 @@ /* AUX (TX during scan dwell) queue */ #define IWL_AUX_QUEUE 10 +#define IWL_INVALID_STATION 255 + /* device operations */ extern struct iwl_lib_ops iwl1000_lib; extern struct iwl_lib_ops iwl2000_lib; @@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); void iwlagn_temperature(struct iwl_priv *priv); -int iwlagn_txfifo_flush(struct iwl_priv *priv); +int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 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, struct ieee80211_sta *sta, u16 tid, u8 buf_size); int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); +int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid); int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, 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, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; - ch = ch_switch->channel->hw_value; + ch = ch_switch->chandef.chan->hw_value; IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", ctx->active.channel, ch); cmd.channel = cpu_to_le16(ch); @@ -414,7 +414,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", cmd.switch_time); - cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; + cmd.expect_beacon = + ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; return iwl_dvm_send_cmd(priv, &hcmd); } @@ -540,7 +541,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, hcmd.data[0] = cmd; cmd->band = priv->band == IEEE80211_BAND_2GHZ; - ch = ch_switch->channel->hw_value; + ch = ch_switch->chandef.chan->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", ctx->active.channel, ch); cmd->channel = cpu_to_le16(ch); @@ -575,7 +576,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", cmd->switch_time); - cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; + cmd->expect_beacon = + ch_switch->chandef.chan->flags & IEEE80211_CHAN_RADAR; err = iwl_dvm_send_cmd(priv, &hcmd); 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, * 1. acquire mutex before calling * 2. make sure rf is on and not in exit state */ -int iwlagn_txfifo_flush(struct iwl_priv *priv) +int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk) { struct iwl_txfifo_flush_cmd flush_cmd; struct iwl_host_cmd cmd = { @@ -162,6 +162,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv) if (priv->nvm_data->sku_cap_11n_enable) flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; + if (scd_q_msk) + flush_cmd.queue_control = cpu_to_le32(scd_q_msk); + IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", flush_cmd.queue_control); flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); @@ -173,7 +176,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) { mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); - if (iwlagn_txfifo_flush(priv)) { + if (iwlagn_txfifo_flush(priv, 0)) { IWL_ERR(priv, "flush request fail\n"); goto done; } @@ -1084,7 +1087,14 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; - struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; + struct iwlagn_d3_config_cmd d3_cfg_cmd = { + /* + * Program the minimum sleep time to 10 seconds, as many + * platforms have issues processing a wakeup signal while + * still being in the process of suspending. + */ + .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), + }; struct wowlan_key_data key_data = { .ctx = ctx, .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, IWL_DEBUG_HT(priv, "start Tx\n"); ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); break; - case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + IWL_DEBUG_HT(priv, "Flush Tx\n"); + ret = iwlagn_tx_agg_flush(priv, vif, sta, tid); + break; + case IEEE80211_AMPDU_TX_STOP_CONT: IWL_DEBUG_HT(priv, "stop Tx\n"); ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); if ((ret == 0) && (priv->agg_tids_count > 0)) { @@ -967,7 +970,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = ch_switch->channel; + struct ieee80211_channel *channel = ch_switch->chandef.chan; struct iwl_ht_config *ht_conf = &priv->current_ht_config; /* * MULTI-FIXME @@ -1005,11 +1008,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) - iwlagn_config_ht40(conf, ctx); - else + switch (cfg80211_get_chandef_type(&ch_switch->chandef)) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: ctx->ht.is_40mhz = false; + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + break; + case NL80211_CHAN_HT40MINUS: + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + break; + case NL80211_CHAN_HT40PLUS: + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + break; + } if ((le16_to_cpu(ctx->staging.channel) != ch)) ctx->staging.flags = 0; @@ -1122,7 +1135,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) */ if (drop) { IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (iwlagn_txfifo_flush(priv)) { + if (iwlagn_txfifo_flush(priv, 0)) { IWL_ERR(priv, "flush request fail\n"); goto done; } 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 sta_priv = (struct iwl_station_priv *) sta->drv_priv; lq_sta = &sta_priv->lq_sta; - sband = hw->wiphy->bands[conf->channel->band]; + sband = hw->wiphy->bands[conf->chandef.chan->band]; 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, ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif - ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value); - priv->band = priv->hw->conf.channel->band; + ctx->staging.channel = + cpu_to_le16(priv->hw->conf.chandef.chan->hw_value); + priv->band = priv->hw->conf.chandef.chan->band; iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); @@ -951,7 +952,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, unsigned long basic = ctx->vif->bss_conf.basic_rates; int i; - sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band]; + sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band]; for_each_set_bit(i, &basic, BITS_PER_LONG) { int hw = sband->bitrates[i].hw_value; @@ -1159,7 +1160,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } void iwlagn_config_ht40(struct ieee80211_conf *conf, - struct iwl_rxon_context *ctx) + struct iwl_rxon_context *ctx) { if (conf_is_ht40_minus(conf)) { ctx->ht.extension_chan_offset = @@ -1181,7 +1182,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx; struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = conf->channel; + struct ieee80211_channel *channel = conf->chandef.chan; int ret = 0; 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, return ret; } +int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid) +{ + struct iwl_tid_data *tid_data; + enum iwl_agg_state agg_state; + int sta_id, txq_id; + sta_id = iwl_sta_id(sta); + + /* + * First set the agg state to OFF to avoid calling + * ieee80211_stop_tx_ba_cb in iwlagn_check_ratid_empty. + */ + spin_lock_bh(&priv->sta_lock); + + tid_data = &priv->tid_data[sta_id][tid]; + txq_id = tid_data->agg.txq_id; + agg_state = tid_data->agg.state; + IWL_DEBUG_TX_QUEUES(priv, "Flush AGG: sta %d tid %d q %d state %d\n", + sta_id, tid, txq_id, tid_data->agg.state); + + tid_data->agg.state = IWL_AGG_OFF; + + spin_unlock_bh(&priv->sta_lock); + + if (iwlagn_txfifo_flush(priv, BIT(txq_id))) + IWL_ERR(priv, "Couldn't flush the AGG queue\n"); + + if (test_bit(txq_id, priv->agg_q_alloc)) { + /* + * If the transport didn't know that we wanted to start + * agreggation, don't tell it that we want to stop them. + * This can happen when we don't get the addBA response on + * time, or we hadn't time to drain the AC queues. + */ + if (agg_state == IWL_AGG_ON) + iwl_trans_txq_disable(priv->trans, txq_id); + else + IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", + agg_state); + iwlagn_dealloc_agg_txq(priv, txq_id); + } + + return 0; +} + int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u8 buf_size) { 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) } } - IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); - /* * In mvm uCode there is no difference between data and instructions * sections. @@ -970,6 +968,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) else op = &iwlwifi_opmode_table[DVM_OP_MODE]; + IWL_INFO(drv, "loaded firmware version %s op_mode %s\n", + drv->fw.fw_version, op->name); + /* add this device to the list of devices using this op_mode */ list_add_tail(&drv->list, &op->drv); @@ -997,8 +998,13 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) * else from proceeding if the module fails to load * or hangs loading. */ - if (load_module) - request_module("%s", op->name); + if (load_module) { + err = request_module("%s", op->name); + if (err) + IWL_ERR(drv, + "failed to load module %s (error %d), is dynamic loading enabled?\n", + op->name, err); + } return; 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) * currently supports */ #define IWL_MAX_HW_QUEUES 32 -#define IWL_INVALID_STATION 255 #define IWL_MAX_TID_COUNT 8 #define IWL_FRAME_LIMIT 64 @@ -682,7 +681,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo) { - iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, + iwl_trans_txq_enable(trans, queue, fifo, -1, IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); } 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 @@ * *****************************************************************************/ +#include <net/mac80211.h> + #include "fw-api-bt-coex.h" #include "iwl-modparams.h" #include "mvm.h" @@ -96,6 +98,20 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { #undef EVENT_PRIO_ANT +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) +#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) + +#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) +#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) +#define BT_REDUCED_TX_POWER_BIT BIT(7) + +static inline bool is_loose_coex(void) +{ + return iwlwifi_mod_params.ant_coupling > + IWL_BT_ANTENNA_COUPLING_THRESHOLD; +} + int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) { 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] = { cpu_to_le32(0x00000000), }; -/* BT Antenna Coupling Threshold (dB) */ -#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) -#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) - - int iwl_send_bt_init_conf(struct iwl_mvm *mvm) { struct iwl_bt_coex_cmd cmd = { @@ -203,8 +214,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) cmd.flags = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE; - cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? BT_CH_PRIMARY_EN : 0; - cmd.flags |= BT_SYNC_2_BT_DISABLE; + cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | BT_VALID_BT_PRIO_BOOST | @@ -215,7 +225,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) BT_VALID_REDUCED_TX_POWER | BT_VALID_LUT); - if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) + if (is_loose_coex()) memcpy(&cmd.decision_lut, iwl_loose_lookup, sizeof(iwl_tight_lookup)); else @@ -228,6 +238,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); + memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); + /* go to CALIB state in internal BT-Coex state machine */ ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); @@ -243,19 +255,101 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) sizeof(cmd), &cmd); } -struct iwl_bt_notif_iterator_data { - struct iwl_mvm *mvm; +static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, + bool reduced_tx_power) +{ + enum iwl_bt_kill_msk bt_kill_msk; + struct iwl_bt_coex_cmd cmd = {}; + struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; + + lockdep_assert_held(&mvm->mutex); + + if (reduced_tx_power) { + /* Reduced Tx power has precedence on the type of the profile */ + bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW; + } else { + /* Low latency BT profile is active: give higher prio to BT */ + if (BT_MBOX_MSG(notif, 3, SCO_STATE) || + BT_MBOX_MSG(notif, 3, A2DP_STATE) || + BT_MBOX_MSG(notif, 3, SNIFF_STATE)) + bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; + else + bt_kill_msk = BT_KILL_MSK_DEFAULT; + } + + IWL_DEBUG_COEX(mvm, + "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", + bt_kill_msk, + BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); + + /* Don't send HCMD if there is no update */ + if (bt_kill_msk == mvm->bt_kill_msk) + return 0; + + mvm->bt_kill_msk = bt_kill_msk; + cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); + cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); + cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); + + IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); + return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, + sizeof(cmd), &cmd); +} + +static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, + bool enable) +{ + struct iwl_bt_coex_cmd cmd = { + .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), + .bt_reduced_tx_power = sta_id, + }; + struct ieee80211_sta *sta; + struct iwl_mvm_sta *mvmsta; + + /* This can happen if the station has been removed right now */ + if (sta_id == IWL_MVM_STATION_COUNT) + return 0; + + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], + lockdep_is_held(&mvm->mutex)); + mvmsta = (void *)sta->drv_priv; + + /* nothing to do */ + if (mvmsta->bt_reduced_txpower == enable) + return 0; + + if (enable) + cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT; + + IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n", + enable ? "en" : "dis", sta_id); + + mvmsta->bt_reduced_txpower = enable; + + /* Send ASYNC since this can be sent from an atomic context */ + return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC, + sizeof(cmd), &cmd); +} + +struct iwl_bt_iterator_data { struct iwl_bt_coex_profile_notif *notif; + struct iwl_mvm *mvm; + u32 num_bss_ifaces; + bool reduced_tx_power; }; static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_bt_notif_iterator_data *data = _data; + struct iwl_bt_iterator_data *data = _data; + struct iwl_mvm *mvm = data->mvm; struct ieee80211_chanctx_conf *chanctx_conf; enum ieee80211_smps_mode smps_mode; enum ieee80211_band band; + int ave_rssi; if (vif->type != NL80211_IFTYPE_STATION) return; @@ -268,11 +362,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, band = -1; rcu_read_unlock(); - if (band != IEEE80211_BAND_2GHZ) - return; - smps_mode = IEEE80211_SMPS_AUTOMATIC; + if (band != IEEE80211_BAND_2GHZ) { + ieee80211_request_smps(vif, smps_mode); + return; + } + if (data->notif->bt_status) smps_mode = IEEE80211_SMPS_DYNAMIC; @@ -285,20 +381,88 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, data->notif->bt_traffic_load, smps_mode); ieee80211_request_smps(vif, smps_mode); + + /* don't reduce the Tx power if in loose scheme */ + if (is_loose_coex()) + return; + + data->num_bss_ifaces++; + + /* reduced Txpower only if there are open BT connections, so ...*/ + if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) { + /* ... cancel reduced Tx power ... */ + if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) + IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); + data->reduced_tx_power = false; + + /* ... and there is no need to get reports on RSSI any more. */ + ieee80211_disable_rssi_reports(vif); + return; + } + + ave_rssi = ieee80211_ave_rssi(vif); + + /* if the RSSI isn't valid, fake it is very low */ + if (!ave_rssi) + ave_rssi = -100; + if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) { + if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true)) + IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); + + /* + * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the + * BSS / P2P clients have rssi above threshold. + * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before + * the iteration, if one interface's rssi isn't good enough, + * bt_kill_msk will be set to default values. + */ + } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) { + if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) + IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); + + /* + * One interface hasn't rssi above threshold, bt_kill_msk must + * be set to default values. + */ + data->reduced_tx_power = false; + } + + /* Begin to monitor the RSSI: it may influence the reduced Tx power */ + ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD, + BT_ENABLE_REDUCED_TXPOWER_THRESHOLD); +} + +static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) +{ + struct iwl_bt_iterator_data data = { + .mvm = mvm, + .notif = &mvm->last_bt_notif, + .reduced_tx_power = true, + }; + + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_bt_notif_iterator, &data); + + /* + * If there are no BSS / P2P client interfaces, reduced Tx Power is + * irrelevant since it is based on the RSSI coming from the beacon. + * Use BT_KILL_MSK_DEFAULT in that case. + */ + data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; + + if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) + IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); } +/* upon association, the fw will send in BT Coex notification */ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *dev_cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; - struct iwl_bt_notif_iterator_data data = { - .mvm = mvm, - .notif = notif, - }; - struct iwl_bt_coex_cmd cmd = {}; - enum iwl_bt_kill_msk bt_kill_msk; + IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); 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, /* remember this notification for future use: rssi fluctuations */ memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_bt_notif_iterator, &data); + iwl_mvm_bt_coex_notif_handle(mvm); + + /* + * This is an async handler for a notification, returning anything other + * than 0 doesn't make sense even if HCMD failed. + */ + return 0; +} + +static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; + struct iwl_bt_iterator_data *data = _data; + struct iwl_mvm *mvm = data->mvm; + + struct ieee80211_sta *sta; + struct iwl_mvm_sta *mvmsta; + + if (vif->type != NL80211_IFTYPE_STATION || + mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) + return; + + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], + lockdep_is_held(&mvm->mutex)); + mvmsta = (void *)sta->drv_priv; + + /* + * This interface doesn't support reduced Tx power (because of low + * RSSI probably), then set bt_kill_msk to default values. + */ + if (!mvmsta->bt_reduced_txpower) + data->reduced_tx_power = false; + /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */ +} + +void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + enum ieee80211_rssi_event rssi_event) +{ + struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; + struct iwl_bt_iterator_data data = { + .mvm = mvm, + .reduced_tx_power = true, + }; + int ret; + + mutex_lock(&mvm->mutex); + + /* Rssi update while not associated ?! */ + if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) + goto out_unlock; - /* Low latency BT profile is active: give higher prio to BT */ - if (BT_MBOX_MSG(notif, 3, SCO_STATE) || - BT_MBOX_MSG(notif, 3, A2DP_STATE) || - BT_MBOX_MSG(notif, 3, SNIFF_STATE)) - bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; + /* No open connection - reports should be disabled */ + if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2)) + goto out_unlock; + + IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, + rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); + + /* + * Check if rssi is good enough for reduced Tx power, but not in loose + * scheme. + */ + if (rssi_event == RSSI_EVENT_LOW || is_loose_coex()) + ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, + false); else - bt_kill_msk = BT_KILL_MSK_DEFAULT; + ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true); - /* Don't send HCMD if there is no update */ - if (bt_kill_msk == mvm->bt_kill_msk) - return 0; + if (ret) + IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n"); - IWL_DEBUG_COEX(mvm, - "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n", - bt_kill_msk, - BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", - BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", - BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_bt_rssi_iterator, &data); - mvm->bt_kill_msk = bt_kill_msk; - cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); - cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); + /* + * If there are no BSS / P2P client interfaces, reduced Tx Power is + * irrelevant since it is based on the RSSI coming from the beacon. + * Use BT_KILL_MSK_DEFAULT in that case. + */ + data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; - cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); + if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) + IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); - if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) - IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); + out_unlock: + mutex_unlock(&mvm->mutex); +} - /* This handler is ASYNC */ - return 0; +void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct ieee80211_chanctx_conf *chanctx_conf; + enum ieee80211_band band; + + rcu_read_lock(); + chanctx_conf = rcu_dereference(vif->chanctx_conf); + if (chanctx_conf && chanctx_conf->def.chan) + band = chanctx_conf->def.chan->band; + else + band = -1; + rcu_read_unlock(); + + /* if we are in 2GHz we will get a notification from the fw */ + if (band == IEEE80211_BAND_2GHZ) + return; + + /* else, we can remove all the constraints */ + memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); + + iwl_mvm_bt_coex_notif_handle(mvm); } 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) struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; - struct iwl_d3_manager_config d3_cfg_cmd = {}; + struct iwl_d3_manager_config d3_cfg_cmd = { + /* + * Program the minimum sleep time to 10 seconds, as many + * platforms have issues processing a wakeup signal while + * still being in the process of suspending. + */ + .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), + }; struct wowlan_key_data key_data = { .use_rsc_tsc = false, .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, return count; } +static ssize_t iwl_dbgfs_mac_params_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_vif *vif = file->private_data; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm *mvm = mvmvif->dbgfs_data; + u8 ap_sta_id; + struct ieee80211_chanctx_conf *chanctx_conf; + char buf[512]; + int bufsz = sizeof(buf); + int pos = 0; + int i; + + mutex_lock(&mvm->mutex); + + ap_sta_id = mvmvif->ap_sta_id; + + pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n", + mvmvif->id, mvmvif->color); + pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n", + vif->bss_conf.bssid); + pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n"); + for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) { + pos += scnprintf(buf+pos, bufsz-pos, + "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n", + i, mvmvif->queue_params[i].txop, + mvmvif->queue_params[i].cw_min, + mvmvif->queue_params[i].cw_max, + mvmvif->queue_params[i].aifs, + mvmvif->queue_params[i].uapsd); + } + + if (vif->type == NL80211_IFTYPE_STATION && + ap_sta_id != IWL_MVM_STATION_COUNT) { + struct ieee80211_sta *sta; + struct iwl_mvm_sta *mvm_sta; + + sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id], + lockdep_is_held(&mvm->mutex)); + mvm_sta = (void *)sta->drv_priv; + pos += scnprintf(buf+pos, bufsz-pos, + "ap_sta_id %d - reduced Tx power %d\n", + ap_sta_id, mvm_sta->bt_reduced_txpower); + } + + rcu_read_lock(); + chanctx_conf = rcu_dereference(vif->chanctx_conf); + if (chanctx_conf) { + pos += scnprintf(buf+pos, bufsz-pos, + "idle rx chains %d, active rx chains: %d\n", + chanctx_conf->rx_chains_static, + chanctx_conf->rx_chains_dynamic); + } + rcu_read_unlock(); + + mutex_unlock(&mvm->mutex); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + #define BT_MBOX_MSG(_notif, _num, _field) \ ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ >> BT_MBOX##_num##_##_field##_POS) @@ -464,6 +525,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); +/* Interface specific debugfs entries */ +MVM_DEBUGFS_READ_FILE_OPS(mac_params); + int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) { char buf[100]; @@ -494,3 +558,58 @@ err: IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); return -ENOMEM; } + +void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct dentry *dbgfs_dir = vif->debugfs_dir; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + char buf[100]; + + if (!dbgfs_dir) + return; + + mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); + mvmvif->dbgfs_data = mvm; + + if (!mvmvif->dbgfs_dir) { + IWL_ERR(mvm, "Failed to create debugfs directory under %s\n", + dbgfs_dir->d_name.name); + return; + } + + MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, + S_IRUSR); + + /* + * Create symlink for convenience pointing to interface specific + * debugfs entries for the driver. For example, under + * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/ + * find + * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/ + */ + snprintf(buf, 100, "../../../%s/%s/%s/%s", + dbgfs_dir->d_parent->d_parent->d_name.name, + dbgfs_dir->d_parent->d_name.name, + dbgfs_dir->d_name.name, + mvmvif->dbgfs_dir->d_name.name); + + mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name, + mvm->debugfs_dir, buf); + if (!mvmvif->dbgfs_slink) + IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n", + dbgfs_dir->d_name.name); + return; +err: + IWL_ERR(mvm, "Can't create debugfs entity\n"); +} + +void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + debugfs_remove(mvmvif->dbgfs_slink); + mvmvif->dbgfs_slink = NULL; + + debugfs_remove_recursive(mvmvif->dbgfs_dir); + mvmvif->dbgfs_dir = NULL; +} 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 @@ /** * enum iwl_scan_flags - masks for power table command flags + * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off + * receiver and transmitter. '0' - does not allow. * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, * '1' Driver enables PM (use rest of parameters) - * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, + * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, * '1' PM could sleep over DTIM till listen Interval. - * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. - * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all - * access categories are both delivery and trigger enabled. - * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and - * PBW Snoozing enabled * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask + * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. */ enum iwl_power_flags { - POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0), - POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1), - POWER_FLAGS_LPRX_ENA_MSK = BIT(2), - POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3), - POWER_FLAGS_BT_SCO_ENA = BIT(4), - POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5) + POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), + POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1), + POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2), + POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), + POWER_FLAGS_LPRX_ENA_MSK = BIT(11), }; +#define IWL_POWER_VEC_SIZE 5 + /** * struct iwl_powertable_cmd - Power Table Command * POWER_TABLE_CMD = 0x77 (command, has simple generic response) * - * @id_and_color: MAC contex identifier - * @action: Action on context - no action, add new, - * modify existent, remove * @flags: Power table command flags from POWER_FLAGS_* * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. - * Minimum allowed:- 3 * DTIM + * Minimum allowed:- 3 * DTIM. Keep alive period must be + * set regardless of power scheme or current power state. + * FW use this value also when PM is disabled. * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to * PSM transition - legacy PM * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to * PSM transition - legacy PM - * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to - * PSM transition - uAPSD - * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to - * PSM transition - uAPSD + * @sleep_interval: not in use + * @keep_alive_beacons: not in use * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. * Default: 80dbm - * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set - * @snooze_interval: TBD - * @snooze_window: TBD - * @snooze_step: TBD - * @qndp_tid: TBD - * @uapsd_ac_flags: TBD - * @uapsd_max_sp: TBD */ struct iwl_powertable_cmd { - /* COMMON_INDEX_HDR_API_S_VER_1 */ - __le32 id_and_color; - __le32 action; + /* PM_POWER_TABLE_CMD_API_S_VER_5 */ __le16 flags; - u8 reserved; - __le16 keep_alive_seconds; + u8 keep_alive_seconds; + u8 debug_flags; __le32 rx_data_timeout; __le32 tx_data_timeout; - __le32 rx_data_timeout_uapsd; - __le32 tx_data_timeout_uapsd; - u8 lprx_rssi_threshold; - u8 num_skip_dtim; - __le16 snooze_interval; - __le16 snooze_window; - u8 snooze_step; - u8 qndp_tid; - u8 uapsd_ac_flags; - u8 uapsd_max_sp; + __le32 sleep_interval[IWL_POWER_VEC_SIZE]; + __le32 keep_alive_beacons; + __le32 lprx_rssi_threshold; } __packed; #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 { TE_DEP_TSF = 2, TE_EVENT_SOCIOPATHIC = 4, }; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ - -/* When to send Time Event notifications and to whom (internal = FW) */ +/* + * Supported Time event notifications configuration. + * A notification (both event and fragment) includes a status indicating weather + * the FW was able to schedule the event or not. For fragment start/end + * notification the status is always success. There is no start/end fragment + * notification for monolithic events. + * + * @TE_NOTIF_NONE: no notifications + * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start + * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end + * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use + * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use. + * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start + * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end + * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use. + * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use. + */ enum { TE_NOTIF_NONE = 0, - TE_NOTIF_HOST_START = 0x1, - TE_NOTIF_HOST_END = 0x2, - TE_NOTIF_INTERNAL_START = 0x4, - TE_NOTIF_INTERNAL_END = 0x8 -}; /* MAC_EVENT_ACTION_API_E_VER_1 */ + TE_NOTIF_HOST_EVENT_START = 0x1, + TE_NOTIF_HOST_EVENT_END = 0x2, + TE_NOTIF_INTERNAL_EVENT_START = 0x4, + TE_NOTIF_INTERNAL_EVENT_END = 0x8, + TE_NOTIF_HOST_FRAG_START = 0x10, + TE_NOTIF_HOST_FRAG_END = 0x20, + TE_NOTIF_INTERNAL_FRAG_START = 0x40, + TE_NOTIF_INTERNAL_FRAG_END = 0x80 +}; /* MAC_EVENT_ACTION_API_E_VER_2 */ /* * @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, u32 action) { struct iwl_mac_ctx_cmd cmd = {}; + struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr; WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p); @@ -678,7 +679,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm, /* Fill the data specific for station mode */ iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); - cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); + cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & + IEEE80211_P2P_OPPPS_CTWINDOW_MASK); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } @@ -919,6 +921,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, u32 action) { struct iwl_mac_ctx_cmd cmd = {}; + struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr; WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); @@ -929,8 +932,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, action == FW_CTXT_ACTION_ADD); - cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); - cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); + cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow & + IEEE80211_P2P_OPPPS_CTWINDOW_MASK); + cmd.go.opp_ps_enabled = + cpu_to_le32(!!(noa->oppps_ctwindow & + IEEE80211_P2P_OPPPS_ENABLE_BIT)); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } 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, /* * TODO: remove this temporary code. * Currently MVM FW supports power management only on single MAC. - * Iterate and disable PM on all active interfaces. + * If new interface added, disable PM on existing interface. + * P2P device is a special case, since it is handled by FW similary to + * scan. If P2P deviced is added, PM remains enabled on existing + * interface. * Note: the method below does not count the new interface being added * at this moment. */ - mvm->vif_count++; + if (vif->type != NL80211_IFTYPE_P2P_DEVICE) + mvm->vif_count++; if (mvm->vif_count > 1) { IWL_DEBUG_MAC80211(mvm, "Disable power on existing interfaces\n"); @@ -562,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, mvm->p2p_device_vif = vif; } + iwl_mvm_vif_dbgfs_register(mvm, vif); goto out_unlock; out_unbind: @@ -575,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, /* * TODO: remove this temporary code. * Currently MVM FW supports power management only on single MAC. - * Check if only one additional interface remains after rereasing + * Check if only one additional interface remains after releasing * current one. Update power mode on the remaining interface. */ - mvm->vif_count--; + if (vif->type != NL80211_IFTYPE_P2P_DEVICE) + mvm->vif_count--; IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", mvm->vif_count); if (mvm->vif_count == 1) { @@ -640,6 +646,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + iwl_mvm_vif_dbgfs_clean(mvm, vif); + /* * For AP/GO interface, the tear down of the resources allocated to the * 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, * Check if only one additional interface remains after removing * current one. Update power mode on the remaining interface. */ - if (mvm->vif_count) + if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) mvm->vif_count--; IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", mvm->vif_count); @@ -713,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, IWL_ERR(mvm, "failed to update quotas\n"); return; } + iwl_mvm_bt_coex_vif_assoc(mvm, vif); } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { /* remove AP station now that the MAC is unassoc */ 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, */ break; case STA_NOTIFY_AWAKE: - if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) + if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) break; iwl_mvm_sta_modify_ps_wake(mvm, sta); break; @@ -1326,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw, return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); } +static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_rssi_event rssi_event) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + + iwl_mvm_bt_rssi_event(mvm, vif, rssi_event); +} + struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, .ampdu_action = iwl_mvm_mac_ampdu_action, @@ -1349,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = { .update_tkip_key = iwl_mvm_mac_update_tkip_key, .remain_on_channel = iwl_mvm_roc, .cancel_remain_on_channel = iwl_mvm_cancel_roc, + .rssi_callback = iwl_mvm_mac_rssi_callback, .add_chanctx = iwl_mvm_add_chanctx, .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 { #ifdef CONFIG_IWLWIFI_DEBUGFS struct dentry *dbgfs_dir; + struct dentry *dbgfs_slink; void *dbgfs_data; #endif }; @@ -321,6 +322,13 @@ struct iwl_mvm { * can hold 16 keys at most. Reflect this fact. */ unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; + + /* + * This counter of created interfaces is referenced only in conjunction + * with FW limitation related to power management. Currently PM is + * supported only on a single interface. + * IMPORTANT: this variable counts all interfaces except P2P device. + */ u8 vif_count; struct led_classdev led; @@ -471,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); /* MVM debugfs */ #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); -int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct dentry *dbgfs_dir); -void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_powertable_cmd *cmd); +void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #else static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) { return 0; } +static inline void +iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ +} +static inline void +iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ +} #endif /* CONFIG_IWLWIFI_DEBUGFS */ /* rate scaling */ @@ -490,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, /* power managment */ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct iwl_powertable_cmd *cmd); int iwl_mvm_leds_init(struct iwl_mvm *mvm); void iwl_mvm_leds_exit(struct iwl_mvm *mvm); @@ -513,5 +529,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm); int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); +void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + enum ieee80211_rssi_event rssi_event); +void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #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 @@ #define POWER_KEEP_ALIVE_PERIOD_SEC 25 -static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_powertable_cmd *cmd) +static void iwl_mvm_power_log(struct iwl_mvm *mvm, + struct iwl_powertable_cmd *cmd) +{ + IWL_DEBUG_POWER(mvm, + "Sending power table command for power level %d, flags = 0x%X\n", + iwlmvm_mod_params.power_scheme, + le16_to_cpu(cmd->flags)); + IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds); + + if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { + IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", + le32_to_cpu(cmd->rx_data_timeout)); + IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", + le32_to_cpu(cmd->tx_data_timeout)); + IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", + cmd->lprx_rssi_threshold); + } +} + +void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct iwl_powertable_cmd *cmd) { struct ieee80211_hw *hw = mvm->hw; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; int dtimper, dtimper_msec; int keep_alive; bool radar_detect = false; - cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, - mvmvif->color)); - cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); + /* + * Regardless of power management state the driver must set + * keep alive period. FW will use it for sending keep alive NDPs + * immediately after association. + */ + cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; + + if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) || + !iwlwifi_mod_params.power_save) + return; + + cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); - if ((!vif->bss_conf.ps) || - (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)) + if (!vif->bss_conf.ps) return; 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, /* Check skip over DTIM conditions */ if (!radar_detect && (dtimper <= 10) && - (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { - cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); - cmd->num_skip_dtim = 2; - } + (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) + cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); /* Check that keep alive period is at least 3 * DTIM */ dtimper_msec = dtimper * vif->bss_conf.beacon_int; keep_alive = max_t(int, 3 * dtimper_msec, - MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); + MSEC_PER_SEC * cmd->keep_alive_seconds); keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); - - cmd->keep_alive_seconds = cpu_to_le16(keep_alive); + cmd->keep_alive_seconds = keep_alive; if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { /* TODO: Also for D3 (device sleep / WoWLAN) */ - cmd->rx_data_timeout = cpu_to_le32(10); - cmd->tx_data_timeout = cpu_to_le32(10); + cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); + cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); } else { - cmd->rx_data_timeout = cpu_to_le32(50); - cmd->tx_data_timeout = cpu_to_le32(50); + cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); + cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); } } @@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_powertable_cmd cmd = {}; - if (!iwlwifi_mod_params.power_save) { - IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); - return 0; - } - if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - iwl_power_build_cmd(mvm, vif, &cmd); - - IWL_DEBUG_POWER(mvm, - "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", - cmd.id_and_color, iwlmvm_mod_params.power_scheme, - le16_to_cpu(cmd.flags)); - - if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { - IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", - le16_to_cpu(cmd.keep_alive_seconds)); - IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", - le32_to_cpu(cmd.rx_data_timeout)); - IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", - le32_to_cpu(cmd.tx_data_timeout)); - IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n", - le32_to_cpu(cmd.rx_data_timeout_uapsd)); - IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", - le32_to_cpu(cmd.tx_data_timeout_uapsd)); - IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", - cmd.lprx_rssi_threshold); - IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim); - } + iwl_mvm_power_build_cmd(mvm, vif, &cmd); + iwl_mvm_power_log(mvm, &cmd); return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, sizeof(cmd), &cmd); @@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_powertable_cmd cmd = {}; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - - if (!iwlwifi_mod_params.power_save) { - IWL_DEBUG_POWER(mvm, "Power management is not allowed\n"); - return 0; - } if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, - mvmvif->color)); - cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); + if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) && + iwlwifi_mod_params.power_save) + cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); - IWL_DEBUG_POWER(mvm, - "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n", - cmd.id_and_color, iwlmvm_mod_params.power_scheme, - le16_to_cpu(cmd.flags)); + iwl_mvm_power_log(mvm, &cmd); return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, sizeof(cmd), &cmd); } - -#ifdef CONFIG_IWLWIFI_DEBUGFS -void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_powertable_cmd *cmd) -{ - iwl_power_build_cmd(mvm, vif, cmd); -} -#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, if (num_of_ant(tbl->ant_type) > 1) tbl->ant_type = - first_antenna(mvm->nvm_data->valid_tx_ant); + first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); tbl->is_ht40 = 0; tbl->is_SGI = 0; @@ -1235,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, return -1; /* Need both Tx chains/antennas to support MIMO */ - if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2) + if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2) return -1; 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, return -1; /* Need both Tx chains/antennas to support MIMO */ - if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3) + if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3) return -1; 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, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; + u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); u8 tx_chains_num = num_of_ant(valid_tx_ant); int ret; u8 update_search_tbl_counter = 0; @@ -1514,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; + u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); u8 tx_chains_num = num_of_ant(valid_tx_ant); u8 update_search_tbl_counter = 0; int ret; @@ -1649,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; + u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); u8 tx_chains_num = num_of_ant(valid_tx_ant); u8 update_search_tbl_counter = 0; int ret; @@ -1786,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm, u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; - u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; + u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); u8 tx_chains_num = num_of_ant(valid_tx_ant); int ret; u8 update_search_tbl_counter = 0; @@ -2449,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, i = lq_sta->last_txrate_idx; - valid_tx_ant = mvm->nvm_data->valid_tx_ant; + valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); if (!lq_sta->search_better_tbl) active_tbl = lq_sta->active_tbl; @@ -2639,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, /* These values will be overridden later */ lq_sta->lq.single_stream_ant_msk = - first_antenna(mvm->nvm_data->valid_tx_ant); + first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); lq_sta->lq.dual_stream_ant_msk = - mvm->nvm_data->valid_tx_ant & - ~first_antenna(mvm->nvm_data->valid_tx_ant); + iwl_fw_valid_tx_ant(mvm->fw) & + ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); if (!lq_sta->lq.dual_stream_ant_msk) { lq_sta->lq.dual_stream_ant_msk = ANT_AB; - } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) { + } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) { lq_sta->lq.dual_stream_ant_msk = - mvm->nvm_data->valid_tx_ant; + iwl_fw_valid_tx_ant(mvm->fw); } /* as default allow aggregation for all tids */ @@ -2708,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, index++; repeat_rate--; if (mvm) - valid_tx_ant = mvm->nvm_data->valid_tx_ant; + valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); /* Fill rest of rate table */ while (index < LINK_QUAL_MAX_RETRY_NUM) { @@ -2813,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, u8 ant_sel_tx; mvm = lq_sta->drv; - valid_tx_ant = mvm->nvm_data->valid_tx_ant; + valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); if (lq_sta->dbg_fixed_rate) { ant_sel_tx = ((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, desc += sprintf(buff+desc, "fixed rate 0x%X\n", lq_sta->dbg_fixed_rate); desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", - (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", - (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", - (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); + (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "", + (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", + (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); desc += sprintf(buff+desc, "lq type %s\n", (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 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, mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) return mvmvif->ap_sta_id; - return IWL_INVALID_STATION; + return IWL_MVM_STATION_COUNT; } 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, /* Get the station id from the mvm local station table */ sta_id = iwl_mvm_get_key_sta_id(vif, sta); - if (sta_id == IWL_INVALID_STATION) { + if (sta_id == IWL_MVM_STATION_COUNT) { IWL_ERR(mvm, "Failed to find station id\n"); return -EINVAL; } @@ -1188,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, return -ENOENT; } - if (sta_id == IWL_INVALID_STATION) { + if (sta_id == IWL_MVM_STATION_COUNT) { IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); return 0; } @@ -1254,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvm_sta; u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); - if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) + if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) return; 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 { * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for * tid. * @max_agg_bufsize: the maximal size of the AGG buffer for this station + * @bt_reduced_txpower: is reduced tx power enabled for this station * @lock: lock to protect the whole struct. Since %tid_data is access from Tx * and from Tx response flow, it needs a spinlock. * @pending_frames: number of frames for this STA on the shared Tx queues. @@ -287,6 +288,7 @@ struct iwl_mvm_sta { u32 mac_id_n_color; u16 tid_disable_agg; u8 max_agg_bufsize; + bool bt_reduced_txpower; spinlock_t lock; atomic_t pending_frames; 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, WARN_ONCE(!le32_to_cpu(notif->status), "Failed to schedule time event\n"); - if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) { + if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { IWL_DEBUG_TE(mvm, "TE ended - current time %lu, estimated end %lu\n", jiffies, te_data->end_jiffies); @@ -189,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, } iwl_mvm_te_clear_data(mvm, te_data); - } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { + } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { te_data->running = true; te_data->end_jiffies = jiffies + TU_TO_JIFFIES(te_data->duration); @@ -368,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); time_cmd.duration = cpu_to_le32(duration); time_cmd.repeat = cpu_to_le32(1); - time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); + time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | + TE_NOTIF_HOST_EVENT_END); iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); } @@ -485,7 +486,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); time_cmd.repeat = cpu_to_le32(1); - time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); + time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | + TE_NOTIF_HOST_EVENT_END); return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); } 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, rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); mvm->mgmt_last_antenna_idx = - iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, + iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw), mvm->mgmt_last_antenna_idx); rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; @@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, if (WARN_ON_ONCE(!mvmsta)) return -1; - if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION)) + if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) return -1; 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, } IWL_DEBUG_TX_REPLY(mvm, - "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x " - "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", - txq_id, iwl_mvm_get_tx_fail_reason(status), - status, le32_to_cpu(tx_resp->initial_rate), + "TXQ %d status %s (0x%08x)\n", + txq_id, iwl_mvm_get_tx_fail_reason(status), status); + + IWL_DEBUG_TX_REPLY(mvm, + "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", + le32_to_cpu(tx_resp->initial_rate), tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn, next_reclaimed, seq_ctl); 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, .data = { lq, }, }; - if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) + if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT)) return -EINVAL; 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) = { {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, /* 105 Series */ {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, iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); /* If this queue is mapped to a certain station: it is an AGG queue */ - if (sta_id != IWL_INVALID_STATION) { + if (sta_id >= 0) { u16 ra_tid = BUILD_RAxTID(sta_id, tid); /* 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) struct ieee80211_conf *conf = &hw->conf; lbtf_deb_enter(LBTF_DEB_MACOPS); - if (conf->channel->center_freq != priv->cur_freq) { - priv->cur_freq = conf->channel->center_freq; - lbtf_set_channel(priv, conf->channel->hw_value); + if (conf->chandef.chan->center_freq != priv->cur_freq) { + priv->cur_freq = conf->chandef.chan->center_freq; + lbtf_set_channel(priv, conf->chandef.chan->hw_value); } lbtf_deb_leave(LBTF_DEB_MACOPS); return 0; @@ -537,7 +537,7 @@ static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = priv->noise; 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 @@ #include <linux/if_arp.h> #include <linux/rtnetlink.h> #include <linux/etherdevice.h> +#include <linux/platform_device.h> #include <linux/debugfs.h> #include <linux/module.h> #include <linux/ktime.h> @@ -52,6 +53,10 @@ static bool paged_rx = false; module_param(paged_rx, bool, 0644); MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones"); +static bool rctbl = false; +module_param(rctbl, bool, 0444); +MODULE_PARM_DESC(rctbl, "Handle rate control table"); + /** * enum hwsim_regtest - the type of regulatory tests we offer * @@ -717,9 +722,17 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, rx_status.flag |= RX_FLAG_MACTIME_START; rx_status.freq = chan->center_freq; rx_status.band = chan->band; - rx_status.rate_idx = info->control.rates[0].idx; - if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) - rx_status.flag |= RX_FLAG_HT; + if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) { + rx_status.rate_idx = + ieee80211_rate_get_vht_mcs(&info->control.rates[0]); + rx_status.vht_nss = + ieee80211_rate_get_vht_nss(&info->control.rates[0]); + rx_status.flag |= RX_FLAG_VHT; + } else { + rx_status.rate_idx = info->control.rates[0].idx; + if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) + rx_status.flag |= RX_FLAG_HT; + } if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) rx_status.flag |= RX_FLAG_40MHZ; if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI) @@ -886,8 +899,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, if (control->sta) hwsim_check_sta_magic(control->sta); - txi->rate_driver_data[0] = channel; + if (rctbl) + ieee80211_get_tx_rates(txi->control.vif, control->sta, skb, + txi->control.rates, + ARRAY_SIZE(txi->control.rates)); + txi->rate_driver_data[0] = channel; mac80211_hwsim_monitor_rx(hw, skb, channel); /* wmediumd mode check */ @@ -989,6 +1006,13 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, { u32 _pid = ACCESS_ONCE(wmediumd_portid); + if (rctbl) { + struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); + ieee80211_get_tx_rates(txi->control.vif, NULL, skb, + txi->control.rates, + ARRAY_SIZE(txi->control.rates)); + } + mac80211_hwsim_monitor_rx(hw, skb, chan); if (_pid) @@ -1019,6 +1043,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, if (skb == NULL) return; info = IEEE80211_SKB_CB(skb); + if (rctbl) + ieee80211_get_tx_rates(vif, NULL, skb, + info->control.rates, + ARRAY_SIZE(info->control.rates)); + txrate = ieee80211_get_tx_rate(hw, info); mgmt = (struct ieee80211_mgmt *) skb->data; @@ -1062,11 +1091,13 @@ out: return HRTIMER_NORESTART; } -static const char *hwsim_chantypes[] = { - [NL80211_CHAN_NO_HT] = "noht", - [NL80211_CHAN_HT20] = "ht20", - [NL80211_CHAN_HT40MINUS] = "ht40-", - [NL80211_CHAN_HT40PLUS] = "ht40+", +static const char * const hwsim_chanwidths[] = { + [NL80211_CHAN_WIDTH_20_NOHT] = "noht", + [NL80211_CHAN_WIDTH_20] = "ht20", + [NL80211_CHAN_WIDTH_40] = "ht40", + [NL80211_CHAN_WIDTH_80] = "vht80", + [NL80211_CHAN_WIDTH_80P80] = "vht80p80", + [NL80211_CHAN_WIDTH_160] = "vht160", }; 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) [IEEE80211_SMPS_DYNAMIC] = "dynamic", }; - wiphy_debug(hw->wiphy, - "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", - __func__, - conf->channel ? conf->channel->center_freq : 0, - hwsim_chantypes[conf->channel_type], - !!(conf->flags & IEEE80211_CONF_IDLE), - !!(conf->flags & IEEE80211_CONF_PS), - smps_modes[conf->smps_mode]); + if (conf->chandef.chan) + wiphy_debug(hw->wiphy, + "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n", + __func__, + conf->chandef.chan->center_freq, + conf->chandef.center_freq1, + conf->chandef.center_freq2, + hwsim_chanwidths[conf->chandef.width], + !!(conf->flags & IEEE80211_CONF_IDLE), + !!(conf->flags & IEEE80211_CONF_PS), + smps_modes[conf->smps_mode]); + else + wiphy_debug(hw->wiphy, + "%s (freq=0 idle=%d ps=%d smps=%s)\n", + __func__, + !!(conf->flags & IEEE80211_CONF_IDLE), + !!(conf->flags & IEEE80211_CONF_PS), + smps_modes[conf->smps_mode]); data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); - data->channel = conf->channel; + data->channel = conf->chandef.chan; WARN_ON(data->channel && channels > 1); @@ -1277,7 +1318,7 @@ static int mac80211_hwsim_get_survey( return -ENOENT; /* Current channel */ - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; /* * Magically conjured noise level --- this is only ok for simulated hardware. @@ -1675,6 +1716,7 @@ static void mac80211_hwsim_free(void) debugfs_remove(data->debugfs_ps); debugfs_remove(data->debugfs); ieee80211_unregister_hw(data->hw); + device_release_driver(data->dev); device_unregister(data->dev); ieee80211_free_hw(data->hw); } @@ -1683,7 +1725,9 @@ static void mac80211_hwsim_free(void) static struct device_driver mac80211_hwsim_driver = { - .name = "mac80211_hwsim" + .name = "mac80211_hwsim", + .bus = &platform_bus_type, + .owner = THIS_MODULE, }; static const struct net_device_ops hwsim_netdev_ops = { @@ -2175,9 +2219,15 @@ static int __init init_mac80211_hwsim(void) spin_lock_init(&hwsim_radio_lock); INIT_LIST_HEAD(&hwsim_radios); + err = driver_register(&mac80211_hwsim_driver); + if (err) + return err; + hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); - if (IS_ERR(hwsim_class)) - return PTR_ERR(hwsim_class); + if (IS_ERR(hwsim_class)) { + err = PTR_ERR(hwsim_class); + goto failed_unregister_driver; + } memset(addr, 0, ETH_ALEN); addr[0] = 0x02; @@ -2199,12 +2249,20 @@ static int __init init_mac80211_hwsim(void) "hwsim%d", i); if (IS_ERR(data->dev)) { printk(KERN_DEBUG - "mac80211_hwsim: device_create " - "failed (%ld)\n", PTR_ERR(data->dev)); + "mac80211_hwsim: device_create failed (%ld)\n", + PTR_ERR(data->dev)); err = -ENOMEM; goto failed_drvdata; } data->dev->driver = &mac80211_hwsim_driver; + err = device_bind_driver(data->dev); + if (err != 0) { + printk(KERN_DEBUG + "mac80211_hwsim: device_bind_driver failed (%d)\n", + err); + goto failed_hw; + } + skb_queue_head_init(&data->pending); SET_IEEE80211_DEV(hw, data->dev); @@ -2247,6 +2305,8 @@ static int __init init_mac80211_hwsim(void) IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_WANT_MONITOR_VIF | IEEE80211_HW_QUEUE_CONTROL; + if (rctbl) + hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; @@ -2298,9 +2358,6 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->bands[band] = sband; - if (channels == 1) - continue; - sband->vht_cap.vht_supported = true; sband->vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | @@ -2506,6 +2563,8 @@ failed_drvdata: ieee80211_free_hw(hw); failed: mac80211_hwsim_free(); +failed_unregister_driver: + driver_unregister(&mac80211_hwsim_driver); return err; } module_init(init_mac80211_hwsim); @@ -2518,5 +2577,6 @@ static void __exit exit_mac80211_hwsim(void) mac80211_hwsim_free(); unregister_netdev(hwsim_mon); + driver_unregister(&mac80211_hwsim_driver); } 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, /* VHT Operation IE */ if (bss_desc->bcn_vht_oper) { - if (priv->bss_mode == HostCmd_BSS_MODE_IBSS) { + if (priv->bss_mode == NL80211_IFTYPE_STATION) { vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer; memset(vht_op, 0, sizeof(*vht_op)); 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, break; } if (ret != -EBUSY) { - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); - if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { - priv->wmm.packets_out[ptrindex]++; - priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list; - } - /* Now bss_prio_cur pointer points to next node */ - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - list_first_entry( - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_cur->list, - struct mwifiex_bss_prio_node, list); - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, - ra_list_flags); + mwifiex_rotate_priolists(priv, pra_list, ptrindex); } 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, end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); del_timer(&tbl->timer_context.timer); mod_timer(&tbl->timer_context.timer, - jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); + jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size)); /* * 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, struct cfg80211_connect_params *sme) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - int ret = 0; - - if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { - wiphy_err(wiphy, "received infra assoc request " - "when station is in ibss mode\n"); - goto done; - } + int ret; - if (priv->bss_mode == NL80211_IFTYPE_AP) { - wiphy_err(wiphy, "skip association request for AP interface\n"); - goto done; + if (priv->bss_mode != NL80211_IFTYPE_STATION) { + wiphy_err(wiphy, + "%s: reject infra assoc request in non-STA mode\n", + dev->name); + return -EINVAL; } 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, ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, priv->bss_mode, sme->channel, sme, 0); -done: if (!ret) { cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, NULL, 0, WLAN_STATUS_SUCCESS, @@ -2136,10 +2131,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* At start-up, wpa_supplicant tries to change the interface * to NL80211_IFTYPE_STATION if it is not managed mode. - * So, we initialize it to STA mode. */ - wdev->iftype = NL80211_IFTYPE_STATION; - priv->bss_mode = NL80211_IFTYPE_STATION; + wdev->iftype = NL80211_IFTYPE_P2P_CLIENT; + priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT; /* Setting bss_type to P2P tells firmware that this interface * is receiving P2P peers found during find phase and doing @@ -2153,6 +2147,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_started = 0; priv->bss_num = 0; + if (mwifiex_cfg80211_init_p2p_client(priv)) + return ERR_PTR(-EFAULT); + break; default: 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, /* Setup the timer after transmit command */ mod_timer(&adapter->cmd_timer, - jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); + jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); return 0; } 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) bss_prio->priv = priv; INIT_LIST_HEAD(&bss_prio->list); - if (!tbl[priv->bss_priority].bss_prio_cur) - tbl[priv->bss_priority].bss_prio_cur = bss_prio; spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); 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) for (i = 0; i < adapter->priv_num; ++i) { INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); - adapter->bss_prio_tbl[i].bss_prio_cur = NULL; spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); } @@ -625,42 +622,36 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) { int i; struct mwifiex_adapter *adapter = priv->adapter; - struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; + struct mwifiex_bss_prio_node *bssprio_node, *tmp_node; struct list_head *head; spinlock_t *lock; /* bss priority lock */ unsigned long flags; for (i = 0; i < adapter->priv_num; ++i) { head = &adapter->bss_prio_tbl[i].bss_prio_head; - cur = &adapter->bss_prio_tbl[i].bss_prio_cur; lock = &adapter->bss_prio_tbl[i].bss_prio_lock; dev_dbg(adapter->dev, "info: delete BSS priority table," " bss_type = %d, bss_num = %d, i = %d," - " head = %p, cur = %p\n", - priv->bss_type, priv->bss_num, i, head, *cur); - if (*cur) { + " head = %p\n", + priv->bss_type, priv->bss_num, i, head); + + { spin_lock_irqsave(lock, flags); if (list_empty(head)) { spin_unlock_irqrestore(lock, flags); continue; } - bssprio_node = list_first_entry(head, - struct mwifiex_bss_prio_node, list); - spin_unlock_irqrestore(lock, flags); - list_for_each_entry_safe(bssprio_node, tmp_node, head, list) { if (bssprio_node->priv == priv) { dev_dbg(adapter->dev, "info: Delete " "node %p, next = %p\n", bssprio_node, tmp_node); - spin_lock_irqsave(lock, flags); list_del(&bssprio_node->list); - spin_unlock_irqrestore(lock, flags); kfree(bssprio_node); } } - *cur = (struct mwifiex_bss_prio_node *)head; + spin_unlock_irqrestore(lock, flags); } } } 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 { struct mwifiex_tid_tbl { struct list_head ra_list; - struct mwifiex_ra_list_tbl *ra_list_curr; }; #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) if (card->rx_buf_list[i]) { skb = card->rx_buf_list[i]; pci_unmap_single(card->dev, desc2->paddr, - skb->len, PCI_DMA_TODEVICE); + skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); } memset(desc2, 0, sizeof(*desc2)); @@ -581,7 +581,7 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) if (card->rx_buf_list[i]) { skb = card->rx_buf_list[i]; pci_unmap_single(card->dev, desc->paddr, - skb->len, PCI_DMA_TODEVICE); + skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); } 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, if (ret) goto done; - /* Update current bss descriptor parameters */ spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); - priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL; - priv->curr_bss_params.bss_descriptor.wpa_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL; - priv->curr_bss_params.bss_descriptor.rsn_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL; - priv->curr_bss_params.bss_descriptor.wapi_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL; - priv->curr_bss_params.bss_descriptor.ht_cap_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_ht_oper = NULL; - priv->curr_bss_params.bss_descriptor.ht_info_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = NULL; - priv->curr_bss_params.bss_descriptor.bss_co_2040_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL; - priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0; - priv->curr_bss_params.bss_descriptor.beacon_buf = NULL; - priv->curr_bss_params.bss_descriptor.beacon_buf_size = 0; - priv->curr_bss_params.bss_descriptor.bcn_vht_cap = NULL; - priv->curr_bss_params.bss_descriptor.vht_cap_offset = 0; - priv->curr_bss_params.bss_descriptor.bcn_vht_oper = NULL; - priv->curr_bss_params.bss_descriptor.vht_info_offset = 0; - priv->curr_bss_params.bss_descriptor.oper_mode = NULL; - priv->curr_bss_params.bss_descriptor.oper_mode_offset = 0; - - /* Disable 11ac by default. Enable it only where there - * exist VHT_CAP IE in AP beacon - */ - priv->curr_bss_params.bss_descriptor.disable_11ac = true; - /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, sizeof(priv->curr_bss_params.bss_descriptor)); + + /* The contents of beacon_ie will be copied to its own buffer + * in mwifiex_save_curr_bcn() + */ mwifiex_save_curr_bcn(priv); spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); done: + /* beacon_ie buffer was allocated in function + * mwifiex_fill_new_bss_desc(). Free it now. + */ + kfree(bss_desc->beacon_buf); kfree(bss_desc); return 0; } 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, /* * This function fills bss descriptor structure using provided * information. + * beacon_ie buffer is allocated in this function. It is caller's + * responsibility to free the memory. */ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, struct cfg80211_bss *bss, struct mwifiex_bssdescriptor *bss_desc) { - int ret; u8 *beacon_ie; size_t beacon_ie_len; struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; @@ -165,6 +166,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); bss_desc->rssi = bss->signal; + /* The caller of this function will free beacon_ie */ bss_desc->beacon_buf = beacon_ie; bss_desc->beacon_buf_size = beacon_ie_len; bss_desc->beacon_period = bss->beacon_interval; @@ -182,10 +184,12 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, else bss_desc->bss_mode = NL80211_IFTYPE_STATION; - ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); + /* Disable 11ac by default. Enable it only where there + * exist VHT_CAP IE in AP beacon + */ + bss_desc->disable_11ac = true; - kfree(beacon_ie); - return ret; + return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); } 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, } done: + /* beacon_ie buffer was allocated in function + * mwifiex_fill_new_bss_desc(). Free it now. + */ + if (bss_desc) + kfree(bss_desc->beacon_buf); kfree(bss_desc); return ret; } 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) } list_add_tail(&ra_list->list, &priv->wmm.tid_tbl_ptr[i].ra_list); - - if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) - priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; } } @@ -424,7 +421,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; - priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; } priv->aggr_prio_tbl[6].amsdu @@ -530,8 +526,6 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) } INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); - - priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; } } @@ -883,38 +877,26 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_private **priv, int *tid) { struct mwifiex_private *priv_tmp; - struct mwifiex_ra_list_tbl *ptr, *head; - struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; + struct mwifiex_ra_list_tbl *ptr; struct mwifiex_tid_tbl *tid_ptr; atomic_t *hqp; unsigned long flags_bss, flags_ra; int i, j; + /* check the BSS with highest priority first */ for (j = adapter->priv_num - 1; j >= 0; --j) { spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, flags_bss); - if (list_empty(&adapter->bss_prio_tbl[j].bss_prio_head)) - goto skip_prio_tbl; - - if (adapter->bss_prio_tbl[j].bss_prio_cur == - (struct mwifiex_bss_prio_node *) - &adapter->bss_prio_tbl[j].bss_prio_head) { - adapter->bss_prio_tbl[j].bss_prio_cur = - list_first_entry(&adapter->bss_prio_tbl[j] - .bss_prio_head, - struct mwifiex_bss_prio_node, - list); - } - - bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur; - bssprio_head = bssprio_node; + /* iterate over BSS with the equal priority */ + list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur, + &adapter->bss_prio_tbl[j].bss_prio_head, + list) { - do { - priv_tmp = bssprio_node->priv; + priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv; if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0) - goto skip_bss; + continue; /* iterate over the WMM queues of the BSS */ hqp = &priv_tmp->wmm.highest_queued_prio; @@ -926,73 +908,21 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, tid_ptr = &(priv_tmp)->wmm. tid_tbl_ptr[tos_to_tid[i]]; - /* For non-STA ra_list_curr may be NULL */ - if (!tid_ptr->ra_list_curr) - goto skip_wmm_queue; - - if (list_empty(&tid_ptr->ra_list)) - goto skip_wmm_queue; - - /* - * Always choose the next ra we transmitted - * last time, this way we pick the ra's in - * round robin fashion. - */ - ptr = list_first_entry( - &tid_ptr->ra_list_curr->list, - struct mwifiex_ra_list_tbl, - list); - - head = ptr; - if (ptr == (struct mwifiex_ra_list_tbl *) - &tid_ptr->ra_list) { - /* Get next ra */ - ptr = list_first_entry(&ptr->list, - struct mwifiex_ra_list_tbl, list); - head = ptr; - } + /* iterate over receiver addresses */ + list_for_each_entry(ptr, &tid_ptr->ra_list, + list) { - do { if (!skb_queue_empty(&ptr->skb_head)) /* holds both locks */ goto found; + } - /* Get next ra */ - ptr = list_first_entry(&ptr->list, - struct mwifiex_ra_list_tbl, - list); - if (ptr == - (struct mwifiex_ra_list_tbl *) - &tid_ptr->ra_list) - ptr = list_first_entry( - &ptr->list, - struct mwifiex_ra_list_tbl, - list); - } while (ptr != head); - -skip_wmm_queue: spin_unlock_irqrestore(&priv_tmp->wmm. ra_list_spinlock, flags_ra); } + } -skip_bss: - /* Get next bss priority node */ - bssprio_node = list_first_entry(&bssprio_node->list, - struct mwifiex_bss_prio_node, - list); - - if (bssprio_node == - (struct mwifiex_bss_prio_node *) - &adapter->bss_prio_tbl[j].bss_prio_head) - /* Get next bss priority node */ - bssprio_node = list_first_entry( - &bssprio_node->list, - struct mwifiex_bss_prio_node, - list); - } while (bssprio_node != bssprio_head); - -skip_prio_tbl: spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, flags_bss); } @@ -1013,6 +943,42 @@ found: return ptr; } +/* This functions rotates ra and bss lists so packets are picked round robin. + * + * After a packet is successfully transmitted, rotate the ra list, so the ra + * next to the one transmitted, will come first in the list. This way we pick + * the ra' in a round robin fashion. Same applies to bss nodes of equal + * priority. + * + * Function also increments wmm.packets_out counter. + */ +void mwifiex_rotate_priolists(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra, + int tid) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; + struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid]; + unsigned long flags; + + spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); + /* + * dirty trick: we remove 'head' temporarily and reinsert it after + * curr bss node. imagine list to stay fixed while head is moved + */ + list_move(&tbl[priv->bss_priority].bss_prio_head, + &tbl[priv->bss_priority].bss_prio_cur->list); + spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); + + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); + if (mwifiex_is_ralist_valid(priv, ra, tid)) { + priv->wmm.packets_out[tid]++; + /* same as above */ + list_move(&tid_ptr->ra_list, &ra->list); + } + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); +} + /* * This function checks if 11n aggregation is possible. */ @@ -1099,20 +1065,8 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); } else { - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); - if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { - priv->wmm.packets_out[ptr_index]++; - priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; - } - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - list_first_entry( - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_cur->list, - struct mwifiex_bss_prio_node, - list); + mwifiex_rotate_priolists(priv, ptr, ptr_index); atomic_dec(&priv->wmm.tx_pkts_queued); - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, - ra_list_flags); } } @@ -1216,20 +1170,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, break; } if (ret != -EBUSY) { - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); - if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { - priv->wmm.packets_out[ptr_index]++; - priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; - } - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - list_first_entry( - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_cur->list, - struct mwifiex_bss_prio_node, - list); + mwifiex_rotate_priolists(priv, ptr, ptr_index); atomic_dec(&priv->wmm.tx_pkts_queued); - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, - ra_list_flags); } } 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) void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); +void mwifiex_rotate_priolists(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra, + int tid); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); 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 { struct rxd_ops *rxd_ops; struct ieee80211_supported_band band_24; struct ieee80211_channel channels_24[14]; - struct ieee80211_rate rates_24[14]; + struct ieee80211_rate rates_24[13]; struct ieee80211_supported_band band_50; struct ieee80211_channel channels_50[4]; - struct ieee80211_rate rates_50[9]; + struct ieee80211_rate rates_50[8]; u32 ap_macids_supported; u32 sta_macids_supported; @@ -366,7 +366,6 @@ static const struct ieee80211_rate mwl8k_rates_24[] = { { .bitrate = 360, .hw_value = 72, }, { .bitrate = 480, .hw_value = 96, }, { .bitrate = 540, .hw_value = 108, }, - { .bitrate = 720, .hw_value = 144, }, }; static const struct ieee80211_channel mwl8k_channels_50[] = { @@ -385,7 +384,6 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { { .bitrate = 360, .hw_value = 72, }, { .bitrate = 480, .hw_value = 96, }, { .bitrate = 540, .hw_value = 108, }, - { .bitrate = 720, .hw_value = 144, }, }; /* Set or get info from Firmware */ @@ -2852,7 +2850,9 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, struct ieee80211_conf *conf, unsigned short pwr) { - struct ieee80211_channel *channel = conf->channel; + struct ieee80211_channel *channel = conf->chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&conf->chandef); struct mwl8k_cmd_tx_power *cmd; int rc; int i; @@ -2872,14 +2872,14 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, cmd->channel = cpu_to_le16(channel->hw_value); - if (conf->channel_type == NL80211_CHAN_NO_HT || - conf->channel_type == NL80211_CHAN_HT20) { + if (channel_type == NL80211_CHAN_NO_HT || + channel_type == NL80211_CHAN_HT20) { cmd->bw = cpu_to_le16(0x2); } else { cmd->bw = cpu_to_le16(0x4); - if (conf->channel_type == NL80211_CHAN_HT40MINUS) + if (channel_type == NL80211_CHAN_HT40MINUS) cmd->sub_ch = cpu_to_le16(0x3); - else if (conf->channel_type == NL80211_CHAN_HT40PLUS) + else if (channel_type == NL80211_CHAN_HT40PLUS) cmd->sub_ch = cpu_to_le16(0x1); } @@ -3023,7 +3023,9 @@ struct mwl8k_cmd_set_rf_channel { static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, struct ieee80211_conf *conf) { - struct ieee80211_channel *channel = conf->channel; + struct ieee80211_channel *channel = conf->chandef.chan; + enum nl80211_channel_type channel_type = + cfg80211_get_chandef_type(&conf->chandef); struct mwl8k_cmd_set_rf_channel *cmd; int rc; @@ -3041,12 +3043,12 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, else if (channel->band == IEEE80211_BAND_5GHZ) cmd->channel_flags |= cpu_to_le32(0x00000004); - if (conf->channel_type == NL80211_CHAN_NO_HT || - conf->channel_type == NL80211_CHAN_HT20) + if (channel_type == NL80211_CHAN_NO_HT || + channel_type == NL80211_CHAN_HT20) cmd->channel_flags |= cpu_to_le32(0x00000080); - else if (conf->channel_type == NL80211_CHAN_HT40MINUS) + else if (channel_type == NL80211_CHAN_HT40MINUS) cmd->channel_flags |= cpu_to_le32(0x000001900); - else if (conf->channel_type == NL80211_CHAN_HT40PLUS) + else if (channel_type == NL80211_CHAN_HT40PLUS) cmd->channel_flags |= cpu_to_le32(0x000000900); rc = mwl8k_post_cmd(hw, &cmd->header); @@ -3079,11 +3081,11 @@ static void legacy_rate_mask_to_array(u8 *rates, u32 mask) int j; /* - * Clear nonstandard rates 4 and 13. + * Clear nonstandard rate 4. */ mask &= 0x1fef; - for (i = 0, j = 0; i < 14; i++) { + for (i = 0, j = 0; i < 13; i++) { if (mask & (1 << i)) rates[j++] = mwl8k_rates_24[i].hw_value; } @@ -3965,7 +3967,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, memcpy(cmd->mac_addr, sta->addr, ETH_ALEN); cmd->stn_id = cpu_to_le16(sta->aid); cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD); - if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) + if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; else rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5; @@ -4400,7 +4402,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, p->ht_caps = cpu_to_le16(sta->ht_cap.cap); p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | ((sta->ht_cap.ampdu_density & 7) << 2); - if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) + if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) rates = sta->supp_rates[IEEE80211_BAND_2GHZ]; else 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, goto out; } - if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) { ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ]; } else { ap_legacy_rates = @@ -4913,7 +4915,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (idx) idx--; - if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) + if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) rate = mwl8k_rates_24[idx].hw_value; else rate = mwl8k_rates_50[idx].hw_value; @@ -4986,7 +4988,7 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (idx) idx--; - if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) + if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) rate = mwl8k_rates_24[idx].hw_value; else rate = mwl8k_rates_50[idx].hw_value; @@ -5259,7 +5261,7 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = priv->noise; 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) struct p54_rssi_db_entry *rssi_data; unsigned int i; void *entry; - __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); + __le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq); skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + 2 + sizeof(*iq_autocal) + sizeof(*body) + @@ -532,7 +532,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) err: wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", ieee80211_frequency_to_channel( - priv->hw->conf.channel->center_freq)); + priv->hw->conf.chandef.chan->center_freq)); dev_kfree_skb_any(skb); 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) * TODO: Use the LM_SCAN_TRAP to determine the current * operating channel. */ - priv->curchan = priv->hw->conf.channel; + priv->curchan = priv->hw->conf.chandef.chan; p54_reset_stats(priv); WARN_ON(p54_fetch_statistics(priv)); } @@ -480,7 +480,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev, p54_set_edcf(priv); } if (changed & BSS_CHANGED_BASIC_RATES) { - if (dev->conf.channel->band == IEEE80211_BAND_5GHZ) + if (dev->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) priv->basic_rate_mask = (info->basic_rates << 4); else 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) rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); if (hdr->rate & 0x10) rx_status->flag |= RX_FLAG_SHORTPRE; - if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) + if (priv->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) rx_status->rate_idx = (rate < 4) ? 0 : rate - 4; else rx_status->rate_idx = rate; rx_status->freq = freq; - rx_status->band = priv->hw->conf.channel->band; + rx_status->band = priv->hw->conf.chandef.chan->band; rx_status->antenna = hdr->antenna; 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 @@ /* * Register access. * All access to the CSR registers will go through the methods - * rt2x00pci_register_read and rt2x00pci_register_write. + * rt2x00mmio_register_read and rt2x00mmio_register_write. * BBP and RF register require indirect register access, * and use the CSR registers BBPCSR and RFCSR to achieve this. * These indirect registers work with busy bits, @@ -52,9 +52,9 @@ * and we will print an error. */ #define WAIT_FOR_BBP(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) #define WAIT_FOR_RF(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) @@ -74,7 +74,7 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBPCSR_BUSY, 1); rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); - rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); + rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); } mutex_unlock(&rt2x00dev->csr_mutex); @@ -101,7 +101,7 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBPCSR_BUSY, 1); rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); - rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); + rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); WAIT_FOR_BBP(rt2x00dev, ®); } @@ -129,7 +129,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); rt2x00_set_field32(®, RFCSR_BUSY, 1); - rt2x00pci_register_write(rt2x00dev, RFCSR, reg); + rt2x00mmio_register_write(rt2x00dev, RFCSR, reg); rt2x00_rf_write(rt2x00dev, word, value); } @@ -141,7 +141,7 @@ static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR21, ®); + rt2x00mmio_register_read(rt2x00dev, CSR21, ®); eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); 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) rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, !!eeprom->reg_chip_select); - rt2x00pci_register_write(rt2x00dev, CSR21, reg); + rt2x00mmio_register_write(rt2x00dev, CSR21, reg); } #ifdef CONFIG_RT2X00_LIB_DEBUGFS static const struct rt2x00debug rt2400pci_rt2x00debug = { .owner = THIS_MODULE, .csr = { - .read = rt2x00pci_register_read, - .write = rt2x00pci_register_write, + .read = rt2x00mmio_register_read, + .write = rt2x00mmio_register_write, .flags = RT2X00DEBUGFS_OFFSET, .word_base = CSR_REG_BASE, .word_size = sizeof(u32), @@ -205,7 +205,7 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); + rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); return rt2x00_get_field32(reg, GPIOCSR_VAL0); } @@ -218,14 +218,14 @@ static void rt2400pci_brightness_set(struct led_classdev *led_cdev, unsigned int enabled = brightness != LED_OFF; u32 reg; - rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); + rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) rt2x00_set_field32(®, LEDCSR_LINK, enabled); else if (led->type == LED_TYPE_ACTIVITY) rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); - rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); + rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); } static int rt2400pci_blink_set(struct led_classdev *led_cdev, @@ -236,10 +236,10 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev, container_of(led_cdev, struct rt2x00_led, led_dev); u32 reg; - rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); + rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); - rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); + rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); return 0; } @@ -269,7 +269,7 @@ static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, * Note that the version error will always be dropped * since there is no filter for it at this time. */ - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DROP_CRC, !(filter_flags & FIF_FCSFAIL)); rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, @@ -282,7 +282,7 @@ static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev, !(filter_flags & FIF_PROMISC_IN_BSS) && !rt2x00dev->intf_ap_count); rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); } static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, @@ -298,25 +298,26 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, * Enable beacon config */ bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); - rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, BCNCSR1, ®); rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); - rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg); /* * Enable synchronisation. */ - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); } if (flags & CONFIG_UPDATE_MAC) - rt2x00pci_register_multiwrite(rt2x00dev, CSR3, - conf->mac, sizeof(conf->mac)); + rt2x00mmio_register_multiwrite(rt2x00dev, CSR3, + conf->mac, sizeof(conf->mac)); if (flags & CONFIG_UPDATE_BSSID) - rt2x00pci_register_multiwrite(rt2x00dev, CSR5, - conf->bssid, sizeof(conf->bssid)); + rt2x00mmio_register_multiwrite(rt2x00dev, CSR5, + conf->bssid, + sizeof(conf->bssid)); } static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, @@ -332,68 +333,68 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, if (changed & BSS_CHANGED_ERP_PREAMBLE) { preamble_mask = erp->short_preamble << 3; - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR1, ®); rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR2, ®); rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR3, ®); rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR4, ®); rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR5, ®); rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg); } if (changed & BSS_CHANGED_BASIC_RATES) - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates); if (changed & BSS_CHANGED_ERP_SLOT) { - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00mmio_register_read(rt2x00dev, CSR18, ®); rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00mmio_register_write(rt2x00dev, CSR18, reg); - rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00mmio_register_read(rt2x00dev, CSR19, ®); rt2x00_set_field32(®, CSR19_DIFS, erp->difs); rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); + rt2x00mmio_register_write(rt2x00dev, CSR19, reg); } if (changed & BSS_CHANGED_BEACON_INT) { - rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00mmio_register_read(rt2x00dev, CSR12, ®); rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + rt2x00mmio_register_write(rt2x00dev, CSR12, reg); } } @@ -497,7 +498,7 @@ static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev, /* * Clear false CRC during channel switch. */ - rt2x00pci_register_read(rt2x00dev, CNT0, &rf->rf1); + rt2x00mmio_register_read(rt2x00dev, CNT0, &rf->rf1); } 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, { u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_LONG_RETRY, libconf->conf->long_frame_max_tx_count); rt2x00_set_field32(®, CSR11_SHORT_RETRY, libconf->conf->short_frame_max_tx_count); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); } static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, @@ -527,7 +528,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, u32 reg; if (state == STATE_SLEEP) { - rt2x00pci_register_read(rt2x00dev, CSR20, ®); + rt2x00mmio_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, (rt2x00dev->beacon_int - 20) * 16); rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, @@ -535,14 +536,14 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, /* We must first disable autowake before it can be enabled */ rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); } else { - rt2x00pci_register_read(rt2x00dev, CSR20, ®); + rt2x00mmio_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); } rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); @@ -568,10 +569,10 @@ static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_CWMIN, cw_min); rt2x00_set_field32(®, CSR11_CWMAX, cw_max); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); } /* @@ -586,7 +587,7 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, /* * Update FCS error count from register. */ - rt2x00pci_register_read(rt2x00dev, CNT0, ®); + rt2x00mmio_register_read(rt2x00dev, CNT0, ®); qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); /* @@ -641,16 +642,16 @@ static void rt2400pci_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); break; default: break; @@ -664,19 +665,19 @@ static void rt2400pci_kick_queue(struct data_queue *queue) switch (queue->qid) { case QID_AC_VO: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_AC_VI: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_ATIM: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; default: break; @@ -692,21 +693,21 @@ static void rt2400pci_stop_queue(struct data_queue *queue) case QID_AC_VO: case QID_AC_VI: case QID_ATIM: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_RX: - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); rt2x00_set_field32(®, CSR14_TBCN, 0); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); /* * Wait for possibly running tbtt tasklets. @@ -723,7 +724,7 @@ static void rt2400pci_stop_queue(struct data_queue *queue) */ static bool rt2400pci_get_entry_state(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word; if (entry->queue->qid == QID_RX) { @@ -740,7 +741,7 @@ static bool rt2400pci_get_entry_state(struct queue_entry *entry) static void rt2400pci_clear_entry(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; @@ -766,53 +767,53 @@ static void rt2400pci_clear_entry(struct queue_entry *entry) static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) { - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; u32 reg; /* * Initialize registers. */ - rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR2, ®); rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); - rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR3, ®); rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg); entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR5, ®); rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg); entry_priv = rt2x00dev->atim->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR4, ®); rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg); entry_priv = rt2x00dev->bcn->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR6, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg); - rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR1, ®); rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); - rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg); entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR2, ®); rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg); return 0; } @@ -821,23 +822,23 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); - rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); - rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00023f20); - rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); + rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002); + rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002); + rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00023f20); + rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002); - rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); + rt2x00mmio_register_read(rt2x00dev, TIMECSR, ®); rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); - rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); + rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg); - rt2x00pci_register_read(rt2x00dev, CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, CSR9, ®); rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, (rt2x00dev->rx->data_size / 128)); - rt2x00pci_register_write(rt2x00dev, CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, CSR9, reg); - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); rt2x00_set_field32(®, CSR14_TBCN, 0); @@ -846,63 +847,63 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); - rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); + rt2x00mmio_register_write(rt2x00dev, CNT3, 0x3f080000); - rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR0, ®); rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA0, 133); rt2x00_set_field32(®, ARCSR0_AR_BBP_ID0, 134); rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA1, 136); rt2x00_set_field32(®, ARCSR0_AR_BBP_ID1, 135); - rt2x00pci_register_write(rt2x00dev, ARCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR0, reg); - rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR3, ®); rt2x00_set_field32(®, RXCSR3_BBP_ID0, 3); /* Tx power.*/ rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); rt2x00_set_field32(®, RXCSR3_BBP_ID1, 32); /* Signal */ rt2x00_set_field32(®, RXCSR3_BBP_ID1_VALID, 1); rt2x00_set_field32(®, RXCSR3_BBP_ID2, 36); /* Rssi */ rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); - rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg); - rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); + rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) return -EBUSY; - rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00217223); - rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); + rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00217223); + rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518); - rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, MACCSR2, ®); rt2x00_set_field32(®, MACCSR2_DELAY, 64); - rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg); - rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); + rt2x00mmio_register_read(rt2x00dev, RALINKCSR, ®); rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 154); rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 154); - rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); + rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg); - rt2x00pci_register_read(rt2x00dev, CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, CSR1, ®); rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, CSR1_BBP_RESET, 0); rt2x00_set_field32(®, CSR1_HOST_READY, 0); - rt2x00pci_register_write(rt2x00dev, CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, CSR1, reg); - rt2x00pci_register_read(rt2x00dev, CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, CSR1, ®); rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); rt2x00_set_field32(®, CSR1_HOST_READY, 1); - rt2x00pci_register_write(rt2x00dev, CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, CSR1, reg); /* * We must clear the FCS and FIFO error count. * These registers are cleared on read, * so we may pass a useless variable to store the value. */ - rt2x00pci_register_read(rt2x00dev, CNT0, ®); - rt2x00pci_register_read(rt2x00dev, CNT4, ®); + rt2x00mmio_register_read(rt2x00dev, CNT0, ®); + rt2x00mmio_register_read(rt2x00dev, CNT4, ®); return 0; } @@ -919,7 +920,7 @@ static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -976,8 +977,8 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); + rt2x00mmio_register_read(rt2x00dev, CSR7, ®); + rt2x00mmio_register_write(rt2x00dev, CSR7, reg); } /* @@ -986,13 +987,13 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, */ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); rt2x00_set_field32(®, CSR8_RXDONE, mask); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); @@ -1025,7 +1026,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Disable power */ - rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); + rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0); } static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -1039,12 +1040,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, put_to_sleep = (state != STATE_AWAKE); - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®); rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); - rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); /* * Device is not guaranteed to be in the requested state yet. @@ -1052,12 +1053,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); + rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®2); bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); if (bbp_state == state && rf_state == state) return 0; - rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); msleep(10); } @@ -1092,8 +1093,8 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -1105,7 +1106,7 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1182,12 +1183,12 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); if (rt2x00queue_map_txskb(entry)) { - ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); + rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n"); goto out; } /* @@ -1208,7 +1209,7 @@ out: * Enable beaconing again. */ rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); } /* @@ -1218,7 +1219,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word0; u32 word2; u32 word3; @@ -1276,7 +1277,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; u32 word; @@ -1322,9 +1323,9 @@ static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, irq_field, 0); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -1347,11 +1348,11 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -1368,7 +1369,7 @@ static void rt2400pci_tbtt_tasklet(unsigned long data) static void rt2400pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2x00pci_rxdone(rt2x00dev)) + if (rt2x00mmio_rxdone(rt2x00dev)) tasklet_schedule(&rt2x00dev->rxdone_tasklet); else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); @@ -1383,8 +1384,8 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) * Get the interrupt sources & saved to local variable. * Write register value back to clear pending interrupts. */ - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); + rt2x00mmio_register_read(rt2x00dev, CSR7, ®); + rt2x00mmio_register_write(rt2x00dev, CSR7, reg); if (!reg) return IRQ_NONE; @@ -1421,9 +1422,9 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) */ spin_lock(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); reg |= mask; - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock(&rt2x00dev->irqmask_lock); @@ -1442,7 +1443,7 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) u16 word; u8 *mac; - rt2x00pci_register_read(rt2x00dev, CSR21, ®); + rt2x00mmio_register_read(rt2x00dev, CSR21, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt2400pci_eepromregister_read; @@ -1463,12 +1464,12 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { - ERROR(rt2x00dev, "Invalid EEPROM data detected.\n"); + rt2x00_err(rt2x00dev, "Invalid EEPROM data detected\n"); return -EINVAL; } @@ -1490,12 +1491,12 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Identify RF chipset. */ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); - rt2x00pci_register_read(rt2x00dev, CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, CSR0, ®); rt2x00_set_chip(rt2x00dev, RT2460, value, rt2x00_get_field32(reg, CSR0_REVISION)); if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); return -ENODEV; } @@ -1635,9 +1636,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) * Enable rfkill polling by setting GPIO direction of the * rfkill switch GPIO pin correctly. */ - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); + rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); rt2x00_set_field32(®, GPIOCSR_DIR0, 1); - rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg); /* * Initialize hw specifications. @@ -1697,9 +1698,9 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw, u64 tsf; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR17, ®); + rt2x00mmio_register_read(rt2x00dev, CSR17, ®); tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; - rt2x00pci_register_read(rt2x00dev, CSR16, ®); + rt2x00mmio_register_read(rt2x00dev, CSR16, ®); tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); return tsf; @@ -1710,7 +1711,7 @@ static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) struct rt2x00_dev *rt2x00dev = hw->priv; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR15, ®); + rt2x00mmio_register_read(rt2x00dev, CSR15, ®); return rt2x00_get_field32(reg, CSR15_BEACON_SENT); } @@ -1743,8 +1744,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .tbtt_tasklet = rt2400pci_tbtt_tasklet, .rxdone_tasklet = rt2400pci_rxdone_tasklet, .probe_hw = rt2400pci_probe_hw, - .initialize = rt2x00pci_initialize, - .uninitialize = rt2x00pci_uninitialize, + .initialize = rt2x00mmio_initialize, + .uninitialize = rt2x00mmio_uninitialize, .get_entry_state = rt2400pci_get_entry_state, .clear_entry = rt2400pci_clear_entry, .set_device_state = rt2400pci_set_device_state, @@ -1755,7 +1756,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .start_queue = rt2400pci_start_queue, .kick_queue = rt2400pci_kick_queue, .stop_queue = rt2400pci_stop_queue, - .flush_queue = rt2x00pci_flush_queue, + .flush_queue = rt2x00mmio_flush_queue, .write_tx_desc = rt2400pci_write_tx_desc, .write_beacon = rt2400pci_write_beacon, .fill_rxdone = rt2400pci_fill_rxdone, @@ -1770,28 +1771,28 @@ static const struct data_queue_desc rt2400pci_queue_rx = { .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2400pci_queue_tx = { .entry_num = 24, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2400pci_queue_bcn = { .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2400pci_queue_atim = { .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; 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 @@ /* * Register access. * All access to the CSR registers will go through the methods - * rt2x00pci_register_read and rt2x00pci_register_write. + * rt2x00mmio_register_read and rt2x00mmio_register_write. * BBP and RF register require indirect register access, * and use the CSR registers BBPCSR and RFCSR to achieve this. * These indirect registers work with busy bits, @@ -52,9 +52,9 @@ * and we will print an error. */ #define WAIT_FOR_BBP(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) #define WAIT_FOR_RF(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) @@ -74,7 +74,7 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBPCSR_BUSY, 1); rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); - rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); + rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); } mutex_unlock(&rt2x00dev->csr_mutex); @@ -101,7 +101,7 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBPCSR_BUSY, 1); rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); - rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); + rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg); WAIT_FOR_BBP(rt2x00dev, ®); } @@ -129,7 +129,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); rt2x00_set_field32(®, RFCSR_BUSY, 1); - rt2x00pci_register_write(rt2x00dev, RFCSR, reg); + rt2x00mmio_register_write(rt2x00dev, RFCSR, reg); rt2x00_rf_write(rt2x00dev, word, value); } @@ -141,7 +141,7 @@ static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR21, ®); + rt2x00mmio_register_read(rt2x00dev, CSR21, ®); eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); 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) rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, !!eeprom->reg_chip_select); - rt2x00pci_register_write(rt2x00dev, CSR21, reg); + rt2x00mmio_register_write(rt2x00dev, CSR21, reg); } #ifdef CONFIG_RT2X00_LIB_DEBUGFS static const struct rt2x00debug rt2500pci_rt2x00debug = { .owner = THIS_MODULE, .csr = { - .read = rt2x00pci_register_read, - .write = rt2x00pci_register_write, + .read = rt2x00mmio_register_read, + .write = rt2x00mmio_register_write, .flags = RT2X00DEBUGFS_OFFSET, .word_base = CSR_REG_BASE, .word_size = sizeof(u32), @@ -205,7 +205,7 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); + rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); return rt2x00_get_field32(reg, GPIOCSR_VAL0); } @@ -218,14 +218,14 @@ static void rt2500pci_brightness_set(struct led_classdev *led_cdev, unsigned int enabled = brightness != LED_OFF; u32 reg; - rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); + rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) rt2x00_set_field32(®, LEDCSR_LINK, enabled); else if (led->type == LED_TYPE_ACTIVITY) rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled); - rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); + rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); } static int rt2500pci_blink_set(struct led_classdev *led_cdev, @@ -236,10 +236,10 @@ static int rt2500pci_blink_set(struct led_classdev *led_cdev, container_of(led_cdev, struct rt2x00_led, led_dev); u32 reg; - rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); + rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, ®); rt2x00_set_field32(®, LEDCSR_ON_PERIOD, *delay_on); rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, *delay_off); - rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); + rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg); return 0; } @@ -270,7 +270,7 @@ static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, * and broadcast frames will always be accepted since * there is no filter for it at this time. */ - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DROP_CRC, !(filter_flags & FIF_FCSFAIL)); rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, @@ -286,7 +286,7 @@ static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, RXCSR0_DROP_MCAST, !(filter_flags & FIF_ALLMULTI)); rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); } static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, @@ -303,25 +303,25 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, * Enable beacon config */ bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); - rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, BCNCSR1, ®); rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); - rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg); /* * Enable synchronisation. */ - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); } if (flags & CONFIG_UPDATE_MAC) - rt2x00pci_register_multiwrite(rt2x00dev, CSR3, + rt2x00mmio_register_multiwrite(rt2x00dev, CSR3, conf->mac, sizeof(conf->mac)); if (flags & CONFIG_UPDATE_BSSID) - rt2x00pci_register_multiwrite(rt2x00dev, CSR5, + rt2x00mmio_register_multiwrite(rt2x00dev, CSR5, conf->bssid, sizeof(conf->bssid)); } @@ -338,68 +338,68 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, if (changed & BSS_CHANGED_ERP_PREAMBLE) { preamble_mask = erp->short_preamble << 3; - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR1, ®); rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR2, ®); rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR3, ®); rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR4, ®); rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg); - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00mmio_register_read(rt2x00dev, ARCSR5, ®); rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg); } if (changed & BSS_CHANGED_BASIC_RATES) - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates); if (changed & BSS_CHANGED_ERP_SLOT) { - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00mmio_register_read(rt2x00dev, CSR18, ®); rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00mmio_register_write(rt2x00dev, CSR18, reg); - rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00mmio_register_read(rt2x00dev, CSR19, ®); rt2x00_set_field32(®, CSR19_DIFS, erp->difs); rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); + rt2x00mmio_register_write(rt2x00dev, CSR19, reg); } if (changed & BSS_CHANGED_BEACON_INT) { - rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00mmio_register_read(rt2x00dev, CSR12, ®); rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + rt2x00mmio_register_write(rt2x00dev, CSR12, reg); } } @@ -418,7 +418,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || ant->tx == ANTENNA_SW_DIVERSITY); - rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, BBPCSR1, ®); rt2500pci_bbp_read(rt2x00dev, 14, &r14); rt2500pci_bbp_read(rt2x00dev, 2, &r2); @@ -470,7 +470,7 @@ static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 0); } - rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, BBPCSR1, reg); rt2500pci_bbp_write(rt2x00dev, 14, r14); rt2500pci_bbp_write(rt2x00dev, 2, r2); } @@ -541,7 +541,7 @@ static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev, /* * Clear false CRC during channel switch. */ - rt2x00pci_register_read(rt2x00dev, CNT0, &rf->rf1); + rt2x00mmio_register_read(rt2x00dev, CNT0, &rf->rf1); } static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, @@ -559,12 +559,12 @@ static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_LONG_RETRY, libconf->conf->long_frame_max_tx_count); rt2x00_set_field32(®, CSR11_SHORT_RETRY, libconf->conf->short_frame_max_tx_count); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); } static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, @@ -576,7 +576,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, u32 reg; if (state == STATE_SLEEP) { - rt2x00pci_register_read(rt2x00dev, CSR20, ®); + rt2x00mmio_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, (rt2x00dev->beacon_int - 20) * 16); rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, @@ -584,14 +584,14 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, /* We must first disable autowake before it can be enabled */ rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); } else { - rt2x00pci_register_read(rt2x00dev, CSR20, ®); + rt2x00mmio_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); - rt2x00pci_register_write(rt2x00dev, CSR20, reg); + rt2x00mmio_register_write(rt2x00dev, CSR20, reg); } rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); @@ -625,13 +625,13 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, /* * Update FCS error count from register. */ - rt2x00pci_register_read(rt2x00dev, CNT0, ®); + rt2x00mmio_register_read(rt2x00dev, CNT0, ®); qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); /* * Update False CCA count from register. */ - rt2x00pci_register_read(rt2x00dev, CNT3, ®); + rt2x00mmio_register_read(rt2x00dev, CNT3, ®); qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); } @@ -731,16 +731,16 @@ static void rt2500pci_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); break; default: break; @@ -754,19 +754,19 @@ static void rt2500pci_kick_queue(struct data_queue *queue) switch (queue->qid) { case QID_AC_VO: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_AC_VI: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_ATIM: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; default: break; @@ -782,21 +782,21 @@ static void rt2500pci_stop_queue(struct data_queue *queue) case QID_AC_VO: case QID_AC_VI: case QID_ATIM: - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg); break; case QID_RX: - rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); - rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); rt2x00_set_field32(®, CSR14_TBCN, 0); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); /* * Wait for possibly running tbtt tasklets. @@ -813,7 +813,7 @@ static void rt2500pci_stop_queue(struct data_queue *queue) */ static bool rt2500pci_get_entry_state(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word; if (entry->queue->qid == QID_RX) { @@ -830,7 +830,7 @@ static bool rt2500pci_get_entry_state(struct queue_entry *entry) static void rt2500pci_clear_entry(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; @@ -852,53 +852,53 @@ static void rt2500pci_clear_entry(struct queue_entry *entry) static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) { - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; u32 reg; /* * Initialize registers. */ - rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR2, ®); rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); - rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR3, ®); rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg); entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR5, ®); rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg); entry_priv = rt2x00dev->atim->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR4, ®); rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg); entry_priv = rt2x00dev->bcn->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR6, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg); - rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR1, ®); rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); - rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg); entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR2, ®); rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg); return 0; } @@ -907,30 +907,30 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); - rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); - rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00020002); - rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); + rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002); + rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002); + rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00020002); + rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002); - rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); + rt2x00mmio_register_read(rt2x00dev, TIMECSR, ®); rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); - rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); + rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg); - rt2x00pci_register_read(rt2x00dev, CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, CSR9, ®); rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, rt2x00dev->rx->data_size / 128); - rt2x00pci_register_write(rt2x00dev, CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, CSR9, reg); /* * Always use CWmin and CWmax set in descriptor. */ - rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, CSR11, ®); rt2x00_set_field32(®, CSR11_CW_SELECT, 0); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); rt2x00_set_field32(®, CSR14_TBCN, 0); @@ -939,11 +939,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00_set_field32(®, CSR14_CFP_COUNT_PRELOAD, 0); rt2x00_set_field32(®, CSR14_TBCM_PRELOAD, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); - rt2x00pci_register_write(rt2x00dev, CNT3, 0); + rt2x00mmio_register_write(rt2x00dev, CNT3, 0); - rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); + rt2x00mmio_register_read(rt2x00dev, TXCSR8, ®); rt2x00_set_field32(®, TXCSR8_BBP_ID0, 10); rt2x00_set_field32(®, TXCSR8_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXCSR8_BBP_ID1, 11); @@ -952,30 +952,30 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TXCSR8_BBP_ID2_VALID, 1); rt2x00_set_field32(®, TXCSR8_BBP_ID3, 12); rt2x00_set_field32(®, TXCSR8_BBP_ID3_VALID, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR8, reg); + rt2x00mmio_register_write(rt2x00dev, TXCSR8, reg); - rt2x00pci_register_read(rt2x00dev, ARTCSR0, ®); + rt2x00mmio_register_read(rt2x00dev, ARTCSR0, ®); rt2x00_set_field32(®, ARTCSR0_ACK_CTS_1MBS, 112); rt2x00_set_field32(®, ARTCSR0_ACK_CTS_2MBS, 56); rt2x00_set_field32(®, ARTCSR0_ACK_CTS_5_5MBS, 20); rt2x00_set_field32(®, ARTCSR0_ACK_CTS_11MBS, 10); - rt2x00pci_register_write(rt2x00dev, ARTCSR0, reg); + rt2x00mmio_register_write(rt2x00dev, ARTCSR0, reg); - rt2x00pci_register_read(rt2x00dev, ARTCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, ARTCSR1, ®); rt2x00_set_field32(®, ARTCSR1_ACK_CTS_6MBS, 45); rt2x00_set_field32(®, ARTCSR1_ACK_CTS_9MBS, 37); rt2x00_set_field32(®, ARTCSR1_ACK_CTS_12MBS, 33); rt2x00_set_field32(®, ARTCSR1_ACK_CTS_18MBS, 29); - rt2x00pci_register_write(rt2x00dev, ARTCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, ARTCSR1, reg); - rt2x00pci_register_read(rt2x00dev, ARTCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, ARTCSR2, ®); rt2x00_set_field32(®, ARTCSR2_ACK_CTS_24MBS, 29); rt2x00_set_field32(®, ARTCSR2_ACK_CTS_36MBS, 25); rt2x00_set_field32(®, ARTCSR2_ACK_CTS_48MBS, 25); rt2x00_set_field32(®, ARTCSR2_ACK_CTS_54MBS, 25); - rt2x00pci_register_write(rt2x00dev, ARTCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, ARTCSR2, reg); - rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); + rt2x00mmio_register_read(rt2x00dev, RXCSR3, ®); rt2x00_set_field32(®, RXCSR3_BBP_ID0, 47); /* CCK Signal */ rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); rt2x00_set_field32(®, RXCSR3_BBP_ID1, 51); /* Rssi */ @@ -984,9 +984,9 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); rt2x00_set_field32(®, RXCSR3_BBP_ID3, 51); /* RSSI */ rt2x00_set_field32(®, RXCSR3_BBP_ID3_VALID, 1); - rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); + rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg); - rt2x00pci_register_read(rt2x00dev, PCICSR, ®); + rt2x00mmio_register_read(rt2x00dev, PCICSR, ®); rt2x00_set_field32(®, PCICSR_BIG_ENDIAN, 0); rt2x00_set_field32(®, PCICSR_RX_TRESHOLD, 0); rt2x00_set_field32(®, PCICSR_TX_TRESHOLD, 3); @@ -994,54 +994,54 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, PCICSR_ENABLE_CLK, 1); rt2x00_set_field32(®, PCICSR_READ_MULTIPLE, 1); rt2x00_set_field32(®, PCICSR_WRITE_INVALID, 1); - rt2x00pci_register_write(rt2x00dev, PCICSR, reg); + rt2x00mmio_register_write(rt2x00dev, PCICSR, reg); - rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); + rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); - rt2x00pci_register_write(rt2x00dev, GPIOCSR, 0x0000ff00); - rt2x00pci_register_write(rt2x00dev, TESTCSR, 0x000000f0); + rt2x00mmio_register_write(rt2x00dev, GPIOCSR, 0x0000ff00); + rt2x00mmio_register_write(rt2x00dev, TESTCSR, 0x000000f0); if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) return -EBUSY; - rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00213223); - rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); + rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00213223); + rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518); - rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); + rt2x00mmio_register_read(rt2x00dev, MACCSR2, ®); rt2x00_set_field32(®, MACCSR2_DELAY, 64); - rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); + rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg); - rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); + rt2x00mmio_register_read(rt2x00dev, RALINKCSR, ®); rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 26); rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID0, 1); rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 26); rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID1, 1); - rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); + rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg); - rt2x00pci_register_write(rt2x00dev, BBPCSR1, 0x82188200); + rt2x00mmio_register_write(rt2x00dev, BBPCSR1, 0x82188200); - rt2x00pci_register_write(rt2x00dev, TXACKCSR0, 0x00000020); + rt2x00mmio_register_write(rt2x00dev, TXACKCSR0, 0x00000020); - rt2x00pci_register_read(rt2x00dev, CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, CSR1, ®); rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, CSR1_BBP_RESET, 0); rt2x00_set_field32(®, CSR1_HOST_READY, 0); - rt2x00pci_register_write(rt2x00dev, CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, CSR1, reg); - rt2x00pci_register_read(rt2x00dev, CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, CSR1, ®); rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); rt2x00_set_field32(®, CSR1_HOST_READY, 1); - rt2x00pci_register_write(rt2x00dev, CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, CSR1, reg); /* * We must clear the FCS and FIFO error count. * These registers are cleared on read, * so we may pass a useless variable to store the value. */ - rt2x00pci_register_read(rt2x00dev, CNT0, ®); - rt2x00pci_register_read(rt2x00dev, CNT4, ®); + rt2x00mmio_register_read(rt2x00dev, CNT0, ®); + rt2x00mmio_register_read(rt2x00dev, CNT4, ®); return 0; } @@ -1058,7 +1058,7 @@ static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -1131,8 +1131,8 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); + rt2x00mmio_register_read(rt2x00dev, CSR7, ®); + rt2x00mmio_register_write(rt2x00dev, CSR7, reg); } /* @@ -1141,13 +1141,13 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, */ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); rt2x00_set_field32(®, CSR8_RXDONE, mask); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); @@ -1179,7 +1179,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Disable power */ - rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); + rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0); } static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -1193,12 +1193,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, put_to_sleep = (state != STATE_AWAKE); - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); + rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®); rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); - rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); /* * Device is not guaranteed to be in the requested state yet. @@ -1206,12 +1206,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); + rt2x00mmio_register_read(rt2x00dev, PWRCSR1, ®2); bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); if (bbp_state == state && rf_state == state) return 0; - rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); + rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg); msleep(10); } @@ -1246,8 +1246,8 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -1259,7 +1259,7 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1335,12 +1335,12 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ - rt2x00pci_register_read(rt2x00dev, CSR14, ®); + rt2x00mmio_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); if (rt2x00queue_map_txskb(entry)) { - ERROR(rt2x00dev, "Fail to map beacon, aborting\n"); + rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n"); goto out; } @@ -1358,7 +1358,7 @@ out: * Enable beaconing again. */ rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, CSR14, reg); + rt2x00mmio_register_write(rt2x00dev, CSR14, reg); } /* @@ -1367,7 +1367,7 @@ out: static void rt2500pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word0; u32 word2; @@ -1405,7 +1405,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; u32 word; @@ -1451,9 +1451,9 @@ static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, irq_field, 0); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -1476,11 +1476,11 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -1497,7 +1497,7 @@ static void rt2500pci_tbtt_tasklet(unsigned long data) static void rt2500pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2x00pci_rxdone(rt2x00dev)) + if (rt2x00mmio_rxdone(rt2x00dev)) tasklet_schedule(&rt2x00dev->rxdone_tasklet); else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); @@ -1512,8 +1512,8 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) * Get the interrupt sources & saved to local variable. * Write register value back to clear pending interrupts. */ - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); + rt2x00mmio_register_read(rt2x00dev, CSR7, ®); + rt2x00mmio_register_write(rt2x00dev, CSR7, reg); if (!reg) return IRQ_NONE; @@ -1550,9 +1550,9 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) */ spin_lock(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, CSR8, ®); reg |= mask; - rt2x00pci_register_write(rt2x00dev, CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, CSR8, reg); spin_unlock(&rt2x00dev->irqmask_lock); @@ -1569,7 +1569,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) u16 word; u8 *mac; - rt2x00pci_register_read(rt2x00dev, CSR21, ®); + rt2x00mmio_register_read(rt2x00dev, CSR21, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt2500pci_eepromregister_read; @@ -1590,7 +1590,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); @@ -1606,7 +1606,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); - EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); @@ -1615,7 +1615,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); - EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); @@ -1623,7 +1623,8 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, DEFAULT_RSSI_OFFSET); rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); - EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Calibrate offset: 0x%04x\n", + word); } return 0; @@ -1644,7 +1645,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Identify RF chipset. */ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); - rt2x00pci_register_read(rt2x00dev, CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, CSR0, ®); rt2x00_set_chip(rt2x00dev, RT2560, value, rt2x00_get_field32(reg, CSR0_REVISION)); @@ -1654,7 +1655,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF2525) && !rt2x00_rf(rt2x00dev, RF2525E) && !rt2x00_rf(rt2x00dev, RF5222)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); return -ENODEV; } @@ -1950,9 +1951,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) * Enable rfkill polling by setting GPIO direction of the * rfkill switch GPIO pin correctly. */ - rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); + rt2x00mmio_register_read(rt2x00dev, GPIOCSR, ®); rt2x00_set_field32(®, GPIOCSR_DIR0, 1); - rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg); /* * Initialize hw specifications. @@ -1986,9 +1987,9 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw, u64 tsf; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR17, ®); + rt2x00mmio_register_read(rt2x00dev, CSR17, ®); tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; - rt2x00pci_register_read(rt2x00dev, CSR16, ®); + rt2x00mmio_register_read(rt2x00dev, CSR16, ®); tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); return tsf; @@ -1999,7 +2000,7 @@ static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) struct rt2x00_dev *rt2x00dev = hw->priv; u32 reg; - rt2x00pci_register_read(rt2x00dev, CSR15, ®); + rt2x00mmio_register_read(rt2x00dev, CSR15, ®); return rt2x00_get_field32(reg, CSR15_BEACON_SENT); } @@ -2032,8 +2033,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .tbtt_tasklet = rt2500pci_tbtt_tasklet, .rxdone_tasklet = rt2500pci_rxdone_tasklet, .probe_hw = rt2500pci_probe_hw, - .initialize = rt2x00pci_initialize, - .uninitialize = rt2x00pci_uninitialize, + .initialize = rt2x00mmio_initialize, + .uninitialize = rt2x00mmio_uninitialize, .get_entry_state = rt2500pci_get_entry_state, .clear_entry = rt2500pci_clear_entry, .set_device_state = rt2500pci_set_device_state, @@ -2044,7 +2045,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .start_queue = rt2500pci_start_queue, .kick_queue = rt2500pci_kick_queue, .stop_queue = rt2500pci_stop_queue, - .flush_queue = rt2x00pci_flush_queue, + .flush_queue = rt2x00mmio_flush_queue, .write_tx_desc = rt2500pci_write_tx_desc, .write_beacon = rt2500pci_write_beacon, .fill_rxdone = rt2500pci_fill_rxdone, @@ -2059,28 +2060,28 @@ static const struct data_queue_desc rt2500pci_queue_rx = { .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2500pci_queue_tx = { .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2500pci_queue_bcn = { .entry_num = 1, .data_size = MGMT_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2500pci_queue_atim = { .entry_num = 8, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; 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, udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + rt2x00_err(rt2x00dev, "Indirect register access failed: offset=0x%.08x, value=0x%.08x\n", + offset, *reg); *reg = ~0; return 0; @@ -916,7 +916,7 @@ static int rt2500usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -1069,8 +1069,8 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -1353,7 +1353,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); @@ -1369,7 +1369,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); - EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); @@ -1378,7 +1378,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); - EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); @@ -1386,14 +1386,15 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, DEFAULT_RSSI_OFFSET); rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); - EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Calibrate offset: 0x%04x\n", + word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_BBPTUNE_THRESHOLD, 45); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE, word); - EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune: 0x%04x\n", word); } /* @@ -1408,7 +1409,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); - EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); } else { rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); @@ -1419,7 +1420,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_LOW, 0x48); rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); - EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r17: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); @@ -1427,7 +1428,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_LOW, 0x40); rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_HIGH, 0x80); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R24, word); - EEPROM(rt2x00dev, "BBPtune r24: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r24: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &word); @@ -1435,7 +1436,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_LOW, 0x40); rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_HIGH, 0x50); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R25, word); - EEPROM(rt2x00dev, "BBPtune r25: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r25: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &word); @@ -1443,7 +1444,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_LOW, 0x60); rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_HIGH, 0x6d); rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R61, word); - EEPROM(rt2x00dev, "BBPtune r61: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "BBPtune r61: 0x%04x\n", word); } return 0; @@ -1468,7 +1469,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_chip(rt2x00dev, RT2570, value, reg); if (((reg & 0xfff0) != 0) || ((reg & 0x0000000f) == 0)) { - ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RT chipset detected\n"); return -ENODEV; } @@ -1478,7 +1479,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF2525) && !rt2x00_rf(rt2x00dev, RF2525E) && !rt2x00_rf(rt2x00dev, RF5222)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); return -ENODEV; } 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) rt2x00_rf(rt2x00dev, RF3022)) return true; - WARNING(rt2x00dev, "Unknown RF chipset on rt305x\n"); + rt2x00_warn(rt2x00dev, "Unknown RF chipset on rt305x\n"); return false; } @@ -328,7 +328,7 @@ int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) msleep(1); } - ERROR(rt2x00dev, "Unstable hardware.\n"); + rt2x00_err(rt2x00dev, "Unstable hardware\n"); return -EBUSY; } EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); @@ -351,7 +351,7 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) msleep(10); } - ERROR(rt2x00dev, "WPDMA TX/RX busy [0x%08x].\n", reg); + rt2x00_err(rt2x00dev, "WPDMA TX/RX busy [0x%08x]\n", reg); return -EACCES; } EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); @@ -512,7 +512,7 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, } if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "PBF system register not ready.\n"); + rt2x00_err(rt2x00dev, "PBF system register not ready\n"); return -EBUSY; } @@ -542,6 +542,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, { __le32 *txwi = rt2800_drv_get_txwi(entry); u32 word; + int i; /* * Initialize TX Info descriptor @@ -584,14 +585,16 @@ void rt2800_write_tx_data(struct queue_entry *entry, rt2x00_desc_write(txwi, 1, word); /* - * Always write 0 to IV/EIV fields, hardware will insert the IV - * from the IVEIV register when TXD_W3_WIV is set to 0. + * Always write 0 to IV/EIV fields (word 2 and 3), hardware will insert + * the IV from the IVEIV register when TXD_W3_WIV is set to 0. * When TXD_W3_WIV is set to 1 it will use the IV data * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which * crypto entry in the registers should be used to encrypt the frame. + * + * Nulify all remaining words as well, we don't know how to program them. */ - _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); - _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); + for (i = 2; i < entry->queue->winfo_size / sizeof(__le32); i++) + _rt2x00_desc_write(txwi, i, 0); } EXPORT_SYMBOL_GPL(rt2800_write_tx_data); @@ -676,6 +679,10 @@ void rt2800_process_rxwi(struct queue_entry *entry, * Convert descriptor AGC value to RSSI value. */ rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); + /* + * Remove RXWI descriptor from start of the buffer. + */ + skb_pull(entry->skb, entry->queue->winfo_size); } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); @@ -766,6 +773,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) unsigned int beacon_base; unsigned int padding_len; u32 orig_reg, reg; + const int txwi_desc_size = entry->queue->winfo_size; /* * 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) /* * Add space for the TXWI in front of the skb. */ - memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); + memset(skb_push(entry->skb, txwi_desc_size), 0, txwi_desc_size); /* * Register descriptor details in skb frame descriptor. */ skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = entry->skb->data; - skbdesc->desc_len = TXWI_DESC_SIZE; + skbdesc->desc_len = txwi_desc_size; /* * 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) */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); /* skb freed by skb_pad() on failure */ entry->skb = NULL; rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); @@ -832,13 +840,14 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev, unsigned int beacon_base) { int i; + const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size; /* * For the Beacon base registers we only need to clear * the whole TXWI which (when set to 0) will invalidate * the entire beacon. */ - for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32)) + for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) rt2800_register_write(rt2x00dev, beacon_base + i, 0); } @@ -3147,7 +3156,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) { - rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel, + rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan, rt2x00dev->tx_power); } EXPORT_SYMBOL_GPL(rt2800_gain_calibration); @@ -3282,11 +3291,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { rt2800_config_channel(rt2x00dev, libconf->conf, &libconf->rf, &libconf->channel); - rt2800_config_txpower(rt2x00dev, libconf->conf->channel, + rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, libconf->conf->power_level); } if (flags & IEEE80211_CONF_CHANGE_POWER) - rt2800_config_txpower(rt2x00dev, libconf->conf->channel, + rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, libconf->conf->power_level); if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) rt2800_config_retry_limit(rt2x00dev, libconf); @@ -3860,7 +3869,7 @@ static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n"); return -EACCES; } @@ -3884,7 +3893,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -3924,7 +3933,7 @@ static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) } }; -static void rt2800_init_bbb_early(struct rt2x00_dev *rt2x00dev) +static void rt2800_init_bbp_early(struct rt2x00_dev *rt2x00dev) { rt2800_bbp_write(rt2x00dev, 65, 0x2C); rt2800_bbp_write(rt2x00dev, 66, 0x38); @@ -3950,7 +3959,7 @@ static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) u16 eeprom; u8 value; - rt2800_init_bbb_early(rt2x00dev); + rt2800_init_bbp_early(rt2x00dev); rt2800_bbp_read(rt2x00dev, 105, &value); rt2x00_set_field8(&value, BBP105_MLD, @@ -4332,8 +4341,17 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) return 0; } -static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, - bool bw40, u8 rfcsr24, u8 filter_target) +static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + + rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); + rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); + rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); +} + +static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, bool bw40, + u8 filter_target) { unsigned int i; u8 bbp; @@ -4341,6 +4359,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, u8 passband; u8 stopband; u8 overtuned = 0; + u8 rfcsr24 = (bw40) ? 0x27 : 0x07; rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24); @@ -4396,8 +4415,169 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, return rfcsr24; } +static void rt2800_rf_init_calibration(struct rt2x00_dev *rt2x00dev, + const unsigned int rf_reg) +{ + u8 rfcsr; + + rt2800_rfcsr_read(rt2x00dev, rf_reg, &rfcsr); + rt2x00_set_field8(&rfcsr, FIELD8(0x80), 1); + rt2800_rfcsr_write(rt2x00dev, rf_reg, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, FIELD8(0x80), 0); + rt2800_rfcsr_write(rt2x00dev, rf_reg, rfcsr); +} + +static void rt2800_rx_filter_calibration(struct rt2x00_dev *rt2x00dev) +{ + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u8 filter_tgt_bw20; + u8 filter_tgt_bw40; + u8 rfcsr, bbp; + + /* + * TODO: sync filter_tgt values with vendor driver + */ + if (rt2x00_rt(rt2x00dev, RT3070)) { + filter_tgt_bw20 = 0x16; + filter_tgt_bw40 = 0x19; + } else { + filter_tgt_bw20 = 0x13; + filter_tgt_bw40 = 0x15; + } + + drv_data->calibration_bw20 = + rt2800_init_rx_filter(rt2x00dev, false, filter_tgt_bw20); + drv_data->calibration_bw40 = + rt2800_init_rx_filter(rt2x00dev, true, filter_tgt_bw40); + + /* + * Save BBP 25 & 26 values for later use in channel switching (for 3052) + */ + rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); + rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); + + /* + * Set back to initial state + */ + rt2800_bbp_write(rt2x00dev, 24, 0); + + rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); + rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); + + /* + * Set BBP back to BW20 + */ + rt2800_bbp_read(rt2x00dev, 4, &bbp); + rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); + rt2800_bbp_write(rt2x00dev, 4, bbp); +} + +static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev) +{ + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u8 min_gain, rfcsr, bbp; + u16 eeprom; + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + + rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { + if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) + rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); + } + + min_gain = rt2x00_rt(rt2x00dev, RT3070) ? 1 : 2; + if (drv_data->txmixer_gain_24g >= min_gain) { + rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, + drv_data->txmixer_gain_24g); + } + + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + if (rt2x00_rt(rt2x00dev, RT3090)) { + /* Turn off unused DAC1 and ADC1 to reduce power consumption */ + rt2800_bbp_read(rt2x00dev, 138, &bbp); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) + rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) + rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); + rt2800_bbp_write(rt2x00dev, 138, bbp); + } + + if (rt2x00_rt(rt2x00dev, RT3070)) { + rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); + if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) + rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); + else + rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); + rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0); + rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0); + rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0); + rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); + } else if (rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3390)) { + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 15, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); + } +} + +static void rt2800_normal_mode_setup_5xxx(struct rt2x00_dev *rt2x00dev) +{ + u8 reg; + u16 eeprom; + + /* Turn off unused DAC1 and ADC1 to reduce power consumption */ + rt2800_bbp_read(rt2x00dev, 138, ®); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) + rt2x00_set_field8(®, BBP138_RX_ADC1, 0); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) + rt2x00_set_field8(®, BBP138_TX_DAC1, 1); + rt2800_bbp_write(rt2x00dev, 138, reg); + + rt2800_rfcsr_read(rt2x00dev, 38, ®); + rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 38, reg); + + rt2800_rfcsr_read(rt2x00dev, 39, ®); + rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 39, reg); + + rt2800_bbp4_mac_if_ctrl(rt2x00dev); + + rt2800_rfcsr_read(rt2x00dev, 30, ®); + rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); + rt2800_rfcsr_write(rt2x00dev, 30, reg); +} + static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) { + rt2800_rf_init_calibration(rt2x00dev, 30); + rt2800_rfcsr_write(rt2x00dev, 0, 0x50); rt2800_rfcsr_write(rt2x00dev, 1, 0x01); rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); @@ -4434,6 +4614,13 @@ static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) { + u8 rfcsr; + u16 eeprom; + u32 reg; + + /* XXX vendor driver do this only for 3070 */ + rt2800_rf_init_calibration(rt2x00dev, 30); + rt2800_rfcsr_write(rt2x00dev, 4, 0x40); rt2800_rfcsr_write(rt2x00dev, 5, 0x03); rt2800_rfcsr_write(rt2x00dev, 6, 0x02); @@ -4453,10 +4640,54 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 24, 0x16); rt2800_rfcsr_write(rt2x00dev, 25, 0x01); rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); + + if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + } else if (rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3090)) { + rt2800_rfcsr_write(rt2x00dev, 31, 0x14); + + rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); + rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); + + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); + else + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); + } + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + + rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); + rt2x00_set_field32(®, GPIO_SWITCH_5, 0); + rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); + } + + rt2800_rx_filter_calibration(rt2x00dev); + + if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || + rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) + rt2800_rfcsr_write(rt2x00dev, 27, 0x03); + + rt2800_led_open_drain_enable(rt2x00dev); + rt2800_normal_mode_setup_3xxx(rt2x00dev); } static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) { + u8 rfcsr; + + rt2800_rf_init_calibration(rt2x00dev, 2); + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); rt2800_rfcsr_write(rt2x00dev, 2, 0x80); rt2800_rfcsr_write(rt2x00dev, 3, 0x08); @@ -4503,10 +4734,19 @@ static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 59, 0x09); rt2800_rfcsr_write(rt2x00dev, 60, 0x45); rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); + + rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); + rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); + + rt2800_led_open_drain_enable(rt2x00dev); + rt2800_normal_mode_setup_3xxx(rt2x00dev); } static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) { + rt2800_rf_init_calibration(rt2x00dev, 30); + rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); rt2800_rfcsr_write(rt2x00dev, 1, 0x23); rt2800_rfcsr_write(rt2x00dev, 2, 0x50); @@ -4570,10 +4810,18 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 61, 0x00); rt2800_rfcsr_write(rt2x00dev, 62, 0x00); rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + + rt2800_rx_filter_calibration(rt2x00dev); + rt2800_led_open_drain_enable(rt2x00dev); + rt2800_normal_mode_setup_3xxx(rt2x00dev); } static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) { + u32 reg; + + rt2800_rf_init_calibration(rt2x00dev, 30); + rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); @@ -4606,10 +4854,27 @@ static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); rt2800_rfcsr_write(rt2x00dev, 30, 0x20); rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); + + rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); + rt2x00_set_field32(®, GPIO_SWITCH_5, 0); + rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); + + rt2800_rx_filter_calibration(rt2x00dev); + + if (rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) + rt2800_rfcsr_write(rt2x00dev, 27, 0x03); + + rt2800_led_open_drain_enable(rt2x00dev); + rt2800_normal_mode_setup_3xxx(rt2x00dev); } static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) { + u8 rfcsr; + u32 reg; + + rt2800_rf_init_calibration(rt2x00dev, 30); + rt2800_rfcsr_write(rt2x00dev, 0, 0x70); rt2800_rfcsr_write(rt2x00dev, 1, 0x81); rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); @@ -4641,10 +4906,30 @@ static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); rt2800_rfcsr_write(rt2x00dev, 30, 0x09); rt2800_rfcsr_write(rt2x00dev, 31, 0x10); + + rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); + rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); + + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + msleep(1); + rt2800_register_read(rt2x00dev, LDO_CFG0, ®); + rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); + rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); + rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + + rt2800_rx_filter_calibration(rt2x00dev); + rt2800_led_open_drain_enable(rt2x00dev); + rt2800_normal_mode_setup_3xxx(rt2x00dev); } static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) { + rt2800_rf_init_calibration(rt2x00dev, 2); + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); rt2800_rfcsr_write(rt2x00dev, 2, 0x80); rt2800_rfcsr_write(rt2x00dev, 3, 0x88); @@ -4725,10 +5010,16 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); rt2800_rfcsr_write(rt2x00dev, 62, 0x00); rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + + rt2800_normal_mode_setup_5xxx(rt2x00dev); + + rt2800_led_open_drain_enable(rt2x00dev); } static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) { + rt2800_rf_init_calibration(rt2x00dev, 2); + rt2800_rfcsr_write(rt2x00dev, 1, 0x17); rt2800_rfcsr_write(rt2x00dev, 2, 0x80); rt2800_rfcsr_write(rt2x00dev, 3, 0x88); @@ -4788,12 +5079,15 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 61, 0x91); rt2800_rfcsr_write(rt2x00dev, 62, 0x39); rt2800_rfcsr_write(rt2x00dev, 63, 0x07); + + rt2800_normal_mode_setup_5xxx(rt2x00dev); + + rt2800_led_open_drain_enable(rt2x00dev); } static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) { - u8 reg; - u16 eeprom; + rt2800_rf_init_calibration(rt2x00dev, 30); rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); rt2800_rfcsr_write(rt2x00dev, 3, 0x08); @@ -4823,83 +5117,23 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) rt2800_adjust_freq_offset(rt2x00dev); - rt2800_bbp_read(rt2x00dev, 138, ®); - - /* Turn off unused DAC1 and ADC1 to reduce power consumption */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) - rt2x00_set_field8(®, BBP138_RX_ADC1, 0); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) - rt2x00_set_field8(®, BBP138_TX_DAC1, 1); - - rt2800_bbp_write(rt2x00dev, 138, reg); - /* Enable DC filter */ if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); - rt2800_rfcsr_read(rt2x00dev, 38, ®); - rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 38, reg); - - rt2800_rfcsr_read(rt2x00dev, 39, ®); - rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 39, reg); + rt2800_normal_mode_setup_5xxx(rt2x00dev); - rt2800_bbp4_mac_if_ctrl(rt2x00dev); + if (rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C)) + rt2800_rfcsr_write(rt2x00dev, 27, 0x03); - rt2800_rfcsr_read(rt2x00dev, 30, ®); - rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); - rt2800_rfcsr_write(rt2x00dev, 30, reg); + rt2800_led_open_drain_enable(rt2x00dev); } -static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) +static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { - struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; - u8 rfcsr; - u8 bbp; - u32 reg; - u16 eeprom; - - if (!rt2x00_rt(rt2x00dev, RT3070) && - !rt2x00_rt(rt2x00dev, RT3071) && - !rt2x00_rt(rt2x00dev, RT3090) && - !rt2x00_rt(rt2x00dev, RT3290) && - !rt2x00_rt(rt2x00dev, RT3352) && - !rt2x00_rt(rt2x00dev, RT3390) && - !rt2x00_rt(rt2x00dev, RT3572) && - !rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392) && - !rt2x00_rt(rt2x00dev, RT5392) && - !rt2x00_rt(rt2x00dev, RT5592) && - !rt2800_is_305x_soc(rt2x00dev)) - return 0; - - /* - * Init RF calibration. - */ - - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { - rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); - rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); - msleep(1); - rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); - } else { - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - msleep(1); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - } - if (rt2800_is_305x_soc(rt2x00dev)) { rt2800_init_rfcsr_305x_soc(rt2x00dev); - return 0; + return; } switch (rt2x00dev->chip.rt) { @@ -4928,202 +5162,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) break; case RT5592: rt2800_init_rfcsr_5592(rt2x00dev); - return 0; - } - - if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { - rt2800_register_read(rt2x00dev, LDO_CFG0, ®); - rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); - rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); - rt2800_register_write(rt2x00dev, LDO_CFG0, reg); - } else if (rt2x00_rt(rt2x00dev, RT3071) || - rt2x00_rt(rt2x00dev, RT3090)) { - rt2800_rfcsr_write(rt2x00dev, 31, 0x14); - - rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); - rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); - - rt2800_register_read(rt2x00dev, LDO_CFG0, ®); - rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); - if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST)) - rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); - else - rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); - } - rt2800_register_write(rt2x00dev, LDO_CFG0, reg); - - rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); - rt2x00_set_field32(®, GPIO_SWITCH_5, 0); - rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); - } else if (rt2x00_rt(rt2x00dev, RT3390)) { - rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); - rt2x00_set_field32(®, GPIO_SWITCH_5, 0); - rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); - } else if (rt2x00_rt(rt2x00dev, RT3572)) { - rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); - rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); - - rt2800_register_read(rt2x00dev, LDO_CFG0, ®); - rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); - rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); - rt2800_register_write(rt2x00dev, LDO_CFG0, reg); - msleep(1); - rt2800_register_read(rt2x00dev, LDO_CFG0, ®); - rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); - rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); - rt2800_register_write(rt2x00dev, LDO_CFG0, reg); - } - - /* - * Set RX Filter calibration for 20MHz and 40MHz - */ - if (rt2x00_rt(rt2x00dev, RT3070)) { - drv_data->calibration_bw20 = - rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16); - drv_data->calibration_bw40 = - rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); - } else if (rt2x00_rt(rt2x00dev, RT3071) || - rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3352) || - rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT3572)) { - drv_data->calibration_bw20 = - rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); - drv_data->calibration_bw40 = - rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); - } - - /* - * Save BBP 25 & 26 values for later use in channel switching - */ - rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); - rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); - - if (!rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392)) { - /* - * Set back to initial state - */ - rt2800_bbp_write(rt2x00dev, 24, 0); - - rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); - rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); - - /* - * Set BBP back to BW20 - */ - rt2800_bbp_read(rt2x00dev, 4, &bbp); - rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); - rt2800_bbp_write(rt2x00dev, 4, bbp); - } - - if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || - rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E) || - rt2x00_rt_rev_lt(rt2x00dev, RT5592, REV_RT5592C)) - rt2800_rfcsr_write(rt2x00dev, 27, 0x03); - - rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); - rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); - rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); - - if (!rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392)) { - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); - if (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, - &rt2x00dev->cap_flags)) - rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); - } - rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, - drv_data->txmixer_gain_24g); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); - } - - if (rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT5592)) { - rt2800_bbp_read(rt2x00dev, 138, &bbp); - - /* Turn off unused DAC1 and ADC1 to reduce power consumption */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) - rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) - rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); - - rt2800_bbp_write(rt2x00dev, 138, bbp); - } - - if (rt2x00_rt(rt2x00dev, RT3071) || - rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390)) { - rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); - rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); - rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); - rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 15, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); - } - - if (rt2x00_rt(rt2x00dev, RT3070)) { - rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); - if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) - rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); - else - rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); - rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0); - rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0); - rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0); - rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); - } - - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); - rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); - } - - if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || - rt2x00_rt(rt2x00dev, RT5592)) { - rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + break; } - - return 0; } int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) @@ -5149,10 +5189,11 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) } msleep(1); - if (unlikely(rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + if (unlikely(rt2800_init_bbp(rt2x00dev))) return -EIO; + rt2800_init_rfcsr(rt2x00dev); + if (rt2x00_is_usb(rt2x00dev) && (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || @@ -5312,7 +5353,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word); @@ -5321,7 +5362,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1); rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word); - EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); } else if (rt2x00_rt(rt2x00dev, RT2860) || rt2x00_rt(rt2x00dev, RT2872)) { /* @@ -5350,14 +5391,14 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0); rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word); - EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); if ((word & 0x00ff) == 0x00ff) { rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); - EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); } if ((word & 0xff00) == 0xff00) { rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, @@ -5367,7 +5408,7 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8); - EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Led Mode: 0x%04x\n", word); } /* @@ -5473,7 +5514,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF5592: break; default: - ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", rf); + rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", + rf); return -ENODEV; } @@ -6062,9 +6104,8 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev) case RT5592: break; default: - ERROR(rt2x00dev, - "Invalid RT chipset 0x%04x, rev %04x detected.\n", - rt, rev); + rt2x00_err(rt2x00dev, "Invalid RT chipset 0x%04x, rev %04x detected\n", + rt, rev); return -ENODEV; } @@ -6323,7 +6364,8 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_OPERATIONAL: break; default: - WARNING((struct rt2x00_dev *)hw->priv, "Unknown AMPDU action\n"); + rt2x00_warn((struct rt2x00_dev *)hw->priv, + "Unknown AMPDU action\n"); } return ret; @@ -6340,7 +6382,7 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle); 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) return; for (i = 0; i < 200; i++) { - rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); + rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, ®); if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) || (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) } if (i == 200) - ERROR(rt2x00dev, "MCU request failed, no response from hardware\n"); + rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n"); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) @@ -116,7 +116,7 @@ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg; - rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); 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) rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, !!eeprom->reg_chip_select); - rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); } static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) @@ -146,7 +146,7 @@ static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) struct eeprom_93cx6 eeprom; u32 reg; - rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt2800pci_eepromregister_read; @@ -210,20 +210,20 @@ static void rt2800pci_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); - rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); + rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); break; default: break; @@ -241,13 +241,13 @@ static void rt2800pci_kick_queue(struct data_queue *queue) case QID_AC_BE: case QID_AC_BK: entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), - entry->entry_idx); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), + entry->entry_idx); break; case QID_MGMT: entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5), - entry->entry_idx); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5), + entry->entry_idx); break; default: break; @@ -261,20 +261,20 @@ static void rt2800pci_stop_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); - rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg); + rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); /* * Wait for current invocation to finish. The tasklet @@ -314,19 +314,19 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, */ reg = 0; rt2x00_set_field32(®, PBF_SYS_CTRL_HOST_RAM_WRITE, 1); - rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg); /* * Write firmware to device. */ - rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, - data, len); + rt2x00mmio_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, + data, len); - rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); - rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); - rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); return 0; } @@ -336,7 +336,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, */ static bool rt2800pci_get_entry_state(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word; if (entry->queue->qid == QID_RX) { @@ -352,7 +352,7 @@ static bool rt2800pci_get_entry_state(struct queue_entry *entry) static void rt2800pci_clear_entry(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; u32 word; @@ -370,8 +370,8 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) * Set RX IDX in register to inform hardware that we have * handled this entry and it is available for reuse again. */ - rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, - entry->entry_idx); + rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, + entry->entry_idx); } else { rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); @@ -381,60 +381,65 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) { - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; /* * Initialize registers. */ entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0, - rt2x00dev->tx[0].limit); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0); + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, + rt2x00dev->tx[0].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1, - rt2x00dev->tx[1].limit); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0); + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, + rt2x00dev->tx[1].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); entry_priv = rt2x00dev->tx[2].entries[0].priv_data; - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2, - rt2x00dev->tx[2].limit); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0); + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, + rt2x00dev->tx[2].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); entry_priv = rt2x00dev->tx[3].entries[0].priv_data; - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3, - rt2x00dev->tx[3].limit); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0); - - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR4, 0); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT4, 0); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX4, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX4, 0); - - rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR5, 0); - rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT5, 0); - rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX5, 0); - rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, + rt2x00dev->tx[3].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); + + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0); + + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0); entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, - rt2x00dev->rx[0].limit); - rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, - rt2x00dev->rx[0].limit - 1); - rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0); + rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT, + rt2x00dev->rx[0].limit); + rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, + rt2x00dev->rx[0].limit - 1); + rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0); rt2800_disable_wpdma(rt2x00dev); - rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0); + rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0); return 0; } @@ -453,8 +458,8 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { - rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); } spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); @@ -466,7 +471,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); } - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); if (state == STATE_RADIO_IRQ_OFF) { @@ -488,7 +493,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) /* * Reset DMA indexes */ - rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, ®); + rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, ®); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); @@ -496,29 +501,29 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg); + rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); if (rt2x00_is_pcie(rt2x00dev) && (rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392))) { - rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); - rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg); + rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg); } - rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); - rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); return 0; } @@ -538,8 +543,8 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) return retval; /* After resume MCU_BOOT_SIGNAL will trash these. */ - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); @@ -554,8 +559,8 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) { if (rt2x00_is_soc(rt2x00dev)) { rt2800_disable_radio(rt2x00dev); - rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); } } @@ -567,10 +572,10 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, 0, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); } else if (state == STATE_SLEEP) { - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, - 0xffffffff); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, - 0xffffffff); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, + 0xffffffff); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, + 0xffffffff); rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, 0xff, 0x01); } @@ -611,8 +616,8 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -629,7 +634,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -683,7 +688,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, static void rt2800pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; __le32 *rxd = entry_priv->desc; u32 word; @@ -730,11 +735,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure that is at the start of the buffer. */ rt2800_process_rxwi(entry, rxdesc); - - /* - * Remove RXWI descriptor from start of buffer. - */ - skb_pull(entry->skb, RXWI_DESC_SIZE); } /* @@ -843,8 +843,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * Unknown queue, this shouldn't happen. Just drop * this tx status. */ - WARNING(rt2x00dev, "Got TX status report with " - "unexpected pid %u, dropping\n", qid); + rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", + qid); break; } @@ -854,8 +854,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * The queue is NULL, this shouldn't happen. Stop * processing here and drop the tx status */ - WARNING(rt2x00dev, "Got TX status for an unavailable " - "queue %u, dropping\n", qid); + rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", + qid); break; } @@ -864,8 +864,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) * The queue is empty. Stop processing here * and drop the tx status. */ - WARNING(rt2x00dev, "Got TX status for an empty " - "queue %u, dropping\n", qid); + rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", + qid); break; } @@ -883,9 +883,8 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, &status, rt2800pci_txdone_match_first)) { - WARNING(rt2x00dev, "No frame found for TX " - "status on queue %u, dropping\n", - qid); + rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", + qid); break; } } @@ -914,9 +913,9 @@ static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, * access needs locking. */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 1); - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -957,15 +956,15 @@ static void rt2800pci_tbtt_tasklet(unsigned long data) * interval every 64 beacons by 64us to mitigate this effect. */ if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { - rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, (rt2x00dev->beacon_int * 16) - 1); - rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { - rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, (rt2x00dev->beacon_int * 16)); - rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); } drv_data->tbtt_tick++; drv_data->tbtt_tick %= BCN_TBTT_OFFSET; @@ -978,7 +977,7 @@ static void rt2800pci_tbtt_tasklet(unsigned long data) static void rt2800pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2x00pci_rxdone(rt2x00dev)) + if (rt2x00mmio_rxdone(rt2x00dev)) tasklet_schedule(&rt2x00dev->rxdone_tasklet); else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); @@ -1016,14 +1015,13 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * need to lock the kfifo. */ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { - rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status); + rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) break; if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { - WARNING(rt2x00dev, "TX status FIFO overrun," - "drop tx status report.\n"); + rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); break; } } @@ -1038,8 +1036,8 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) u32 reg, mask; /* Read status and ACK all interrupts */ - rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); if (!reg) return IRQ_NONE; @@ -1079,9 +1077,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) * the tasklet will reenable the appropriate interrupts. */ spin_lock(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); reg &= mask; - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock(&rt2x00dev->irqmask_lock); return IRQ_HANDLED; @@ -1132,13 +1130,13 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { }; static const struct rt2800_ops rt2800pci_rt2800_ops = { - .register_read = rt2x00pci_register_read, - .register_read_lock = rt2x00pci_register_read, /* same for PCI */ - .register_write = rt2x00pci_register_write, - .register_write_lock = rt2x00pci_register_write, /* same for PCI */ - .register_multiread = rt2x00pci_register_multiread, - .register_multiwrite = rt2x00pci_register_multiwrite, - .regbusy_read = rt2x00pci_regbusy_read, + .register_read = rt2x00mmio_register_read, + .register_read_lock = rt2x00mmio_register_read, /* same for PCI */ + .register_write = rt2x00mmio_register_write, + .register_write_lock = rt2x00mmio_register_write, /* same for PCI */ + .register_multiread = rt2x00mmio_register_multiread, + .register_multiwrite = rt2x00mmio_register_multiwrite, + .regbusy_read = rt2x00mmio_regbusy_read, .read_eeprom = rt2800pci_read_eeprom, .hwcrypt_disabled = rt2800pci_hwcrypt_disabled, .drv_write_firmware = rt2800pci_write_firmware, @@ -1157,8 +1155,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .get_firmware_name = rt2800pci_get_firmware_name, .check_firmware = rt2800_check_firmware, .load_firmware = rt2800_load_firmware, - .initialize = rt2x00pci_initialize, - .uninitialize = rt2x00pci_uninitialize, + .initialize = rt2x00mmio_initialize, + .uninitialize = rt2x00mmio_uninitialize, .get_entry_state = rt2800pci_get_entry_state, .clear_entry = rt2800pci_clear_entry, .set_device_state = rt2800pci_set_device_state, @@ -1171,7 +1169,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .start_queue = rt2800pci_start_queue, .kick_queue = rt2800pci_kick_queue, .stop_queue = rt2800pci_stop_queue, - .flush_queue = rt2x00pci_flush_queue, + .flush_queue = rt2x00mmio_flush_queue, .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, @@ -1192,21 +1190,24 @@ static const struct data_queue_desc rt2800pci_queue_rx = { .entry_num = 128, .data_size = AGGREGATION_SIZE, .desc_size = RXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .winfo_size = RXWI_DESC_SIZE, + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2800pci_queue_tx = { .entry_num = 64, .data_size = AGGREGATION_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .winfo_size = TXWI_DESC_SIZE, + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt2800pci_queue_bcn = { .entry_num = 8, .data_size = 0, /* No DMA required for beacons */ - .desc_size = TXWI_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .desc_size = TXD_DESC_SIZE, + .winfo_size = TXWI_DESC_SIZE, + .priv_size = sizeof(struct queue_entry_priv_mmio), }; 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) tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); if (unlikely(tout)) - WARNING(entry->queue->rt2x00dev, - "TX status timeout for entry %d in queue %d\n", - entry->entry_idx, entry->queue->qid); + rt2x00_warn(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); return tout; } @@ -154,7 +154,8 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, bool valid; if (urb_status) { - WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); + rt2x00_warn(rt2x00dev, "TX status read failed %d\n", + urb_status); goto stop_reading; } @@ -162,7 +163,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); if (valid) { if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) - WARNING(rt2x00dev, "TX status FIFO overrun\n"); + rt2x00_warn(rt2x00dev, "TX status FIFO overrun\n"); queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); @@ -269,7 +270,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, 0, USB_MODE_FIRMWARE, REGISTER_TIMEOUT_FIRMWARE); if (status < 0) { - ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); + rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n"); return status; } @@ -392,8 +393,8 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -408,8 +409,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { - WARNING(rt2x00dev, "TX HW queue 0 timed out," - " invoke forced kick\n"); + rt2x00_warn(rt2x00dev, "TX HW queue 0 timed out, invoke forced kick\n"); rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); @@ -424,8 +424,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { - WARNING(rt2x00dev, "TX HW queue 1 timed out," - " invoke forced kick\n"); + rt2x00_warn(rt2x00dev, "TX HW queue 1 timed out, invoke forced kick\n"); rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); @@ -485,7 +484,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, */ skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = txi; - skbdesc->desc_len = entry->queue->desc_size; + skbdesc->desc_len = TXINFO_DESC_SIZE + entry->queue->winfo_size; } /* @@ -540,9 +539,9 @@ rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { - DEBUG(entry->queue->rt2x00dev, - "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); + rt2x00_dbg(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); return TXDONE_UNKNOWN; } @@ -566,8 +565,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(rt2x00queue_empty(queue))) { - WARNING(rt2x00dev, "Got TX status for an empty " - "queue %u, dropping\n", qid); + rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", + qid); break; } @@ -575,8 +574,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { - WARNING(rt2x00dev, "Data pending for entry %u " - "in queue %u\n", entry->entry_idx, qid); + rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", + entry->entry_idx, qid); break; } @@ -677,8 +676,8 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, */ if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) { - ERROR(entry->queue->rt2x00dev, - "Bad frame size %d, forcing to 0\n", rx_pkt_len); + rt2x00_err(entry->queue->rt2x00dev, + "Bad frame size %d, forcing to 0\n", rx_pkt_len); return; } @@ -730,11 +729,6 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure. */ rt2800_process_rxwi(entry, rxdesc); - - /* - * Remove RXWI descriptor from start of buffer. - */ - skb_pull(entry->skb, entry->queue->desc_size - RXINFO_DESC_SIZE); } /* @@ -858,21 +852,24 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { static const struct data_queue_desc rt2800usb_queue_rx = { .entry_num = 128, .data_size = AGGREGATION_SIZE, - .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE, + .desc_size = RXINFO_DESC_SIZE, + .winfo_size = RXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_tx = { .entry_num = 16, .data_size = AGGREGATION_SIZE, - .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, + .desc_size = TXINFO_DESC_SIZE, + .winfo_size = TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_bcn = { .entry_num = 8, .data_size = MGMT_FRAME_SIZE, - .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, + .desc_size = TXINFO_DESC_SIZE, + .winfo_size = TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), }; @@ -898,21 +895,24 @@ static const struct rt2x00_ops rt2800usb_ops = { static const struct data_queue_desc rt2800usb_queue_rx_5592 = { .entry_num = 128, .data_size = AGGREGATION_SIZE, - .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE_5592, + .desc_size = RXINFO_DESC_SIZE, + .winfo_size = RXWI_DESC_SIZE_5592, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_tx_5592 = { .entry_num = 16, .data_size = AGGREGATION_SIZE, - .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, + .desc_size = TXINFO_DESC_SIZE, + .winfo_size = TXWI_DESC_SIZE_5592, .priv_size = sizeof(struct queue_entry_priv_usb), }; static const struct data_queue_desc rt2800usb_queue_bcn_5592 = { .entry_num = 8, .data_size = MGMT_FRAME_SIZE, - .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, + .desc_size = TXINFO_DESC_SIZE, + .winfo_size = TXWI_DESC_SIZE_5592, .priv_size = sizeof(struct queue_entry_priv_usb), }; 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 @@ #define DRV_VERSION "2.3.0" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" -/* - * Debug definitions. +/* Debug definitions. * Debug output has to be enabled during compile time. */ -#define DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, __args...) \ - printk(__kernlvl "%s -> %s: %s - " __msg, \ - wiphy_name((__dev)->hw->wiphy), __func__, __lvl, ##__args) - -#define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ - printk(__kernlvl "%s -> %s: %s - " __msg, \ - KBUILD_MODNAME, __func__, __lvl, ##__args) - #ifdef CONFIG_RT2X00_DEBUG -#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args) -#else -#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ - do { } while (0) +#define DEBUG #endif /* CONFIG_RT2X00_DEBUG */ -/* - * Various debug levels. - * The debug levels PANIC and ERROR both indicate serious problems, - * for this reason they should never be ignored. - * The special ERROR_PROBE message is for messages that are generated - * when the rt2x00_dev is not yet initialized. +/* Utility printing macros + * rt2x00_probe_err is for messages when rt2x00_dev is uninitialized */ -#define PANIC(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_CRIT, "Panic", __msg, ##__args) -#define ERROR(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_ERR, "Error", __msg, ##__args) -#define ERROR_PROBE(__msg, __args...) \ - DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args) -#define WARNING(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_WARNING, "Warning", __msg, ##__args) -#define INFO(__dev, __msg, __args...) \ - DEBUG_PRINTK_MSG(__dev, KERN_INFO, "Info", __msg, ##__args) -#define DEBUG(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args) -#define EEPROM(__dev, __msg, __args...) \ - DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) +#define rt2x00_probe_err(fmt, ...) \ + printk(KERN_ERR KBUILD_MODNAME ": %s: Error - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_err(dev, fmt, ...) \ + wiphy_err((dev)->hw->wiphy, "%s: Error - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_warn(dev, fmt, ...) \ + wiphy_warn((dev)->hw->wiphy, "%s: Warning - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_info(dev, fmt, ...) \ + wiphy_info((dev)->hw->wiphy, "%s: Info - " fmt, \ + __func__, ##__VA_ARGS__) + +/* Various debug levels */ +#define rt2x00_dbg(dev, fmt, ...) \ + wiphy_dbg((dev)->hw->wiphy, "%s: Debug - " fmt, \ + __func__, ##__VA_ARGS__) +#define rt2x00_eeprom_dbg(dev, fmt, ...) \ + wiphy_dbg((dev)->hw->wiphy, "%s: EEPROM recovery - " fmt, \ + __func__, ##__VA_ARGS__) /* * Duration calculations @@ -1101,9 +1090,9 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, rt2x00dev->chip.rf = rf; rt2x00dev->chip.rev = rev; - INFO(rt2x00dev, - "Chipset detected - rt: %04x, rf: %04x, rev: %04x.\n", - rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); + rt2x00_info(rt2x00dev, "Chipset detected - rt: %04x, rf: %04x, rev: %04x\n", + rt2x00dev->chip.rt, rt2x00dev->chip.rf, + rt2x00dev->chip.rev); } static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, @@ -1112,15 +1101,16 @@ static inline void rt2x00_set_rt(struct rt2x00_dev *rt2x00dev, rt2x00dev->chip.rt = rt; rt2x00dev->chip.rev = rev; - INFO(rt2x00dev, "RT chipset %04x, rev %04x detected\n", - rt2x00dev->chip.rt, rt2x00dev->chip.rev); + rt2x00_info(rt2x00dev, "RT chipset %04x, rev %04x detected\n", + rt2x00dev->chip.rt, rt2x00dev->chip.rev); } static inline void rt2x00_set_rf(struct rt2x00_dev *rt2x00dev, const u16 rf) { rt2x00dev->chip.rf = rf; - INFO(rt2x00dev, "RF chipset %04x detected\n", rt2x00dev->chip.rf); + rt2x00_info(rt2x00dev, "RF chipset %04x detected\n", + rt2x00dev->chip.rf); } 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, /* * Initialize center channel to current channel. */ - center_channel = spec->channels[conf->channel->hw_value].channel; + center_channel = spec->channels[conf->chandef.chan->hw_value].channel; /* * Adjust center channel to HT40+ and HT40- operation. @@ -199,7 +199,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, return i; WARN_ON(1); - return conf->channel->hw_value; + return conf->chandef.chan->hw_value; } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, @@ -227,7 +227,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, hw_value = rt2x00ht_center_channel(rt2x00dev, conf); } else { clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); - hw_value = conf->channel->hw_value; + hw_value = conf->chandef.chan->hw_value; } memcpy(&libconf.rf, @@ -279,8 +279,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, else clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); - rt2x00dev->curr_band = conf->channel->band; - rt2x00dev->curr_freq = conf->channel->center_freq; + rt2x00dev->curr_band = conf->chandef.chan->band; + rt2x00dev->curr_freq = conf->chandef.chan->center_freq; rt2x00dev->tx_power = conf->power_level; rt2x00dev->short_retry = conf->short_frame_max_tx_count; 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, do_gettimeofday(×tamp); if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { - DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); + rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n"); return; } @@ -185,7 +185,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len, GFP_ATOMIC); if (!skbcopy) { - DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); + rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n"); return; } @@ -657,7 +657,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); if (!intf) { - ERROR(rt2x00dev, "Failed to allocate debug handler.\n"); + rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n"); return; } @@ -760,7 +760,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) exit: rt2x00debug_deregister(rt2x00dev); - ERROR(rt2x00dev, "Failed to register debug handler.\n"); + rt2x00_err(rt2x00dev, "Failed to register debug handler\n"); } 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) return; if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) - ERROR(rt2x00dev, "Device failed to wakeup.\n"); + rt2x00_err(rt2x00dev, "Device failed to wakeup\n"); clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); } @@ -673,9 +673,8 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, break; } - WARNING(rt2x00dev, "Frame received with unrecognized signal, " - "mode=0x%.4x, signal=0x%.4x, type=%d.\n", - rxdesc->rate_mode, signal, type); + rt2x00_warn(rt2x00dev, "Frame received with unrecognized signal, mode=0x%.4x, signal=0x%.4x, type=%d\n", + rxdesc->rate_mode, signal, type); return 0; } @@ -720,8 +719,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) */ if (unlikely(rxdesc.size == 0 || rxdesc.size > entry->queue->data_size)) { - ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", - rxdesc.size, entry->queue->data_size); + rt2x00_err(rt2x00dev, "Wrong frame size %d max %d\n", + rxdesc.size, entry->queue->data_size); dev_kfree_skb(entry->skb); goto renew_skb; } @@ -1006,7 +1005,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, exit_free_channels: kfree(channels); - ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); + rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n"); return -ENOMEM; } @@ -1337,7 +1336,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) */ retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); if (retval) { - ERROR(rt2x00dev, "Failed to allocate device.\n"); + rt2x00_err(rt2x00dev, "Failed to allocate device\n"); goto exit; } @@ -1353,7 +1352,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) */ retval = rt2x00lib_probe_hw(rt2x00dev); if (retval) { - ERROR(rt2x00dev, "Failed to initialize hw.\n"); + rt2x00_err(rt2x00dev, "Failed to initialize hw\n"); goto exit; } @@ -1451,7 +1450,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); #ifdef CONFIG_PM int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) { - DEBUG(rt2x00dev, "Going to sleep.\n"); + rt2x00_dbg(rt2x00dev, "Going to sleep\n"); /* * Prevent mac80211 from accessing driver while suspended. @@ -1482,8 +1481,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) * device is as good as disabled. */ if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) - WARNING(rt2x00dev, "Device failed to enter sleep state, " - "continue suspending.\n"); + rt2x00_warn(rt2x00dev, "Device failed to enter sleep state, continue suspending\n"); return 0; } @@ -1491,7 +1489,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend); int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) { - DEBUG(rt2x00dev, "Waking up.\n"); + rt2x00_dbg(rt2x00dev, "Waking up\n"); /* * 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) */ fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev); if (!fw_name) { - ERROR(rt2x00dev, - "Invalid firmware filename.\n" - "Please file bug report to %s.\n", DRV_PROJECT); + rt2x00_err(rt2x00dev, + "Invalid firmware filename\n" + "Please file bug report to %s\n", DRV_PROJECT); return -EINVAL; } - INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name); + rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); retval = request_firmware(&fw, fw_name, device); if (retval) { - ERROR(rt2x00dev, "Failed to request Firmware.\n"); + rt2x00_err(rt2x00dev, "Failed to request Firmware\n"); return retval; } if (!fw || !fw->size || !fw->data) { - ERROR(rt2x00dev, "Failed to read Firmware.\n"); + rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); release_firmware(fw); return -ENOENT; } - INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", - fw->data[fw->size - 4], fw->data[fw->size - 3]); + rt2x00_info(rt2x00dev, "Firmware detected - version: %d.%d\n", + fw->data[fw->size - 4], fw->data[fw->size - 3]); snprintf(rt2x00dev->hw->wiphy->fw_version, sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", fw->data[fw->size - 4], fw->data[fw->size - 3]); @@ -73,15 +73,14 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) case FW_OK: break; case FW_BAD_CRC: - ERROR(rt2x00dev, "Firmware checksum error.\n"); + rt2x00_err(rt2x00dev, "Firmware checksum error\n"); goto exit; case FW_BAD_LENGTH: - ERROR(rt2x00dev, - "Invalid firmware file length (len=%zu)\n", fw->size); + rt2x00_err(rt2x00dev, "Invalid firmware file length (len=%zu)\n", + fw->size); goto exit; case FW_BAD_VERSION: - ERROR(rt2x00dev, - "Current firmware does not support detected chipset.\n"); + rt2x00_err(rt2x00dev, "Current firmware does not support detected chipset\n"); goto exit; } 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, retval = led_classdev_register(device, &led->led_dev); if (retval) { - ERROR(rt2x00dev, "Failed to register led handler.\n"); + rt2x00_err(rt2x00dev, "Failed to register led handler\n"); return retval; } 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, skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom); if (unlikely(!skb)) { - WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n"); + rt2x00_warn(rt2x00dev, "Failed to create RTS/CTS frame\n"); return -ENOMEM; } @@ -93,7 +93,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, retval = rt2x00queue_write_tx_frame(queue, skb, true); if (retval) { dev_kfree_skb_any(skb); - WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); + rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n"); } return retval; @@ -126,9 +126,9 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(!queue)) { - ERROR(rt2x00dev, - "Attempt to send packet over invalid queue %d.\n" - "Please file bug report to %s.\n", qid, DRV_PROJECT); + rt2x00_err(rt2x00dev, + "Attempt to send packet over invalid queue %d\n" + "Please file bug report to %s\n", qid, DRV_PROJECT); goto exit_free_skb; } @@ -731,9 +731,10 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, queue->aifs = params->aifs; queue->txop = params->txop; - DEBUG(rt2x00dev, - "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n", - queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop); + rt2x00_dbg(rt2x00dev, + "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d\n", + queue_idx, queue->cw_min, queue->cw_max, queue->aifs, + queue->txop); return 0; } 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 @@ /* * Register access. */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg) +int rt2x00mmio_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg) { unsigned int i; @@ -45,7 +45,7 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, return 0; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, offset, reg); + rt2x00mmio_register_read(rt2x00dev, offset, reg); if (!rt2x00_get_field32(*reg, field)) return 1; udelay(REGISTER_BUSY_DELAY); @@ -57,13 +57,13 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, return 0; } -EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); +EXPORT_SYMBOL_GPL(rt2x00mmio_regbusy_read); -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) +bool rt2x00mmio_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue = rt2x00dev->rx; struct queue_entry *entry; - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; struct skb_frame_desc *skbdesc; int max_rx = 16; @@ -96,24 +96,24 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) return !max_rx; } -EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); +EXPORT_SYMBOL_GPL(rt2x00mmio_rxdone); -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) +void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop) { unsigned int i; for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) msleep(10); } -EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); +EXPORT_SYMBOL_GPL(rt2x00mmio_flush_queue); /* * Device initialization handlers. */ -static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static int rt2x00mmio_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) { - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; void *addr; dma_addr_t dma; unsigned int i; @@ -141,10 +141,10 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, return 0; } -static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static void rt2x00mmio_free_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) { - struct queue_entry_priv_pci *entry_priv = + struct queue_entry_priv_mmio *entry_priv = queue->entries[0].priv_data; if (entry_priv->desc) @@ -154,7 +154,7 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, entry_priv->desc = NULL; } -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) +int rt2x00mmio_initialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; int status; @@ -163,7 +163,7 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) * Allocate DMA */ queue_for_each(rt2x00dev, queue) { - status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); + status = rt2x00mmio_alloc_queue_dma(rt2x00dev, queue); if (status) goto exit; } @@ -175,8 +175,8 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) rt2x00dev->ops->lib->irq_handler, IRQF_SHARED, rt2x00dev->name, rt2x00dev); if (status) { - ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", - rt2x00dev->irq, status); + rt2x00_err(rt2x00dev, "IRQ %d allocation failed (error %d)\n", + rt2x00dev->irq, status); goto exit; } @@ -184,13 +184,13 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) exit: queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); + rt2x00mmio_free_queue_dma(rt2x00dev, queue); return status; } -EXPORT_SYMBOL_GPL(rt2x00pci_initialize); +EXPORT_SYMBOL_GPL(rt2x00mmio_initialize); -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) +void rt2x00mmio_uninitialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; @@ -203,9 +203,9 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) * Free DMA */ queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); + rt2x00mmio_free_queue_dma(rt2x00dev, queue); } -EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); +EXPORT_SYMBOL_GPL(rt2x00mmio_uninitialize); /* * 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 @@ /* * Register access. */ -static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 *value) +static inline void rt2x00mmio_register_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 *value) { *value = readl(rt2x00dev->csr.base + offset); } -static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - void *value, const u32 length) +static inline void rt2x00mmio_register_multiread(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void *value, const u32 length) { memcpy_fromio(value, rt2x00dev->csr.base + offset, length); } -static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 value) +static inline void rt2x00mmio_register_write(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 value) { writel(value, rt2x00dev->csr.base + offset); } -static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const void *value, - const u32 length) +static inline void rt2x00mmio_register_multiwrite(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const void *value, + const u32 length) { __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); } /** - * rt2x00pci_regbusy_read - Read from register with busy check + * rt2x00mmio_regbusy_read - Read from register with busy check * @rt2x00dev: Device pointer, see &struct rt2x00_dev. * @offset: Register offset * @field: Field to check if register is busy @@ -73,47 +73,47 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, * is not read after a certain timeout, this function will return * FALSE. */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg); +int rt2x00mmio_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg); /** - * struct queue_entry_priv_pci: Per entry PCI specific information + * struct queue_entry_priv_mmio: Per entry PCI specific information * * @desc: Pointer to device descriptor * @desc_dma: DMA pointer to &desc. * @data: Pointer to device's entry memory. * @data_dma: DMA pointer to &data. */ -struct queue_entry_priv_pci { +struct queue_entry_priv_mmio { __le32 *desc; dma_addr_t desc_dma; }; /** - * rt2x00pci_rxdone - Handle RX done events + * rt2x00mmio_rxdone - Handle RX done events * @rt2x00dev: Device pointer, see &struct rt2x00_dev. * * Returns true if there are still rx frames pending and false if all * pending rx frames were processed. */ -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); +bool rt2x00mmio_rxdone(struct rt2x00_dev *rt2x00dev); /** - * rt2x00pci_flush_queue - Flush data queue + * rt2x00mmio_flush_queue - Flush data queue * @queue: Data queue to stop * @drop: True to drop all pending frames. * * This will wait for a maximum of 100ms, waiting for the queues * to become empty. */ -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); +void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop); /* * Device initialization handlers. */ -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); +int rt2x00mmio_initialize(struct rt2x00_dev *rt2x00dev); +void rt2x00mmio_uninitialize(struct rt2x00_dev *rt2x00dev); #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) return 0; exit: - ERROR_PROBE("Failed to allocate registers.\n"); + rt2x00_probe_err("Failed to allocate registers\n"); rt2x00pci_free_reg(rt2x00dev); @@ -84,30 +84,30 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) retval = pci_enable_device(pci_dev); if (retval) { - ERROR_PROBE("Enable device failed.\n"); + rt2x00_probe_err("Enable device failed\n"); return retval; } retval = pci_request_regions(pci_dev, pci_name(pci_dev)); if (retval) { - ERROR_PROBE("PCI request regions failed.\n"); + rt2x00_probe_err("PCI request regions failed\n"); goto exit_disable_device; } pci_set_master(pci_dev); if (pci_set_mwi(pci_dev)) - ERROR_PROBE("MWI not available.\n"); + rt2x00_probe_err("MWI not available\n"); if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { - ERROR_PROBE("PCI DMA not supported.\n"); + rt2x00_probe_err("PCI DMA not supported\n"); retval = -EIO; goto exit_release_regions; } hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); if (!hw) { - ERROR_PROBE("Failed to allocate hardware.\n"); + rt2x00_probe_err("Failed to allocate hardware\n"); retval = -ENOMEM; goto exit_release_regions; } @@ -207,7 +207,7 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) if (pci_set_power_state(pci_dev, PCI_D0) || pci_enable_device(pci_dev)) { - ERROR(rt2x00dev, "Failed to resume device.\n"); + rt2x00_err(rt2x00dev, "Failed to resume device\n"); return -EIO; } 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 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct data_queue *queue = entry->queue; + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct sk_buff *skb; struct skb_frame_desc *skbdesc; unsigned int frame_size; @@ -46,7 +47,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) * The frame size includes descriptor size, because the * hardware directly receive the frame into the skbuffer. */ - frame_size = entry->queue->data_size + entry->queue->desc_size; + frame_size = queue->data_size + queue->desc_size + queue->winfo_size; /* * The payload should be aligned to a 4-byte boundary, @@ -531,10 +532,10 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, */ if (unlikely(rt2x00dev->ops->lib->get_entry_state && rt2x00dev->ops->lib->get_entry_state(entry))) { - ERROR(rt2x00dev, - "Corrupt queue %d, accessing entry which is not ours.\n" - "Please file bug report to %s.\n", - entry->queue->qid, DRV_PROJECT); + rt2x00_err(rt2x00dev, + "Corrupt queue %d, accessing entry which is not ours\n" + "Please file bug report to %s\n", + entry->queue->qid, DRV_PROJECT); return -EINVAL; } @@ -698,8 +699,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, spin_lock(&queue->tx_lock); if (unlikely(rt2x00queue_full(queue))) { - ERROR(queue->rt2x00dev, - "Dropping frame due to full tx queue %d.\n", queue->qid); + rt2x00_err(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n", + queue->qid); ret = -ENOBUFS; goto out; } @@ -708,10 +709,10 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))) { - ERROR(queue->rt2x00dev, - "Arrived at non-free entry in the non-full queue %d.\n" - "Please file bug report to %s.\n", - queue->qid, DRV_PROJECT); + rt2x00_err(queue->rt2x00dev, + "Arrived at non-free entry in the non-full queue %d\n" + "Please file bug report to %s\n", + queue->qid, DRV_PROJECT); ret = -EINVAL; goto out; } @@ -842,9 +843,9 @@ bool rt2x00queue_for_each_entry(struct data_queue *queue, unsigned int i; if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { - ERROR(queue->rt2x00dev, - "Entry requested from invalid index range (%d - %d)\n", - start, end); + rt2x00_err(queue->rt2x00dev, + "Entry requested from invalid index range (%d - %d)\n", + start, end); return true; } @@ -891,8 +892,8 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, unsigned long irqflags; if (unlikely(index >= Q_INDEX_MAX)) { - ERROR(queue->rt2x00dev, - "Entry requested from invalid index type (%d)\n", index); + rt2x00_err(queue->rt2x00dev, "Entry requested from invalid index type (%d)\n", + index); return NULL; } @@ -912,8 +913,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) unsigned long irqflags; if (unlikely(index >= Q_INDEX_MAX)) { - ERROR(queue->rt2x00dev, - "Index change on invalid index type (%d)\n", index); + rt2x00_err(queue->rt2x00dev, + "Index change on invalid index type (%d)\n", index); return; } @@ -1073,7 +1074,8 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) * The queue flush has failed... */ if (unlikely(!rt2x00queue_empty(queue))) - WARNING(queue->rt2x00dev, "Queue %d failed to flush\n", queue->qid); + rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n", + queue->qid); /* * Restore the queue to the previous status @@ -1172,6 +1174,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); queue->data_size = qdesc->data_size; queue->desc_size = qdesc->desc_size; + queue->winfo_size = qdesc->winfo_size; /* * Allocate all queue entries. @@ -1262,7 +1265,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) return 0; exit: - ERROR(rt2x00dev, "Queue entries allocation failed.\n"); + rt2x00_err(rt2x00dev, "Queue entries allocation failed\n"); rt2x00queue_uninitialize(rt2x00dev); @@ -1314,7 +1317,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); if (!queue) { - ERROR(rt2x00dev, "Queue allocation failed.\n"); + rt2x00_err(rt2x00dev, "Queue allocation failed\n"); return -ENOMEM; } 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 { unsigned short cw_max; unsigned short data_size; - unsigned short desc_size; + unsigned char desc_size; + unsigned char winfo_size; unsigned short usb_endpoint; unsigned short usb_maxpacket; @@ -499,7 +500,8 @@ struct data_queue { struct data_queue_desc { unsigned short entry_num; unsigned short data_size; - unsigned short desc_size; + unsigned char desc_size; + unsigned char winfo_size; unsigned short priv_size; }; 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) return 0; exit: - ERROR_PROBE("Failed to allocate registers.\n"); + rt2x00_probe_err("Failed to allocate registers\n"); rt2x00soc_free_reg(rt2x00dev); return -ENOMEM; @@ -82,7 +82,7 @@ int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops) hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); if (!hw) { - ERROR_PROBE("Failed to allocate hardware.\n"); + rt2x00_probe_err("Failed to allocate hardware\n"); return -ENOMEM; } 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, } } - ERROR(rt2x00dev, - "Vendor Request 0x%02x failed for offset 0x%04x with error %d.\n", - request, offset, status); + rt2x00_err(rt2x00dev, + "Vendor Request 0x%02x failed for offset 0x%04x with error %d\n", + request, offset, status); return status; } @@ -91,7 +91,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, * Check for Cache availability. */ if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { - ERROR(rt2x00dev, "CSR cache not available.\n"); + rt2x00_err(rt2x00dev, "CSR cache not available\n"); return -ENOMEM; } @@ -157,8 +157,8 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + rt2x00_err(rt2x00dev, "Indirect register access failed: offset=0x%.08x, value=0x%.08x\n", + offset, *reg); *reg = ~0; return 0; @@ -307,7 +307,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) status = skb_padto(entry->skb, length); if (unlikely(status)) { /* TODO: report something more appropriate than IO_FAILED. */ - WARNING(rt2x00dev, "TX SKB padding error, out of memory\n"); + rt2x00_warn(rt2x00dev, "TX SKB padding error, out of memory\n"); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); rt2x00lib_dmadone(entry); @@ -520,8 +520,8 @@ EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { - WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," - " invoke forced forced reset\n", queue->qid); + rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", + queue->qid); rt2x00queue_flush_queue(queue, true); } @@ -622,7 +622,7 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) * At least 1 endpoint for RX and 1 endpoint for TX must be available. */ if (!rt2x00dev->rx->usb_endpoint || !rt2x00dev->tx->usb_endpoint) { - ERROR(rt2x00dev, "Bulk-in/Bulk-out endpoints not found\n"); + rt2x00_err(rt2x00dev, "Bulk-in/Bulk-out endpoints not found\n"); return -EPIPE; } @@ -775,7 +775,7 @@ static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) return 0; exit: - ERROR_PROBE("Failed to allocate registers.\n"); + rt2x00_probe_err("Failed to allocate registers\n"); rt2x00usb_free_reg(rt2x00dev); @@ -795,7 +795,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); if (!hw) { - ERROR_PROBE("Failed to allocate hardware.\n"); + rt2x00_probe_err("Failed to allocate hardware\n"); retval = -ENOMEM; goto exit_put_device; } 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."); * and we will print an error. */ #define WAIT_FOR_BBP(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) #define WAIT_FOR_RF(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) + rt2x00mmio_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) #define WAIT_FOR_MCU(__dev, __reg) \ - rt2x00pci_regbusy_read((__dev), H2M_MAILBOX_CSR, \ - H2M_MAILBOX_CSR_OWNER, (__reg)) + rt2x00mmio_regbusy_read((__dev), H2M_MAILBOX_CSR, \ + H2M_MAILBOX_CSR_OWNER, (__reg)) static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) @@ -83,7 +83,7 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); - rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR3, reg); } mutex_unlock(&rt2x00dev->csr_mutex); @@ -110,7 +110,7 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); - rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR3, reg); WAIT_FOR_BBP(rt2x00dev, ®); } @@ -138,7 +138,7 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); - rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR4, reg); rt2x00_rf_write(rt2x00dev, word, value); } @@ -162,12 +162,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); - rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, HOST_CMD_CSR, ®); rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); - rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, HOST_CMD_CSR, reg); } mutex_unlock(&rt2x00dev->csr_mutex); @@ -179,7 +179,7 @@ static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) struct rt2x00_dev *rt2x00dev = eeprom->data; u32 reg; - rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); 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) rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, !!eeprom->reg_chip_select); - rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, E2PROM_CSR, reg); } #ifdef CONFIG_RT2X00_LIB_DEBUGFS static const struct rt2x00debug rt61pci_rt2x00debug = { .owner = THIS_MODULE, .csr = { - .read = rt2x00pci_register_read, - .write = rt2x00pci_register_write, + .read = rt2x00mmio_register_read, + .write = rt2x00mmio_register_write, .flags = RT2X00DEBUGFS_OFFSET, .word_base = CSR_REG_BASE, .word_size = sizeof(u32), @@ -243,7 +243,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); return rt2x00_get_field32(reg, MAC_CSR13_VAL5); } @@ -294,10 +294,10 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev, container_of(led_cdev, struct rt2x00_led, led_dev); u32 reg; - rt2x00pci_register_read(led->rt2x00dev, MAC_CSR14, ®); + rt2x00mmio_register_read(led->rt2x00dev, MAC_CSR14, ®); rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); - rt2x00pci_register_write(led->rt2x00dev, MAC_CSR14, reg); + rt2x00mmio_register_write(led->rt2x00dev, MAC_CSR14, reg); return 0; } @@ -339,7 +339,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, */ mask = (0xf << crypto->bssidx); - rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR0, ®); reg &= mask; if (reg && reg == mask) @@ -358,8 +358,8 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, sizeof(key_entry.rx_mic)); reg = SHARED_KEY_ENTRY(key->hw_key_idx); - rt2x00pci_register_multiwrite(rt2x00dev, reg, - &key_entry, sizeof(key_entry)); + rt2x00mmio_register_multiwrite(rt2x00dev, reg, + &key_entry, sizeof(key_entry)); /* * The cipher types are stored over 2 registers. @@ -372,16 +372,16 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, field.bit_offset = (3 * key->hw_key_idx); field.bit_mask = 0x7 << field.bit_offset; - rt2x00pci_register_read(rt2x00dev, SEC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR1, ®); rt2x00_set_field32(®, field, crypto->cipher); - rt2x00pci_register_write(rt2x00dev, SEC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg); } else { field.bit_offset = (3 * (key->hw_key_idx - 8)); field.bit_mask = 0x7 << field.bit_offset; - rt2x00pci_register_read(rt2x00dev, SEC_CSR5, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR5, ®); rt2x00_set_field32(®, field, crypto->cipher); - rt2x00pci_register_write(rt2x00dev, SEC_CSR5, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg); } /* @@ -404,12 +404,12 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, */ mask = 1 << key->hw_key_idx; - rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR0, ®); if (crypto->cmd == SET_KEY) reg |= mask; else if (crypto->cmd == DISABLE_KEY) reg &= ~mask; - rt2x00pci_register_write(rt2x00dev, SEC_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg); return 0; } @@ -433,10 +433,10 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * When both registers are full, we drop the key. * Otherwise, we use the first invalid entry. */ - rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR2, ®); if (reg && reg == ~0) { key->hw_key_idx = 32; - rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR3, ®); if (reg && reg == ~0) return -ENOSPC; } @@ -458,21 +458,21 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, addr_entry.cipher = crypto->cipher; reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); - rt2x00pci_register_multiwrite(rt2x00dev, reg, - &key_entry, sizeof(key_entry)); + rt2x00mmio_register_multiwrite(rt2x00dev, reg, + &key_entry, sizeof(key_entry)); reg = PAIRWISE_TA_ENTRY(key->hw_key_idx); - rt2x00pci_register_multiwrite(rt2x00dev, reg, - &addr_entry, sizeof(addr_entry)); + rt2x00mmio_register_multiwrite(rt2x00dev, reg, + &addr_entry, sizeof(addr_entry)); /* * Enable pairwise lookup table for given BSS idx. * Without this, received frames will not be decrypted * by the hardware. */ - rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR4, ®); reg |= (1 << crypto->bssidx); - rt2x00pci_register_write(rt2x00dev, SEC_CSR4, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR4, reg); /* * The driver does not support the IV/EIV generation @@ -495,21 +495,21 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, if (key->hw_key_idx < 32) { mask = 1 << key->hw_key_idx; - rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR2, ®); if (crypto->cmd == SET_KEY) reg |= mask; else if (crypto->cmd == DISABLE_KEY) reg &= ~mask; - rt2x00pci_register_write(rt2x00dev, SEC_CSR2, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR2, reg); } else { mask = 1 << (key->hw_key_idx - 32); - rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); + rt2x00mmio_register_read(rt2x00dev, SEC_CSR3, ®); if (crypto->cmd == SET_KEY) reg |= mask; else if (crypto->cmd == DISABLE_KEY) reg &= ~mask; - rt2x00pci_register_write(rt2x00dev, SEC_CSR3, reg); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR3, reg); } return 0; @@ -526,7 +526,7 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, * and broadcast frames will always be accepted since * there is no filter for it at this time. */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, !(filter_flags & FIF_FCSFAIL)); rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, @@ -544,7 +544,7 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, !(filter_flags & FIF_CONTROL)); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); } static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, @@ -558,9 +558,9 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, /* * Enable synchronisation. */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); } if (flags & CONFIG_UPDATE_MAC) { @@ -568,8 +568,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); conf->mac[1] = cpu_to_le32(reg); - rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, - conf->mac, sizeof(conf->mac)); + rt2x00mmio_register_multiwrite(rt2x00dev, MAC_CSR2, + conf->mac, sizeof(conf->mac)); } if (flags & CONFIG_UPDATE_BSSID) { @@ -577,8 +577,9 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); conf->bssid[1] = cpu_to_le32(reg); - rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, - conf->bssid, sizeof(conf->bssid)); + rt2x00mmio_register_multiwrite(rt2x00dev, MAC_CSR4, + conf->bssid, + sizeof(conf->bssid)); } } @@ -588,40 +589,40 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32); rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); if (changed & BSS_CHANGED_ERP_PREAMBLE) { - rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR4, ®); rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, !!erp->short_preamble); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR4, reg); } if (changed & BSS_CHANGED_BASIC_RATES) - rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, - erp->basic_rates); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR5, + erp->basic_rates); if (changed & BSS_CHANGED_BEACON_INT) { - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); } if (changed & BSS_CHANGED_ERP_SLOT) { - rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR9, ®); rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR8, ®); rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR8, reg); } } @@ -714,7 +715,7 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); rt2x00_set_field32(®, MAC_CSR13_DIR4, 0); rt2x00_set_field32(®, MAC_CSR13_VAL4, p1); @@ -722,7 +723,7 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MAC_CSR13_DIR3, 0); rt2x00_set_field32(®, MAC_CSR13_VAL3, !p2); - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, reg); } static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, @@ -821,14 +822,14 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); - rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, PHY_CSR0, ®); rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); - rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR0, reg); if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) rt61pci_config_antenna_5x(rt2x00dev, ant); @@ -848,7 +849,7 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, u16 eeprom; short lna_gain = 0; - if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { + if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; @@ -928,7 +929,7 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR4, ®); rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); @@ -936,7 +937,7 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, libconf->conf->long_frame_max_tx_count); rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, libconf->conf->short_frame_max_tx_count); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR4, reg); } static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, @@ -948,7 +949,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, u32 reg; if (state == STATE_SLEEP) { - rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR11, ®); rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, rt2x00dev->beacon_int - 10); rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, @@ -957,27 +958,29 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, /* We must first disable autowake before it can be enabled */ rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); - rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005); - rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c); - rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060); + rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, + 0x00000005); + rt2x00mmio_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c); + rt2x00mmio_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060); rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0); } else { - rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR11, ®); rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0); rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR11, reg); - rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); - rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018); - rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020); + rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, + 0x00000007); + rt2x00mmio_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018); + rt2x00mmio_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020); rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); } @@ -1013,13 +1016,13 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, /* * Update FCS error count from register. */ - rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR0, ®); qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); /* * Update False CCA count from register. */ - rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR1, ®); qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); } @@ -1138,16 +1141,16 @@ static void rt61pci_start_queue(struct data_queue *queue) switch (queue->qid) { case QID_RX: - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); break; default: break; @@ -1161,24 +1164,24 @@ static void rt61pci_kick_queue(struct data_queue *queue) switch (queue->qid) { case QID_AC_VO: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_VI: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_BE: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_BK: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; default: break; @@ -1192,36 +1195,36 @@ static void rt61pci_stop_queue(struct data_queue *queue) switch (queue->qid) { case QID_AC_VO: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_VI: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_BE: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_AC_BK: - rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_CNTL_CSR, ®); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); - rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_CNTL_CSR, reg); break; case QID_RX: - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); break; case QID_BEACON: - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); /* * Wait for possibly running tbtt tasklets. @@ -1299,14 +1302,14 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, * Wait for stable hardware. */ for (i = 0; i < 100; i++) { - rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR0, ®); if (reg) break; msleep(1); } if (!reg) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + rt2x00_err(rt2x00dev, "Unstable hardware\n"); return -EBUSY; } @@ -1315,10 +1318,10 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, */ reg = 0; rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); - rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); - rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); - rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); - rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, 0); + rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); + rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + rt2x00mmio_register_write(rt2x00dev, HOST_CMD_CSR, 0); /* * Write firmware to device. @@ -1326,26 +1329,26 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, reg = 0; rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 1); - rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); - rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, - data, len); + rt2x00mmio_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, + data, len); rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 0); - rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 0); - rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_CNTL_CSR, reg); for (i = 0; i < 100; i++) { - rt2x00pci_register_read(rt2x00dev, MCU_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, MCU_CNTL_CSR, ®); if (rt2x00_get_field32(reg, MCU_CNTL_CSR_READY)) break; msleep(1); } if (i == 100) { - ERROR(rt2x00dev, "MCU Control register not ready.\n"); + rt2x00_err(rt2x00dev, "MCU Control register not ready\n"); return -EBUSY; } @@ -1360,16 +1363,16 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, reg = 0; rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); return 0; } @@ -1379,7 +1382,7 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, */ static bool rt61pci_get_entry_state(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word; if (entry->queue->qid == QID_RX) { @@ -1396,7 +1399,7 @@ static bool rt61pci_get_entry_state(struct queue_entry *entry) static void rt61pci_clear_entry(struct queue_entry *entry) { - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); u32 word; @@ -1419,13 +1422,13 @@ static void rt61pci_clear_entry(struct queue_entry *entry) static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) { - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; u32 reg; /* * Initialize registers. */ - rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TX_RING_CSR0, ®); rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, rt2x00dev->tx[0].limit); rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, @@ -1434,67 +1437,67 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00dev->tx[2].limit); rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, rt2x00dev->tx[3].limit); - rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TX_RING_CSR0, reg); - rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, TX_RING_CSR1, ®); rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, rt2x00dev->tx[0].desc_size / 4); - rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, TX_RING_CSR1, reg); entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, AC0_BASE_CSR, ®); rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, AC0_BASE_CSR, reg); entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, AC1_BASE_CSR, ®); rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, AC1_BASE_CSR, reg); entry_priv = rt2x00dev->tx[2].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, AC2_BASE_CSR, ®); rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, AC2_BASE_CSR, reg); entry_priv = rt2x00dev->tx[3].entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, AC3_BASE_CSR, ®); rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, AC3_BASE_CSR, reg); - rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, RX_RING_CSR, ®); rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, rt2x00dev->rx->desc_size / 4); rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); - rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, RX_RING_CSR, reg); entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, RX_BASE_CSR, ®); rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, entry_priv->desc_dma); - rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, RX_BASE_CSR, reg); - rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC0, 2); rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); - rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); - rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1); rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); - rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); - rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, RX_CNTL_CSR, ®); rt2x00_set_field32(®, RX_CNTL_CSR_LOAD_RXD, 1); - rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, RX_CNTL_CSR, reg); return 0; } @@ -1503,13 +1506,13 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR0, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR1, ®); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ @@ -1518,12 +1521,12 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR1, reg); /* * CCK TXD BBP registers */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR2, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR2, ®); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); @@ -1532,76 +1535,76 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR2, reg); /* * OFDM TXD BBP registers */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR3, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR3, ®); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR3, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR7, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR7, ®); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR7, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR8, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR8, ®); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR8, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, 0); rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00_set_field32(®, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); - rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); - rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR9, ®); rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) return -EBUSY; - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); /* * Invalidate all Shared Keys (SEC_CSR0), * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) */ - rt2x00pci_register_write(rt2x00dev, SEC_CSR0, 0x00000000); - rt2x00pci_register_write(rt2x00dev, SEC_CSR1, 0x00000000); - rt2x00pci_register_write(rt2x00dev, SEC_CSR5, 0x00000000); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, 0x00000000); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, 0x00000000); + rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, 0x00000000); - rt2x00pci_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); - rt2x00pci_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); - rt2x00pci_register_write(rt2x00dev, PHY_CSR6, 0x00080606); - rt2x00pci_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR6, 0x00080606); + rt2x00mmio_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); - rt2x00pci_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); + rt2x00mmio_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); - rt2x00pci_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); + rt2x00mmio_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); - rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); + rt2x00mmio_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); /* * Clear all beacons @@ -1609,36 +1612,36 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) * the first byte since that byte contains the VALID and OWNER * bits which (when set to 0) will invalidate the entire beacon. */ - rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); - rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); - rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); - rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); + rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE0, 0); + rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE1, 0); + rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE2, 0); + rt2x00mmio_register_write(rt2x00dev, HW_BEACON_BASE3, 0); /* * We must clear the error counters. * These registers are cleared on read, * so we may pass a useless variable to store the value. */ - rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); - rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); - rt2x00pci_register_read(rt2x00dev, STA_CSR2, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR2, ®); /* * Reset MAC and BBP registers. */ - rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR1, ®); rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR1, reg); return 0; } @@ -1655,7 +1658,7 @@ static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -1722,11 +1725,11 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, * should clear the register to assure a clean state. */ if (state == STATE_RADIO_IRQ_ON) { - rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); + rt2x00mmio_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); } /* @@ -1735,15 +1738,15 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, */ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); - rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); rt2x00_set_field32(®, MCU_INT_MASK_CSR_0, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_1, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_2, mask); @@ -1753,7 +1756,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); - rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); @@ -1783,9 +1786,9 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Enable RX. */ - rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, RX_CNTL_CSR, ®); rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); - rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, RX_CNTL_CSR, reg); return 0; } @@ -1795,7 +1798,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Disable power */ - rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR10, 0x00001818); } 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) put_to_sleep = (state != STATE_AWAKE); - rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR12, ®); rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); - rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR12, reg); /* * 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) * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®2); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR12, ®2); state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE); if (state == !put_to_sleep) return 0; - rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR12, reg); msleep(10); } @@ -1856,8 +1859,8 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -1869,7 +1872,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1967,7 +1970,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; unsigned int beacon_base; unsigned int padding_len; u32 orig_reg, reg; @@ -1976,10 +1979,10 @@ static void rt61pci_write_beacon(struct queue_entry *entry, * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); orig_reg = reg; rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); /* * Write the TX descriptor for the beacon. @@ -1996,19 +1999,19 @@ static void rt61pci_write_beacon(struct queue_entry *entry, */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); /* skb freed by skb_pad() on failure */ entry->skb = NULL; - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, orig_reg); return; } beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, - entry_priv->desc, TXINFO_SIZE); - rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, - entry->skb->data, - entry->skb->len + padding_len); + rt2x00mmio_register_multiwrite(rt2x00dev, beacon_base, + entry_priv->desc, TXINFO_SIZE); + rt2x00mmio_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, + entry->skb->data, + entry->skb->len + padding_len); /* * Enable beaconing again. @@ -2016,10 +2019,10 @@ static void rt61pci_write_beacon(struct queue_entry *entry, * For Wi-Fi faily generated beacons between participating * stations. Set TBTT phase adaptive adjustment step to 8us. */ - rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); /* * Clean up beacon skb. @@ -2037,21 +2040,21 @@ static void rt61pci_clear_beacon(struct queue_entry *entry) * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); /* * Clear beacon. */ - rt2x00pci_register_write(rt2x00dev, - HW_BEACON_OFFSET(entry->entry_idx), 0); + rt2x00mmio_register_write(rt2x00dev, + HW_BEACON_OFFSET(entry->entry_idx), 0); /* * Enable beaconing again. */ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg); } /* @@ -2089,7 +2092,7 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; u32 word0; u32 word1; @@ -2155,7 +2158,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; struct queue_entry *entry; struct queue_entry *entry_done; - struct queue_entry_priv_pci *entry_priv; + struct queue_entry_priv_mmio *entry_priv; struct txdone_entry_desc txdesc; u32 word; u32 reg; @@ -2173,7 +2176,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) * tx ring size for now. */ for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { - rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); + rt2x00mmio_register_read(rt2x00dev, STA_CSR4, ®); if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) break; @@ -2207,9 +2210,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) /* Catch up. * Just report any entries we missed as failed. */ - WARNING(rt2x00dev, - "TX status report missed for entry %d\n", - entry_done->entry_idx); + rt2x00_warn(rt2x00dev, "TX status report missed for entry %d\n", + entry_done->entry_idx); rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); @@ -2260,9 +2262,9 @@ static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 0); - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -2278,9 +2280,9 @@ static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, */ spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 0); - rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); spin_unlock_irq(&rt2x00dev->irqmask_lock); } @@ -2304,7 +2306,7 @@ static void rt61pci_tbtt_tasklet(unsigned long data) static void rt61pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2x00pci_rxdone(rt2x00dev)) + if (rt2x00mmio_rxdone(rt2x00dev)) tasklet_schedule(&rt2x00dev->rxdone_tasklet); else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); @@ -2314,8 +2316,8 @@ static void rt61pci_autowake_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; rt61pci_wakeup(rt2x00dev); - rt2x00pci_register_write(rt2x00dev, - M2H_CMD_DONE_CSR, 0xffffffff); + rt2x00mmio_register_write(rt2x00dev, + M2H_CMD_DONE_CSR, 0xffffffff); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP); } @@ -2330,11 +2332,11 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) * Get the interrupt sources & saved to local variable. * Write register value back to clear pending interrupts. */ - rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); - rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); + rt2x00mmio_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); + rt2x00mmio_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); - rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); if (!reg && !reg_mcu) return IRQ_NONE; @@ -2371,13 +2373,13 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) */ spin_lock(&rt2x00dev->irqmask_lock); - rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); reg |= mask; - rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); - rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); reg |= mask_mcu; - rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); spin_unlock(&rt2x00dev->irqmask_lock); @@ -2395,7 +2397,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) u8 *mac; s8 value; - rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt61pci_eepromregister_read; @@ -2416,7 +2418,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); @@ -2431,7 +2433,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); - EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); @@ -2444,7 +2446,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); - EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); @@ -2452,7 +2454,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, LED_MODE_DEFAULT); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); - EEPROM(rt2x00dev, "Led: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Led: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); @@ -2460,7 +2462,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); - EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); @@ -2468,7 +2470,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); - EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); if (value < -10 || value > 10) @@ -2484,7 +2486,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); - EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); if (value < -10 || value > 10) @@ -2513,7 +2515,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Identify RF chipset. */ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); - rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR0, ®); rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); @@ -2521,7 +2523,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF5325) && !rt2x00_rf(rt2x00dev, RF2527) && !rt2x00_rf(rt2x00dev, RF2529)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); return -ENODEV; } @@ -2838,7 +2840,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) /* * Disable power saving. */ - rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); + rt2x00mmio_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); /* * Allocate eeprom data. @@ -2855,9 +2857,9 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) * Enable rfkill polling by setting GPIO direction of the * rfkill switch GPIO pin correctly. */ - rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); + rt2x00mmio_register_read(rt2x00dev, MAC_CSR13, ®); rt2x00_set_field32(®, MAC_CSR13_DIR5, 1); - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); + rt2x00mmio_register_write(rt2x00dev, MAC_CSR13, reg); /* * Initialize hw specifications. @@ -2927,25 +2929,25 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, field.bit_offset = (queue_idx & 1) * 16; field.bit_mask = 0xffff << field.bit_offset; - rt2x00pci_register_read(rt2x00dev, offset, ®); + rt2x00mmio_register_read(rt2x00dev, offset, ®); rt2x00_set_field32(®, field, queue->txop); - rt2x00pci_register_write(rt2x00dev, offset, reg); + rt2x00mmio_register_write(rt2x00dev, offset, reg); /* Update WMM registers */ field.bit_offset = queue_idx * 4; field.bit_mask = 0xf << field.bit_offset; - rt2x00pci_register_read(rt2x00dev, AIFSN_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, AIFSN_CSR, ®); rt2x00_set_field32(®, field, queue->aifs); - rt2x00pci_register_write(rt2x00dev, AIFSN_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, AIFSN_CSR, reg); - rt2x00pci_register_read(rt2x00dev, CWMIN_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, CWMIN_CSR, ®); rt2x00_set_field32(®, field, queue->cw_min); - rt2x00pci_register_write(rt2x00dev, CWMIN_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, CWMIN_CSR, reg); - rt2x00pci_register_read(rt2x00dev, CWMAX_CSR, ®); + rt2x00mmio_register_read(rt2x00dev, CWMAX_CSR, ®); rt2x00_set_field32(®, field, queue->cw_max); - rt2x00pci_register_write(rt2x00dev, CWMAX_CSR, reg); + rt2x00mmio_register_write(rt2x00dev, CWMAX_CSR, reg); return 0; } @@ -2956,9 +2958,9 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) u64 tsf; u32 reg; - rt2x00pci_register_read(rt2x00dev, TXRX_CSR13, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR13, ®); tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; - rt2x00pci_register_read(rt2x00dev, TXRX_CSR12, ®); + rt2x00mmio_register_read(rt2x00dev, TXRX_CSR12, ®); tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); return tsf; @@ -2997,8 +2999,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .get_firmware_name = rt61pci_get_firmware_name, .check_firmware = rt61pci_check_firmware, .load_firmware = rt61pci_load_firmware, - .initialize = rt2x00pci_initialize, - .uninitialize = rt2x00pci_uninitialize, + .initialize = rt2x00mmio_initialize, + .uninitialize = rt2x00mmio_uninitialize, .get_entry_state = rt61pci_get_entry_state, .clear_entry = rt61pci_clear_entry, .set_device_state = rt61pci_set_device_state, @@ -3009,7 +3011,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .start_queue = rt61pci_start_queue, .kick_queue = rt61pci_kick_queue, .stop_queue = rt61pci_stop_queue, - .flush_queue = rt2x00pci_flush_queue, + .flush_queue = rt2x00mmio_flush_queue, .write_tx_desc = rt61pci_write_tx_desc, .write_beacon = rt61pci_write_beacon, .clear_beacon = rt61pci_clear_beacon, @@ -3027,21 +3029,21 @@ static const struct data_queue_desc rt61pci_queue_rx = { .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = RXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt61pci_queue_tx = { .entry_num = 32, .data_size = DATA_FRAME_SIZE, .desc_size = TXD_DESC_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; static const struct data_queue_desc rt61pci_queue_bcn = { .entry_num = 4, .data_size = 0, /* No DMA required for beacons */ .desc_size = TXINFO_SIZE, - .priv_size = sizeof(struct queue_entry_priv_pci), + .priv_size = sizeof(struct queue_entry_priv_mmio), }; 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, u16 eeprom; short lna_gain = 0; - if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { + if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; @@ -1122,7 +1122,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, } if (!reg) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + rt2x00_err(rt2x00dev, "Unstable hardware\n"); return -EBUSY; } @@ -1139,7 +1139,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, 0, USB_MODE_FIRMWARE, REGISTER_TIMEOUT_FIRMWARE); if (status < 0) { - ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); + rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n"); return status; } @@ -1305,7 +1305,7 @@ static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); + rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); return -EACCES; } @@ -1443,8 +1443,8 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, } if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); + rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", + state, retval); return retval; } @@ -1567,7 +1567,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; if (padding_len && skb_pad(entry->skb, padding_len)) { - ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); /* skb freed by skb_pad() on failure */ entry->skb = NULL; rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); @@ -1771,7 +1771,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { eth_random_addr(mac); - EEPROM(rt2x00dev, "MAC: %pM\n", mac); + rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); @@ -1786,14 +1786,14 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5226); rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); - EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); - EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); @@ -1809,7 +1809,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, LED_MODE_DEFAULT); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); - EEPROM(rt2x00dev, "Led: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Led: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); @@ -1817,7 +1817,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); - EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); @@ -1825,7 +1825,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); - EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); if (value < -10 || value > 10) @@ -1841,7 +1841,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); - EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); + rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); if (value < -10 || value > 10) @@ -1875,7 +1875,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) { - ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RT chipset detected\n"); return -ENODEV; } @@ -1883,7 +1883,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF2528) && !rt2x00_rf(rt2x00dev, RF5225) && !rt2x00_rf(rt2x00dev, RF2527)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n"); return -ENODEV; } 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) signal = priv->rf->calc_rssi(agc, sq); } rx_status.signal = signal; - rx_status.freq = dev->conf.channel->center_freq; - rx_status.band = dev->conf.channel->band; + rx_status.freq = dev->conf.chandef.chan->center_freq; + rx_status.band = dev->conf.chandef.chan->band; rx_status.mactime = le64_to_cpu(entry->tsft); rx_status.flag |= RX_FLAG_MACTIME_START; 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, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + int channel = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; u32 chan = channel - 1; 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, { struct rtl8180_priv *priv = dev->priv; int channel = conf ? - ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1; unsigned int chan_idx = channel - 1; u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; 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, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; - int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); + int chan = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); if (priv->rf->init == rtl8225_rf_init) 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, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + int channel = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; u32 chan = sa2400_chan[channel - 1]; 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) rate = (flags >> 20) & 0xF; skb_trim(skb, flags & 0x0FFF); rx_status.rate_idx = rate; - rx_status.freq = dev->conf.channel->center_freq; - rx_status.band = dev->conf.channel->band; + rx_status.freq = dev->conf.chandef.chan->center_freq; + rx_status.band = dev->conf.chandef.chan->band; rx_status.flag |= RX_FLAG_MACTIME_START; if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 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, struct ieee80211_conf *conf) { struct rtl8187_priv *priv = dev->priv; - int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); + int chan = + ieee80211_frequency_to_channel(conf->chandef.chan->center_freq); if (priv->rf->init == rtl8225_rf_init) 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, int rate_idx; if (false == isht) { - if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) { + if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) { switch (desc_rate) { case DESC92_RATE1M: rate_idx = 0; @@ -987,8 +987,8 @@ static bool addbareq_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) { skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid); if (skb_delba) { - rx_status.freq = hw->conf.channel->center_freq; - rx_status.band = hw->conf.channel->band; + rx_status.freq = hw->conf.chandef.chan->center_freq; + rx_status.band = hw->conf.chandef.chan->band; rx_status.flag |= RX_FLAG_DECRYPTED; rx_status.flag |= RX_FLAG_MACTIME_END; rx_status.rate_idx = 0; @@ -1593,7 +1593,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, sta_entry->mimo_ps = smps; info->control.rates[0].idx = 0; - info->band = hw->conf.channel->band; + info->band = hw->conf.chandef.chan->band; rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); } 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) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - struct ieee80211_channel *channel = hw->conf.channel; + struct ieee80211_channel *channel = hw->conf.chandef.chan; u8 wide_chan = (u8) channel->hw_value; if (mac->act_scanning) @@ -392,7 +392,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) *info for cisco1253 bw20, so we modify *it here based on UPPER & LOWER */ - switch (hw->conf.channel_type) { + switch (cfg80211_get_chandef_type(&hw->conf.chandef)) { case NL80211_CHAN_HT20: case NL80211_CHAN_NO_HT: /* SC */ @@ -450,7 +450,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) rtlpriv->cfg->ops->switch_channel(hw); rtlpriv->cfg->ops->set_channel_access(hw); rtlpriv->cfg->ops->set_bw_mode(hw, - hw->conf.channel_type); + cfg80211_get_chandef_type(&hw->conf.chandef)); } 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, if (pwr2g->index_cck_base[path][i] == 0xFF) pwr2g->index_cck_base[path][i] = 0x2D; } - for (i = 0; i < MAX_CHNL_GROUP_24G-1; i++) { + for (i = 0; i < MAX_CHNL_GROUP_24G; i++) { pwr2g->index_bw40_base[path][i] = hwinfo[eadr++]; if (pwr2g->index_bw40_base[path][i] == 0xFF) 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, RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "Get Wakeup Packet!! WakeMatch =%d\n", status->wake_match); - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (status->crc) 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 u8 thermalvalue, delta, delta_lck, delta_iqk; long ele_a, ele_d, temp_cck, val_x, value32; long val_y, ele_c = 0; - u8 ofdm_index[2], ofdm_index_old[2], cck_index_old = 0; + u8 ofdm_index[2], ofdm_index_old[2] = {0, 0}, cck_index_old = 0; s8 cck_index = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); @@ -717,7 +717,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw for (i = 0; i < OFDM_TABLE_LENGTH; i++) { if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - + ofdm_index_old[1] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "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, stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc); - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size + 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, && (GET_RX_DESC_FAGGR(pdesc) == 1)); stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (GET_RX_DESC_CRC32(pdesc)) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; if (!GET_RX_DESC_SWDEC(pdesc)) @@ -395,8 +395,8 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); /* TODO: is center_freq changed when doing scan? */ /* TODO: Shall we add protection or just skip those two step? */ - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (GET_RX_DESC_CRC32(rxdesc)) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 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, && (GET_RX_DESC_FAGGR(pdesc) == 1)); stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (GET_RX_DESC_CRC32(pdesc)) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 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, if (stats->hwerror) return false; - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (stats->crc) 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, status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; if (status->crc) 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) struct ieee80211_conf *conf = &hw->conf; int channel, ret = 0; - channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + channel = ieee80211_frequency_to_channel( + conf->chandef.chan->center_freq); wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", channel, @@ -1223,7 +1224,7 @@ static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = wl->noise; 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, } cmd->role_id = wlvif->role_id; - cmd->channel = ch_switch->channel->hw_value; + cmd->channel = ch_switch->chandef.chan->hw_value; cmd->switch_time = ch_switch->count; cmd->stop_tx = ch_switch->block_tx; 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, } cmd->role_id = wlvif->role_id; - cmd->channel = ch_switch->channel->hw_value; + cmd->channel = ch_switch->chandef.chan->hw_value; cmd->switch_time = ch_switch->count; cmd->stop_tx = ch_switch->block_tx; - switch (ch_switch->channel->band) { + switch (ch_switch->chandef.chan->band) { case IEEE80211_BAND_2GHZ: cmd->band = WLCORE_BAND_2_4GHZ; break; @@ -55,7 +55,7 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl, break; default: wl1271_error("invalid channel switch band: %d", - ch_switch->channel->band); + ch_switch->chandef.chan->band); ret = -EINVAL; goto out_free; } 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, if (idx != 0) return -ENOENT; - survey->channel = conf->channel; + survey->channel = conf->chandef.chan; survey->filled = 0; return 0; } 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) struct ieee80211_conf *conf = &hw->conf; spin_lock_irq(&mac->lock); - mac->channel = conf->channel->hw_value; + mac->channel = conf->chandef.chan->hw_value; spin_unlock_irq(&mac->lock); - return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); + return zd_chip_set_channel(&mac->chip, conf->chandef.chan->hw_value); } 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 Say Y here to compile support for Texas Instrument's NFC WiLink driver into the kernel or say M to compile it as module. +config NFC_MEI_PHY + tristate "MEI bus NFC device support" + depends on INTEL_MEI_BUS_NFC && NFC_HCI + help + This adds support to use an mei bus nfc device. Select this if you + will use an HCI NFC driver for an NFC chip connected behind an + Intel's Management Engine chip. + + If unsure, say N. + source "drivers/nfc/pn544/Kconfig" source "drivers/nfc/microread/Kconfig" 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/ obj-$(CONFIG_NFC_MICROREAD) += microread/ obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o +obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o 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 @@ +/* + * MEI Library for mei bus nfc device access + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/nfc.h> + +#include "mei_phy.h" + +struct mei_nfc_hdr { + u8 cmd; + u8 status; + u16 req_id; + u32 reserved; + u16 data_size; +} __attribute__((packed)); + +#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) + +#define MEI_DUMP_SKB_IN(info, skb) \ +do { \ + pr_debug("%s:\n", info); \ + print_hex_dump_debug("mei in : ", DUMP_PREFIX_OFFSET, \ + 16, 1, (skb)->data, (skb)->len, false); \ +} while (0) + +#define MEI_DUMP_SKB_OUT(info, skb) \ +do { \ + pr_debug("%s:\n", info); \ + print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET, \ + 16, 1, (skb)->data, (skb)->len, false); \ +} while (0) + +int nfc_mei_phy_enable(void *phy_id) +{ + int r; + struct nfc_mei_phy *phy = phy_id; + + pr_info("%s\n", __func__); + + if (phy->powered == 1) + return 0; + + r = mei_cl_enable_device(phy->device); + if (r < 0) { + pr_err("MEI_PHY: Could not enable device\n"); + return r; + } + + phy->powered = 1; + + return 0; +} +EXPORT_SYMBOL_GPL(nfc_mei_phy_enable); + +void nfc_mei_phy_disable(void *phy_id) +{ + struct nfc_mei_phy *phy = phy_id; + + pr_info("%s\n", __func__); + + mei_cl_disable_device(phy->device); + + phy->powered = 0; +} +EXPORT_SYMBOL_GPL(nfc_mei_phy_disable); + +/* + * Writing a frame must not return the number of written bytes. + * It must return either zero for success, or <0 for error. + * In addition, it must not alter the skb + */ +static int nfc_mei_phy_write(void *phy_id, struct sk_buff *skb) +{ + struct nfc_mei_phy *phy = phy_id; + int r; + + MEI_DUMP_SKB_OUT("mei frame sent", skb); + + r = mei_cl_send(phy->device, skb->data, skb->len); + if (r > 0) + r = 0; + + return r; +} + +void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) +{ + struct nfc_mei_phy *phy = context; + + if (phy->hard_fault != 0) + return; + + if (events & BIT(MEI_CL_EVENT_RX)) { + struct sk_buff *skb; + int reply_size; + + skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL); + if (!skb) + return; + + reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); + if (reply_size < MEI_NFC_HEADER_SIZE) { + kfree(skb); + return; + } + + skb_put(skb, reply_size); + skb_pull(skb, MEI_NFC_HEADER_SIZE); + + MEI_DUMP_SKB_IN("mei frame read", skb); + + nfc_hci_recv_frame(phy->hdev, skb); + } +} +EXPORT_SYMBOL_GPL(nfc_mei_event_cb); + +struct nfc_phy_ops mei_phy_ops = { + .write = nfc_mei_phy_write, + .enable = nfc_mei_phy_enable, + .disable = nfc_mei_phy_disable, +}; +EXPORT_SYMBOL_GPL(mei_phy_ops); + +struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device) +{ + struct nfc_mei_phy *phy; + + phy = kzalloc(sizeof(struct nfc_mei_phy), GFP_KERNEL); + if (!phy) + return NULL; + + phy->device = device; + mei_cl_set_drvdata(device, phy); + + return phy; +} +EXPORT_SYMBOL_GPL(nfc_mei_phy_alloc); + +void nfc_mei_phy_free(struct nfc_mei_phy *phy) +{ + kfree(phy); +} +EXPORT_SYMBOL_GPL(nfc_mei_phy_free); + +MODULE_LICENSE("GPL"); +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 @@ +#ifndef __LOCAL_MEI_PHY_H_ +#define __LOCAL_MEI_PHY_H_ + +#include <linux/mei_cl_bus.h> +#include <net/nfc/hci.h> + +#define MEI_NFC_HEADER_SIZE 10 +#define MEI_NFC_MAX_HCI_PAYLOAD 300 + +struct nfc_mei_phy { + struct mei_cl_device *device; + struct nfc_hci_dev *hdev; + + int powered; + + int hard_fault; /* + * < 0 if hardware error occured + * and prevents normal operation. + */ +}; + +extern struct nfc_phy_ops mei_phy_ops; + +int nfc_mei_phy_enable(void *phy_id); +void nfc_mei_phy_disable(void *phy_id); +void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context); +struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device); +void nfc_mei_phy_free(struct nfc_mei_phy *phy); + +#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 config NFC_MICROREAD_MEI tristate "NFC Microread MEI support" - depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC + depends on NFC_MICROREAD && NFC_MEI_PHY ---help--- This module adds support for the mei interface of adapters using 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 @@ */ #include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/gpio.h> -#include <linux/mei_cl_bus.h> - +#include <linux/mod_devicetable.h> #include <linux/nfc.h> #include <net/nfc/hci.h> #include <net/nfc/llc.h> +#include "../mei_phy.h" #include "microread.h" #define MICROREAD_DRIVER_NAME "microread" -struct mei_nfc_hdr { - u8 cmd; - u8 status; - u16 req_id; - u32 reserved; - u16 data_size; -} __attribute__((packed)); - -#define MEI_NFC_HEADER_SIZE 10 -#define MEI_NFC_MAX_HCI_PAYLOAD 300 -#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) - -struct microread_mei_phy { - struct mei_cl_device *device; - struct nfc_hci_dev *hdev; - - int powered; - - int hard_fault; /* - * < 0 if hardware error occured (e.g. i2c err) - * and prevents normal operation. - */ -}; - -#define MEI_DUMP_SKB_IN(info, skb) \ -do { \ - pr_debug("%s:\n", info); \ - print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET, \ - 16, 1, (skb)->data, (skb)->len, 0); \ -} while (0) - -#define MEI_DUMP_SKB_OUT(info, skb) \ -do { \ - pr_debug("%s:\n", info); \ - print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET, \ - 16, 1, (skb)->data, (skb)->len, 0); \ -} while (0) - -static int microread_mei_enable(void *phy_id) -{ - struct microread_mei_phy *phy = phy_id; - - pr_info(DRIVER_DESC ": %s\n", __func__); - - phy->powered = 1; - - return 0; -} - -static void microread_mei_disable(void *phy_id) -{ - struct microread_mei_phy *phy = phy_id; - - pr_info(DRIVER_DESC ": %s\n", __func__); - - phy->powered = 0; -} - -/* - * Writing a frame must not return the number of written bytes. - * It must return either zero for success, or <0 for error. - * In addition, it must not alter the skb - */ -static int microread_mei_write(void *phy_id, struct sk_buff *skb) -{ - struct microread_mei_phy *phy = phy_id; - int r; - - MEI_DUMP_SKB_OUT("mei frame sent", skb); - - r = mei_cl_send(phy->device, skb->data, skb->len); - if (r > 0) - r = 0; - - return r; -} - -static void microread_event_cb(struct mei_cl_device *device, u32 events, - void *context) -{ - struct microread_mei_phy *phy = context; - - if (phy->hard_fault != 0) - return; - - if (events & BIT(MEI_CL_EVENT_RX)) { - struct sk_buff *skb; - int reply_size; - - skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL); - if (!skb) - return; - - reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); - if (reply_size < MEI_NFC_HEADER_SIZE) { - kfree(skb); - return; - } - - skb_put(skb, reply_size); - skb_pull(skb, MEI_NFC_HEADER_SIZE); - - MEI_DUMP_SKB_IN("mei frame read", skb); - - nfc_hci_recv_frame(phy->hdev, skb); - } -} - -static struct nfc_phy_ops mei_phy_ops = { - .write = microread_mei_write, - .enable = microread_mei_enable, - .disable = microread_mei_disable, -}; - static int microread_mei_probe(struct mei_cl_device *device, const struct mei_cl_device_id *id) { - struct microread_mei_phy *phy; + struct nfc_mei_phy *phy; int r; pr_info("Probing NFC microread\n"); - phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL); + phy = nfc_mei_phy_alloc(device); if (!phy) { pr_err("Cannot allocate memory for microread mei phy.\n"); return -ENOMEM; } - phy->device = device; - mei_cl_set_drvdata(device, phy); - - r = mei_cl_register_event_cb(device, microread_event_cb, phy); + r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); if (r) { pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); goto err_out; @@ -178,23 +58,22 @@ static int microread_mei_probe(struct mei_cl_device *device, return 0; err_out: - kfree(phy); + nfc_mei_phy_free(phy); return r; } static int microread_mei_remove(struct mei_cl_device *device) { - struct microread_mei_phy *phy = mei_cl_get_drvdata(device); + struct nfc_mei_phy *phy = mei_cl_get_drvdata(device); pr_info("Removing microread\n"); microread_remove(phy->hdev); - if (phy->powered) - microread_mei_disable(phy); + nfc_mei_phy_disable(phy); - kfree(phy); + nfc_mei_phy_free(phy); return 0; } 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 @@ /* * Copyright (C) 2011 Instituto Nokia de Tecnologia - * - * Authors: - * Lauro Ramos Venancio <lauro.venancio@openbossa.org> - * Aloisio Almeida Jr <aloisio.almeida@openbossa.org> + * Copyright (C) 2012-2013 Tieto Poland * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +27,7 @@ #include <linux/netdevice.h> #include <net/nfc/nfc.h> -#define VERSION "0.1" +#define VERSION "0.2" #define PN533_VENDOR_ID 0x4CC #define PN533_PRODUCT_ID 0x2533 @@ -41,8 +38,12 @@ #define SONY_VENDOR_ID 0x054c #define PASORI_PRODUCT_ID 0x02e1 -#define PN533_DEVICE_STD 0x1 -#define PN533_DEVICE_PASORI 0x2 +#define ACS_VENDOR_ID 0x072f +#define ACR122U_PRODUCT_ID 0x2200 + +#define PN533_DEVICE_STD 0x1 +#define PN533_DEVICE_PASORI 0x2 +#define PN533_DEVICE_ACR122U 0x3 #define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\ NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\ @@ -71,6 +72,11 @@ static const struct usb_device_id pn533_table[] = { .idProduct = PASORI_PRODUCT_ID, .driver_info = PN533_DEVICE_PASORI, }, + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = ACS_VENDOR_ID, + .idProduct = ACR122U_PRODUCT_ID, + .driver_info = PN533_DEVICE_ACR122U, + }, { } }; MODULE_DEVICE_TABLE(usb, pn533_table); @@ -78,32 +84,47 @@ MODULE_DEVICE_TABLE(usb, pn533_table); /* How much time we spend listening for initiators */ #define PN533_LISTEN_TIME 2 -/* frame definitions */ -#define PN533_FRAME_HEADER_LEN (sizeof(struct pn533_frame) \ +/* Standard pn533 frame definitions */ +#define PN533_STD_FRAME_HEADER_LEN (sizeof(struct pn533_std_frame) \ + 2) /* data[0] TFI, data[1] CC */ -#define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ +#define PN533_STD_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/ /* * Max extended frame payload len, excluding TFI and CC * which are already in PN533_FRAME_HEADER_LEN. */ -#define PN533_FRAME_MAX_PAYLOAD_LEN 263 +#define PN533_STD_FRAME_MAX_PAYLOAD_LEN 263 -#define PN533_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2), +#define PN533_STD_FRAME_ACK_SIZE 6 /* Preamble (1), SoPC (2), ACK Code (2), Postamble (1) */ -#define PN533_FRAME_CHECKSUM(f) (f->data[f->datalen]) -#define PN533_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1]) +#define PN533_STD_FRAME_CHECKSUM(f) (f->data[f->datalen]) +#define PN533_STD_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1]) /* start of frame */ -#define PN533_SOF 0x00FF +#define PN533_STD_FRAME_SOF 0x00FF + +/* standard frame identifier: in/out/error */ +#define PN533_STD_FRAME_IDENTIFIER(f) (f->data[0]) /* TFI */ +#define PN533_STD_FRAME_DIR_OUT 0xD4 +#define PN533_STD_FRAME_DIR_IN 0xD5 + +/* ACS ACR122 pn533 frame definitions */ +#define PN533_ACR122_TX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_tx_frame) \ + + 2) +#define PN533_ACR122_TX_FRAME_TAIL_LEN 0 +#define PN533_ACR122_RX_FRAME_HEADER_LEN (sizeof(struct pn533_acr122_rx_frame) \ + + 2) +#define PN533_ACR122_RX_FRAME_TAIL_LEN 2 +#define PN533_ACR122_FRAME_MAX_PAYLOAD_LEN PN533_STD_FRAME_MAX_PAYLOAD_LEN + +/* CCID messages types */ +#define PN533_ACR122_PC_TO_RDR_ICCPOWERON 0x62 +#define PN533_ACR122_PC_TO_RDR_ESCAPE 0x6B -/* frame identifier: in/out/error */ -#define PN533_FRAME_IDENTIFIER(f) (f->data[0]) -#define PN533_DIR_OUT 0xD4 -#define PN533_DIR_IN 0xD5 +#define PN533_ACR122_RDR_TO_PC_ESCAPE 0x83 /* PN533 Commands */ -#define PN533_FRAME_CMD(f) (f->data[1]) +#define PN533_STD_FRAME_CMD(f) (f->data[1]) #define PN533_CMD_GET_FIRMWARE_VERSION 0x02 #define PN533_CMD_RF_CONFIGURATION 0x32 @@ -128,8 +149,6 @@ MODULE_DEVICE_TABLE(usb, pn533_table); struct pn533; -typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg, int status); - typedef int (*pn533_send_async_complete_t) (struct pn533 *dev, void *arg, struct sk_buff *resp); @@ -144,9 +163,13 @@ struct pn533_fw_version { }; /* PN533_CMD_RF_CONFIGURATION */ -#define PN533_CFGITEM_TIMING 0x02 +#define PN533_CFGITEM_RF_FIELD 0x01 +#define PN533_CFGITEM_TIMING 0x02 #define PN533_CFGITEM_MAX_RETRIES 0x05 -#define PN533_CFGITEM_PASORI 0x82 +#define PN533_CFGITEM_PASORI 0x82 + +#define PN533_CFGITEM_RF_FIELD_ON 0x1 +#define PN533_CFGITEM_RF_FIELD_OFF 0x0 #define PN533_CONFIG_TIMING_102 0xb #define PN533_CONFIG_TIMING_204 0xc @@ -313,10 +336,17 @@ struct pn533_cmd_jump_dep_response { #define PN533_INIT_TARGET_RESP_ACTIVE 0x1 #define PN533_INIT_TARGET_RESP_DEP 0x4 +enum pn533_protocol_type { + PN533_PROTO_REQ_ACK_RESP = 0, + PN533_PROTO_REQ_RESP +}; + struct pn533 { struct usb_device *udev; struct usb_interface *interface; struct nfc_dev *nfc_dev; + u32 device_type; + enum pn533_protocol_type protocol_type; struct urb *out_urb; struct urb *in_urb; @@ -329,21 +359,21 @@ struct pn533 { struct work_struct poll_work; struct work_struct mi_work; struct work_struct tg_work; - struct timer_list listen_timer; - int wq_in_error; - int cancel_listen; - pn533_cmd_complete_t cmd_complete; - void *cmd_complete_arg; + struct list_head cmd_queue; + struct pn533_cmd *cmd; + u8 cmd_pending; + struct mutex cmd_lock; /* protects cmd queue */ + void *cmd_complete_mi_arg; - struct mutex cmd_lock; - u8 cmd; struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1]; u8 poll_mod_count; u8 poll_mod_curr; u32 poll_protocols; u32 listen_protocols; + struct timer_list listen_timer; + int cancel_listen; u8 *gb; size_t gb_len; @@ -352,24 +382,21 @@ struct pn533 { u8 tgt_active_prot; u8 tgt_mode; - u32 device_type; - - struct list_head cmd_queue; - u8 cmd_pending; - struct pn533_frame_ops *ops; }; struct pn533_cmd { struct list_head queue; - u8 cmd_code; + u8 code; + int status; struct sk_buff *req; struct sk_buff *resp; int resp_len; - void *arg; + pn533_send_async_complete_t complete_cb; + void *complete_cb_context; }; -struct pn533_frame { +struct pn533_std_frame { u8 preamble; __be16 start_frame; u8 datalen; @@ -393,14 +420,124 @@ struct pn533_frame_ops { u8 (*get_cmd_code)(void *frame); }; +struct pn533_acr122_ccid_hdr { + u8 type; + u32 datalen; + u8 slot; + u8 seq; + u8 params[3]; /* 3 msg specific bytes or status, error and 1 specific + byte for reposnse msg */ + u8 data[]; /* payload */ +} __packed; + +struct pn533_acr122_apdu_hdr { + u8 class; + u8 ins; + u8 p1; + u8 p2; +} __packed; + +struct pn533_acr122_tx_frame { + struct pn533_acr122_ccid_hdr ccid; + struct pn533_acr122_apdu_hdr apdu; + u8 datalen; + u8 data[]; /* pn533 frame: TFI ... */ +} __packed; + +struct pn533_acr122_rx_frame { + struct pn533_acr122_ccid_hdr ccid; + u8 data[]; /* pn533 frame : TFI ... */ +} __packed; + +static void pn533_acr122_tx_frame_init(void *_frame, u8 cmd_code) +{ + struct pn533_acr122_tx_frame *frame = _frame; + + frame->ccid.type = PN533_ACR122_PC_TO_RDR_ESCAPE; + frame->ccid.datalen = sizeof(frame->apdu) + 1; /* sizeof(apdu_hdr) + + sizeof(datalen) */ + frame->ccid.slot = 0; + frame->ccid.seq = 0; + frame->ccid.params[0] = 0; + frame->ccid.params[1] = 0; + frame->ccid.params[2] = 0; + + frame->data[0] = PN533_STD_FRAME_DIR_OUT; + frame->data[1] = cmd_code; + frame->datalen = 2; /* data[0] + data[1] */ + + frame->apdu.class = 0xFF; + frame->apdu.ins = 0; + frame->apdu.p1 = 0; + frame->apdu.p2 = 0; +} + +static void pn533_acr122_tx_frame_finish(void *_frame) +{ + struct pn533_acr122_tx_frame *frame = _frame; + + frame->ccid.datalen += frame->datalen; +} + +static void pn533_acr122_tx_update_payload_len(void *_frame, int len) +{ + struct pn533_acr122_tx_frame *frame = _frame; + + frame->datalen += len; +} + +static bool pn533_acr122_is_rx_frame_valid(void *_frame) +{ + struct pn533_acr122_rx_frame *frame = _frame; + + if (frame->ccid.type != 0x83) + return false; + + if (frame->data[frame->ccid.datalen - 2] == 0x63) + return false; + + return true; +} + +static int pn533_acr122_rx_frame_size(void *frame) +{ + struct pn533_acr122_rx_frame *f = frame; + + /* f->ccid.datalen already includes tail length */ + return sizeof(struct pn533_acr122_rx_frame) + f->ccid.datalen; +} + +static u8 pn533_acr122_get_cmd_code(void *frame) +{ + struct pn533_acr122_rx_frame *f = frame; + + return PN533_STD_FRAME_CMD(f); +} + +static struct pn533_frame_ops pn533_acr122_frame_ops = { + .tx_frame_init = pn533_acr122_tx_frame_init, + .tx_frame_finish = pn533_acr122_tx_frame_finish, + .tx_update_payload_len = pn533_acr122_tx_update_payload_len, + .tx_header_len = PN533_ACR122_TX_FRAME_HEADER_LEN, + .tx_tail_len = PN533_ACR122_TX_FRAME_TAIL_LEN, + + .rx_is_frame_valid = pn533_acr122_is_rx_frame_valid, + .rx_header_len = PN533_ACR122_RX_FRAME_HEADER_LEN, + .rx_tail_len = PN533_ACR122_RX_FRAME_TAIL_LEN, + .rx_frame_size = pn533_acr122_rx_frame_size, + + .max_payload_len = PN533_ACR122_FRAME_MAX_PAYLOAD_LEN, + .get_cmd_code = pn533_acr122_get_cmd_code, +}; + /* The rule: value + checksum = 0 */ -static inline u8 pn533_checksum(u8 value) +static inline u8 pn533_std_checksum(u8 value) { return ~value + 1; } /* The rule: sum(data elements) + checksum = 0 */ -static u8 pn533_data_checksum(u8 *data, int datalen) +static u8 pn533_std_data_checksum(u8 *data, int datalen) { u8 sum = 0; int i; @@ -408,61 +545,61 @@ static u8 pn533_data_checksum(u8 *data, int datalen) for (i = 0; i < datalen; i++) sum += data[i]; - return pn533_checksum(sum); + return pn533_std_checksum(sum); } -static void pn533_tx_frame_init(void *_frame, u8 cmd_code) +static void pn533_std_tx_frame_init(void *_frame, u8 cmd_code) { - struct pn533_frame *frame = _frame; + struct pn533_std_frame *frame = _frame; frame->preamble = 0; - frame->start_frame = cpu_to_be16(PN533_SOF); - PN533_FRAME_IDENTIFIER(frame) = PN533_DIR_OUT; - PN533_FRAME_CMD(frame) = cmd_code; + frame->start_frame = cpu_to_be16(PN533_STD_FRAME_SOF); + PN533_STD_FRAME_IDENTIFIER(frame) = PN533_STD_FRAME_DIR_OUT; + PN533_STD_FRAME_CMD(frame) = cmd_code; frame->datalen = 2; } -static void pn533_tx_frame_finish(void *_frame) +static void pn533_std_tx_frame_finish(void *_frame) { - struct pn533_frame *frame = _frame; + struct pn533_std_frame *frame = _frame; - frame->datalen_checksum = pn533_checksum(frame->datalen); + frame->datalen_checksum = pn533_std_checksum(frame->datalen); - PN533_FRAME_CHECKSUM(frame) = - pn533_data_checksum(frame->data, frame->datalen); + PN533_STD_FRAME_CHECKSUM(frame) = + pn533_std_data_checksum(frame->data, frame->datalen); - PN533_FRAME_POSTAMBLE(frame) = 0; + PN533_STD_FRAME_POSTAMBLE(frame) = 0; } -static void pn533_tx_update_payload_len(void *_frame, int len) +static void pn533_std_tx_update_payload_len(void *_frame, int len) { - struct pn533_frame *frame = _frame; + struct pn533_std_frame *frame = _frame; frame->datalen += len; } -static bool pn533_rx_frame_is_valid(void *_frame) +static bool pn533_std_rx_frame_is_valid(void *_frame) { u8 checksum; - struct pn533_frame *frame = _frame; + struct pn533_std_frame *frame = _frame; - if (frame->start_frame != cpu_to_be16(PN533_SOF)) + if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) return false; - checksum = pn533_checksum(frame->datalen); + checksum = pn533_std_checksum(frame->datalen); if (checksum != frame->datalen_checksum) return false; - checksum = pn533_data_checksum(frame->data, frame->datalen); - if (checksum != PN533_FRAME_CHECKSUM(frame)) + checksum = pn533_std_data_checksum(frame->data, frame->datalen); + if (checksum != PN533_STD_FRAME_CHECKSUM(frame)) return false; return true; } -static bool pn533_rx_frame_is_ack(struct pn533_frame *frame) +static bool pn533_std_rx_frame_is_ack(struct pn533_std_frame *frame) { - if (frame->start_frame != cpu_to_be16(PN533_SOF)) + if (frame->start_frame != cpu_to_be16(PN533_STD_FRAME_SOF)) return false; if (frame->datalen != 0 || frame->datalen_checksum != 0xFF) @@ -471,57 +608,51 @@ static bool pn533_rx_frame_is_ack(struct pn533_frame *frame) return true; } -static inline int pn533_rx_frame_size(void *frame) +static inline int pn533_std_rx_frame_size(void *frame) { - struct pn533_frame *f = frame; + struct pn533_std_frame *f = frame; - return sizeof(struct pn533_frame) + f->datalen + PN533_FRAME_TAIL_LEN; + return sizeof(struct pn533_std_frame) + f->datalen + + PN533_STD_FRAME_TAIL_LEN; } -static u8 pn533_get_cmd_code(void *frame) +static u8 pn533_std_get_cmd_code(void *frame) { - struct pn533_frame *f = frame; + struct pn533_std_frame *f = frame; - return PN533_FRAME_CMD(f); + return PN533_STD_FRAME_CMD(f); } static struct pn533_frame_ops pn533_std_frame_ops = { - .tx_frame_init = pn533_tx_frame_init, - .tx_frame_finish = pn533_tx_frame_finish, - .tx_update_payload_len = pn533_tx_update_payload_len, - .tx_header_len = PN533_FRAME_HEADER_LEN, - .tx_tail_len = PN533_FRAME_TAIL_LEN, - - .rx_is_frame_valid = pn533_rx_frame_is_valid, - .rx_frame_size = pn533_rx_frame_size, - .rx_header_len = PN533_FRAME_HEADER_LEN, - .rx_tail_len = PN533_FRAME_TAIL_LEN, - - .max_payload_len = PN533_FRAME_MAX_PAYLOAD_LEN, - .get_cmd_code = pn533_get_cmd_code, + .tx_frame_init = pn533_std_tx_frame_init, + .tx_frame_finish = pn533_std_tx_frame_finish, + .tx_update_payload_len = pn533_std_tx_update_payload_len, + .tx_header_len = PN533_STD_FRAME_HEADER_LEN, + .tx_tail_len = PN533_STD_FRAME_TAIL_LEN, + + .rx_is_frame_valid = pn533_std_rx_frame_is_valid, + .rx_frame_size = pn533_std_rx_frame_size, + .rx_header_len = PN533_STD_FRAME_HEADER_LEN, + .rx_tail_len = PN533_STD_FRAME_TAIL_LEN, + + .max_payload_len = PN533_STD_FRAME_MAX_PAYLOAD_LEN, + .get_cmd_code = pn533_std_get_cmd_code, }; static bool pn533_rx_frame_is_cmd_response(struct pn533 *dev, void *frame) { - return (dev->ops->get_cmd_code(frame) == PN533_CMD_RESPONSE(dev->cmd)); -} - - -static void pn533_wq_cmd_complete(struct work_struct *work) -{ - struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work); - int rc; - - rc = dev->cmd_complete(dev, dev->cmd_complete_arg, dev->wq_in_error); - if (rc != -EINPROGRESS) - queue_work(dev->wq, &dev->cmd_work); + return (dev->ops->get_cmd_code(frame) == + PN533_CMD_RESPONSE(dev->cmd->code)); } static void pn533_recv_response(struct urb *urb) { struct pn533 *dev = urb->context; + struct pn533_cmd *cmd = dev->cmd; u8 *in_frame; + cmd->status = urb->status; + switch (urb->status) { case 0: break; /* success */ @@ -530,37 +661,33 @@ static void pn533_recv_response(struct urb *urb) nfc_dev_dbg(&dev->interface->dev, "The urb has been canceled (status %d)", urb->status); - dev->wq_in_error = urb->status; goto sched_wq; case -ESHUTDOWN: default: nfc_dev_err(&dev->interface->dev, "Urb failure (status %d)", urb->status); - dev->wq_in_error = urb->status; goto sched_wq; } in_frame = dev->in_urb->transfer_buffer; nfc_dev_dbg(&dev->interface->dev, "Received a frame."); - print_hex_dump(KERN_DEBUG, "PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, - in_frame, dev->ops->rx_frame_size(in_frame), false); + print_hex_dump_debug("PN533 RX: ", DUMP_PREFIX_NONE, 16, 1, in_frame, + dev->ops->rx_frame_size(in_frame), false); if (!dev->ops->rx_is_frame_valid(in_frame)) { nfc_dev_err(&dev->interface->dev, "Received an invalid frame"); - dev->wq_in_error = -EIO; + cmd->status = -EIO; goto sched_wq; } if (!pn533_rx_frame_is_cmd_response(dev, in_frame)) { nfc_dev_err(&dev->interface->dev, "It it not the response to the last command"); - dev->wq_in_error = -EIO; + cmd->status = -EIO; goto sched_wq; } - dev->wq_in_error = 0; - sched_wq: queue_work(dev->wq, &dev->cmd_complete_work); } @@ -575,9 +702,12 @@ static int pn533_submit_urb_for_response(struct pn533 *dev, gfp_t flags) static void pn533_recv_ack(struct urb *urb) { struct pn533 *dev = urb->context; - struct pn533_frame *in_frame; + struct pn533_cmd *cmd = dev->cmd; + struct pn533_std_frame *in_frame; int rc; + cmd->status = urb->status; + switch (urb->status) { case 0: break; /* success */ @@ -586,21 +716,19 @@ static void pn533_recv_ack(struct urb *urb) nfc_dev_dbg(&dev->interface->dev, "The urb has been stopped (status %d)", urb->status); - dev->wq_in_error = urb->status; goto sched_wq; case -ESHUTDOWN: default: nfc_dev_err(&dev->interface->dev, "Urb failure (status %d)", urb->status); - dev->wq_in_error = urb->status; goto sched_wq; } in_frame = dev->in_urb->transfer_buffer; - if (!pn533_rx_frame_is_ack(in_frame)) { + if (!pn533_std_rx_frame_is_ack(in_frame)) { nfc_dev_err(&dev->interface->dev, "Received an invalid ack"); - dev->wq_in_error = -EIO; + cmd->status = -EIO; goto sched_wq; } @@ -608,7 +736,7 @@ static void pn533_recv_ack(struct urb *urb) if (rc) { nfc_dev_err(&dev->interface->dev, "usb_submit_urb failed with result %d", rc); - dev->wq_in_error = rc; + cmd->status = rc; goto sched_wq; } @@ -627,7 +755,7 @@ static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags) static int pn533_send_ack(struct pn533 *dev, gfp_t flags) { - u8 ack[PN533_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; + u8 ack[PN533_STD_FRAME_ACK_SIZE] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ int rc; @@ -643,32 +771,34 @@ static int pn533_send_ack(struct pn533 *dev, gfp_t flags) static int __pn533_send_frame_async(struct pn533 *dev, struct sk_buff *out, struct sk_buff *in, - int in_len, - pn533_cmd_complete_t cmd_complete, - void *arg) + int in_len) { int rc; - dev->cmd = dev->ops->get_cmd_code(out->data); - dev->cmd_complete = cmd_complete; - dev->cmd_complete_arg = arg; - dev->out_urb->transfer_buffer = out->data; dev->out_urb->transfer_buffer_length = out->len; dev->in_urb->transfer_buffer = in->data; dev->in_urb->transfer_buffer_length = in_len; - print_hex_dump(KERN_DEBUG, "PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, - out->data, out->len, false); + print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, + out->data, out->len, false); rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); if (rc) return rc; - rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL); - if (rc) - goto error; + if (dev->protocol_type == PN533_PROTO_REQ_RESP) { + /* request for response for sent packet directly */ + rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC); + if (rc) + goto error; + } else if (dev->protocol_type == PN533_PROTO_REQ_ACK_RESP) { + /* request for ACK if that's the case */ + rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL); + if (rc) + goto error; + } return 0; @@ -693,39 +823,34 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, ops->tx_frame_finish(skb->data); } -struct pn533_send_async_complete_arg { - pn533_send_async_complete_t complete_cb; - void *complete_cb_context; - struct sk_buff *resp; - struct sk_buff *req; -}; - -static int pn533_send_async_complete(struct pn533 *dev, void *_arg, int status) +static int pn533_send_async_complete(struct pn533 *dev) { - struct pn533_send_async_complete_arg *arg = _arg; + struct pn533_cmd *cmd = dev->cmd; + int status = cmd->status; - struct sk_buff *req = arg->req; - struct sk_buff *resp = arg->resp; + struct sk_buff *req = cmd->req; + struct sk_buff *resp = cmd->resp; int rc; dev_kfree_skb(req); if (status < 0) { - arg->complete_cb(dev, arg->complete_cb_context, - ERR_PTR(status)); + rc = cmd->complete_cb(dev, cmd->complete_cb_context, + ERR_PTR(status)); dev_kfree_skb(resp); - kfree(arg); - return status; + goto done; } skb_put(resp, dev->ops->rx_frame_size(resp->data)); skb_pull(resp, dev->ops->rx_header_len); skb_trim(resp, resp->len - dev->ops->rx_tail_len); - rc = arg->complete_cb(dev, arg->complete_cb_context, resp); + rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp); - kfree(arg); +done: + kfree(cmd); + dev->cmd = NULL; return rc; } @@ -736,56 +861,45 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, void *complete_cb_context) { struct pn533_cmd *cmd; - struct pn533_send_async_complete_arg *arg; int rc = 0; nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x", cmd_code); - arg = kzalloc(sizeof(*arg), GFP_KERNEL); - if (!arg) + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) return -ENOMEM; - arg->complete_cb = complete_cb; - arg->complete_cb_context = complete_cb_context; - arg->resp = resp; - arg->req = req; + cmd->code = cmd_code; + cmd->req = req; + cmd->resp = resp; + cmd->resp_len = resp_len; + cmd->complete_cb = complete_cb; + cmd->complete_cb_context = complete_cb_context; pn533_build_cmd_frame(dev, cmd_code, req); mutex_lock(&dev->cmd_lock); if (!dev->cmd_pending) { - rc = __pn533_send_frame_async(dev, req, resp, resp_len, - pn533_send_async_complete, arg); + rc = __pn533_send_frame_async(dev, req, resp, resp_len); if (rc) goto error; dev->cmd_pending = 1; + dev->cmd = cmd; goto unlock; } nfc_dev_dbg(&dev->interface->dev, "%s Queueing command 0x%x", __func__, cmd_code); - cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL); - if (!cmd) { - rc = -ENOMEM; - goto error; - } - INIT_LIST_HEAD(&cmd->queue); - cmd->cmd_code = cmd_code; - cmd->req = req; - cmd->resp = resp; - cmd->resp_len = resp_len; - cmd->arg = arg; - list_add_tail(&cmd->queue, &dev->cmd_queue); goto unlock; error: - kfree(arg); + kfree(cmd); unlock: mutex_unlock(&dev->cmd_lock); return rc; @@ -850,8 +964,8 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, pn533_send_async_complete_t complete_cb, void *complete_cb_context) { - struct pn533_send_async_complete_arg *arg; struct sk_buff *resp; + struct pn533_cmd *cmd; int rc; int resp_len = dev->ops->rx_header_len + dev->ops->max_payload_len + @@ -861,33 +975,47 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, if (!resp) return -ENOMEM; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); - if (!arg) { + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { dev_kfree_skb(resp); return -ENOMEM; } - arg->complete_cb = complete_cb; - arg->complete_cb_context = complete_cb_context; - arg->resp = resp; - arg->req = req; + cmd->code = cmd_code; + cmd->req = req; + cmd->resp = resp; + cmd->resp_len = resp_len; + cmd->complete_cb = complete_cb; + cmd->complete_cb_context = complete_cb_context; pn533_build_cmd_frame(dev, cmd_code, req); - rc = __pn533_send_frame_async(dev, req, resp, resp_len, - pn533_send_async_complete, arg); + rc = __pn533_send_frame_async(dev, req, resp, resp_len); if (rc < 0) { dev_kfree_skb(resp); - kfree(arg); + kfree(cmd); + } else { + dev->cmd = cmd; } return rc; } +static void pn533_wq_cmd_complete(struct work_struct *work) +{ + struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work); + int rc; + + rc = pn533_send_async_complete(dev); + if (rc != -EINPROGRESS) + queue_work(dev->wq, &dev->cmd_work); +} + static void pn533_wq_cmd(struct work_struct *work) { struct pn533 *dev = container_of(work, struct pn533, cmd_work); struct pn533_cmd *cmd; + int rc; mutex_lock(&dev->cmd_lock); @@ -903,10 +1031,15 @@ static void pn533_wq_cmd(struct work_struct *work) mutex_unlock(&dev->cmd_lock); - __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len, - pn533_send_async_complete, cmd->arg); + rc = __pn533_send_frame_async(dev, cmd->req, cmd->resp, cmd->resp_len); + if (rc < 0) { + dev_kfree_skb(cmd->req); + dev_kfree_skb(cmd->resp); + kfree(cmd); + return; + } - kfree(cmd); + dev->cmd = cmd; } struct pn533_sync_cmd_response { @@ -982,6 +1115,23 @@ static void pn533_send_complete(struct urb *urb) } } +static void pn533_abort_cmd(struct pn533 *dev, gfp_t flags) +{ + /* ACR122U does not support any command which aborts last + * issued command i.e. as ACK for standard PN533. Additionally, + * it behaves stange, sending broken or incorrect responses, + * when we cancel urb before the chip will send response. + */ + if (dev->device_type == PN533_DEVICE_ACR122U) + return; + + /* An ack will cancel the last issued command */ + pn533_send_ack(dev, flags); + + /* cancel the urb request */ + usb_kill_urb(dev->in_urb); +} + static struct sk_buff *pn533_alloc_skb(struct pn533 *dev, unsigned int size) { struct sk_buff *skb; @@ -1500,9 +1650,6 @@ static void pn533_listen_mode_timer(unsigned long data) nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout"); - /* An ack will cancel the last issued command (poll) */ - pn533_send_ack(dev, GFP_ATOMIC); - dev->cancel_listen = 1; pn533_poll_next_mod(dev); @@ -1549,6 +1696,11 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, if (!rc) goto done; + if (!dev->poll_mod_count) { + nfc_dev_dbg(&dev->interface->dev, "Polling has been stoped."); + goto done; + } + pn533_poll_next_mod(dev); queue_work(dev->wq, &dev->poll_work); @@ -1627,7 +1779,7 @@ static void pn533_wq_poll(struct work_struct *work) if (dev->cancel_listen == 1) { dev->cancel_listen = 0; - usb_kill_urb(dev->in_urb); + pn533_abort_cmd(dev, GFP_ATOMIC); } rc = pn533_send_poll_frame(dev); @@ -1689,12 +1841,7 @@ static void pn533_stop_poll(struct nfc_dev *nfc_dev) return; } - /* An ack will cancel the last issued command (poll) */ - pn533_send_ack(dev, GFP_KERNEL); - - /* prevent pn533_start_poll_complete to issue a new poll meanwhile */ - usb_kill_urb(dev->in_urb); - + pn533_abort_cmd(dev, GFP_KERNEL); pn533_poll_reset_mod_list(dev); } @@ -1723,6 +1870,8 @@ static int pn533_activate_target_nfcdep(struct pn533 *dev) rsp = (struct pn533_cmd_activate_response *)resp->data; rc = rsp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { + nfc_dev_err(&dev->interface->dev, + "Target activation failed (error 0x%x)", rc); dev_kfree_skb(resp); return -EIO; } @@ -1850,7 +1999,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, rc = rsp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, - "Bringing DEP link up failed %d", rc); + "Bringing DEP link up failed (error 0x%x)", rc); goto error; } @@ -1985,10 +2134,8 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev) pn533_poll_reset_mod_list(dev); - if (dev->tgt_mode || dev->tgt_active_prot) { - pn533_send_ack(dev, GFP_KERNEL); - usb_kill_urb(dev->in_urb); - } + if (dev->tgt_mode || dev->tgt_active_prot) + pn533_abort_cmd(dev, GFP_KERNEL); dev->tgt_active_prot = 0; dev->tgt_mode = 0; @@ -2064,8 +2211,7 @@ static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg, if (ret != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, - "PN533 reported error %d when exchanging data", - ret); + "Exchanging data failed (error 0x%x)", ret); rc = -EIO; goto error; } @@ -2253,7 +2399,7 @@ static void pn533_wq_mi_recv(struct work_struct *work) "Error %d when trying to perform data_exchange", rc); dev_kfree_skb(skb); - kfree(dev->cmd_complete_arg); + kfree(dev->cmd_complete_mi_arg); error: pn533_send_ack(dev, GFP_KERNEL); @@ -2310,7 +2456,7 @@ static int pn533_get_firmware_version(struct pn533 *dev, return 0; } -static int pn533_fw_reset(struct pn533 *dev) +static int pn533_pasori_fw_reset(struct pn533 *dev) { struct sk_buff *skb; struct sk_buff *resp; @@ -2332,9 +2478,102 @@ static int pn533_fw_reset(struct pn533 *dev) return 0; } +struct pn533_acr122_poweron_rdr_arg { + int rc; + struct completion done; +}; + +static void pn533_acr122_poweron_rdr_resp(struct urb *urb) +{ + struct pn533_acr122_poweron_rdr_arg *arg = urb->context; + + nfc_dev_dbg(&urb->dev->dev, "%s", __func__); + + print_hex_dump(KERN_ERR, "ACR122 RX: ", DUMP_PREFIX_NONE, 16, 1, + urb->transfer_buffer, urb->transfer_buffer_length, + false); + + arg->rc = urb->status; + complete(&arg->done); +} + +static int pn533_acr122_poweron_rdr(struct pn533 *dev) +{ + /* Power on th reader (CCID cmd) */ + u8 cmd[10] = {PN533_ACR122_PC_TO_RDR_ICCPOWERON, + 0, 0, 0, 0, 0, 0, 3, 0, 0}; + u8 buf[255]; + int rc; + void *cntx; + struct pn533_acr122_poweron_rdr_arg arg; + + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + + init_completion(&arg.done); + cntx = dev->in_urb->context; /* backup context */ + + dev->in_urb->transfer_buffer = buf; + dev->in_urb->transfer_buffer_length = 255; + dev->in_urb->complete = pn533_acr122_poweron_rdr_resp; + dev->in_urb->context = &arg; + + dev->out_urb->transfer_buffer = cmd; + dev->out_urb->transfer_buffer_length = sizeof(cmd); + + print_hex_dump(KERN_ERR, "ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1, + cmd, sizeof(cmd), false); + + rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Reader power on cmd error %d", rc); + return rc; + } + + rc = usb_submit_urb(dev->in_urb, GFP_KERNEL); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Can't submit for reader power on cmd response %d", + rc); + return rc; + } + + wait_for_completion(&arg.done); + dev->in_urb->context = cntx; /* restore context */ + + return arg.rc; +} + +static int pn533_rf_field(struct nfc_dev *nfc_dev, u8 rf) +{ + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + u8 rf_field = !!rf; + int rc; + + rc = pn533_set_configuration(dev, PN533_CFGITEM_RF_FIELD, + (u8 *)&rf_field, 1); + if (rc) { + nfc_dev_err(&dev->interface->dev, + "Error on setting RF field"); + return rc; + } + + return rc; +} + +int pn533_dev_up(struct nfc_dev *nfc_dev) +{ + return pn533_rf_field(nfc_dev, 1); +} + +int pn533_dev_down(struct nfc_dev *nfc_dev) +{ + return pn533_rf_field(nfc_dev, 0); +} + static struct nfc_ops pn533_nfc_ops = { - .dev_up = NULL, - .dev_down = NULL, + .dev_up = pn533_dev_up, + .dev_down = pn533_dev_down, .dep_link_up = pn533_dep_link_up, .dep_link_down = pn533_dep_link_down, .start_poll = pn533_start_poll, @@ -2366,6 +2605,7 @@ static int pn533_setup(struct pn533 *dev) break; case PN533_DEVICE_PASORI: + case PN533_DEVICE_ACR122U: max_retries.mx_rty_atr = 0x2; max_retries.mx_rty_psl = 0x1; max_retries.mx_rty_passive_act = @@ -2405,7 +2645,7 @@ static int pn533_setup(struct pn533 *dev) break; case PN533_DEVICE_PASORI: - pn533_fw_reset(dev); + pn533_pasori_fw_reset(dev); rc = pn533_set_configuration(dev, PN533_CFGITEM_PASORI, pasori_cfg, 3); @@ -2415,7 +2655,7 @@ static int pn533_setup(struct pn533 *dev) return rc; } - pn533_fw_reset(dev); + pn533_pasori_fw_reset(dev); break; } @@ -2496,6 +2736,7 @@ static int pn533_probe(struct usb_interface *interface, dev->ops = &pn533_std_frame_ops; + dev->protocol_type = PN533_PROTO_REQ_ACK_RESP; dev->device_type = id->driver_info; switch (dev->device_type) { case PN533_DEVICE_STD: @@ -2506,6 +2747,20 @@ static int pn533_probe(struct usb_interface *interface, protocols = PN533_NO_TYPE_B_PROTOCOLS; break; + case PN533_DEVICE_ACR122U: + protocols = PN533_NO_TYPE_B_PROTOCOLS; + dev->ops = &pn533_acr122_frame_ops; + dev->protocol_type = PN533_PROTO_REQ_RESP, + + rc = pn533_acr122_poweron_rdr(dev); + if (rc < 0) { + nfc_dev_err(&dev->interface->dev, + "Couldn't poweron the reader (error %d)", + rc); + goto destroy_wq; + } + break; + default: nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n", dev->device_type); @@ -2555,6 +2810,7 @@ destroy_wq: error: usb_free_urb(dev->in_urb); usb_free_urb(dev->out_urb); + usb_put_dev(dev->udev); kfree(dev); return rc; } @@ -2600,8 +2856,9 @@ static struct usb_driver pn533_driver = { module_usb_driver(pn533_driver); -MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>," - " Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); +MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>"); +MODULE_AUTHOR("Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); +MODULE_AUTHOR("Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>"); MODULE_DESCRIPTION("PN533 usb driver ver " VERSION); MODULE_VERSION(VERSION); 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 Select this if your platform is using the i2c bus. If you choose to build a module, it'll be called pn544_i2c. - Say N if unsure.
\ No newline at end of file + Say N if unsure. + +config NFC_PN544_MEI + tristate "NFC PN544 MEI support" + depends on NFC_PN544 && NFC_MEI_PHY + ---help--- + This module adds support for the mei interface of adapters using + NXP pn544 chipsets. Select this if your pn544 chipset + is handled by Intel's Management Engine Interface on your platform. + + If you choose to build a module, it'll be called pn544_mei. + 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 @@ # pn544_i2c-objs = i2c.o +pn544_mei-objs = mei.o obj-$(CONFIG_NFC_PN544) += pn544.o obj-$(CONFIG_NFC_PN544_I2C) += pn544_i2c.o +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 @@ +/* + * HCI based Driver for NXP pn544 NFC Chip + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/nfc.h> +#include <net/nfc/hci.h> +#include <net/nfc/llc.h> + +#include "../mei_phy.h" +#include "pn544.h" + +#define PN544_DRIVER_NAME "pn544" + +static int pn544_mei_probe(struct mei_cl_device *device, + const struct mei_cl_device_id *id) +{ + struct nfc_mei_phy *phy; + int r; + + pr_info("Probing NFC pn544\n"); + + phy = nfc_mei_phy_alloc(device); + if (!phy) { + pr_err("Cannot allocate memory for pn544 mei phy.\n"); + return -ENOMEM; + } + + r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy); + if (r) { + pr_err(PN544_DRIVER_NAME ": event cb registration failed\n"); + goto err_out; + } + + r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME, + MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD, + &phy->hdev); + if (r < 0) + goto err_out; + + return 0; + +err_out: + nfc_mei_phy_free(phy); + + return r; +} + +static int pn544_mei_remove(struct mei_cl_device *device) +{ + struct nfc_mei_phy *phy = mei_cl_get_drvdata(device); + + pr_info("Removing pn544\n"); + + pn544_hci_remove(phy->hdev); + + nfc_mei_phy_disable(phy); + + nfc_mei_phy_free(phy); + + return 0; +} + +static struct mei_cl_device_id pn544_mei_tbl[] = { + { PN544_DRIVER_NAME }, + + /* required last entry */ + { } +}; +MODULE_DEVICE_TABLE(mei, pn544_mei_tbl); + +static struct mei_cl_driver pn544_driver = { + .id_table = pn544_mei_tbl, + .name = PN544_DRIVER_NAME, + + .probe = pn544_mei_probe, + .remove = pn544_mei_remove, +}; + +static int pn544_mei_init(void) +{ + int r; + + pr_debug(DRIVER_DESC ": %s\n", __func__); + + r = mei_cl_driver_register(&pn544_driver); + if (r) { + pr_err(PN544_DRIVER_NAME ": driver registration failed\n"); + return r; + } + + return 0; +} + +static void pn544_mei_exit(void) +{ + mei_cl_driver_unregister(&pn544_driver); +} + +module_init(pn544_mei_init); +module_exit(pn544_mei_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); |