提交 6ed0e321 编写于 作者: J John W. Linville

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
...@@ -90,6 +90,7 @@ static struct usb_device_id ath3k_table[] = { ...@@ -90,6 +90,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3393) }, { USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x0489, 0xe04e) }, { USB_DEVICE(0x0489, 0xe04e) },
{ USB_DEVICE(0x0489, 0xe056) }, { USB_DEVICE(0x0489, 0xe056) },
{ USB_DEVICE(0x0489, 0xe04d) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) },
...@@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { ...@@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .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 */ /* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
......
...@@ -148,6 +148,7 @@ static struct usb_device_id blacklist_table[] = { ...@@ -148,6 +148,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .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 */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
...@@ -926,6 +927,22 @@ static void btusb_waker(struct work_struct *work) ...@@ -926,6 +927,22 @@ static void btusb_waker(struct work_struct *work)
usb_autopm_put_interface(data->intf); 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, static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
...@@ -1022,11 +1039,14 @@ static int btusb_probe(struct usb_interface *intf, ...@@ -1022,11 +1039,14 @@ static int btusb_probe(struct usb_interface *intf,
SET_HCIDEV_DEV(hdev, &intf->dev); SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = btusb_open; hdev->open = btusb_open;
hdev->close = btusb_close; hdev->close = btusb_close;
hdev->flush = btusb_flush; hdev->flush = btusb_flush;
hdev->send = btusb_send_frame; hdev->send = btusb_send_frame;
hdev->notify = btusb_notify; hdev->notify = btusb_notify;
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
/* Interface numbers are hardcoded in the specification */ /* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1); data->isoc = usb_ifnum_to_if(data->udev, 1);
...@@ -1065,17 +1085,6 @@ static int btusb_probe(struct usb_interface *intf, ...@@ -1065,17 +1085,6 @@ static int btusb_probe(struct usb_interface *intf,
data->isoc = NULL; 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) { if (data->isoc) {
err = usb_driver_claim_interface(&btusb_driver, err = usb_driver_claim_interface(&btusb_driver,
data->isoc, data); data->isoc, data);
......
...@@ -153,6 +153,9 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) ...@@ -153,6 +153,9 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
{ {
int ret; int ret;
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
return -EUNATCH;
ret = hci_recv_stream_fragment(hu->hdev, data, count); ret = hci_recv_stream_fragment(hu->hdev, data, count);
if (ret < 0) { if (ret < 0) {
BT_ERR("Frame Reassembly Failed"); BT_ERR("Frame Reassembly Failed");
......
...@@ -260,12 +260,12 @@ static int hci_uart_send_frame(struct sk_buff *skb) ...@@ -260,12 +260,12 @@ static int hci_uart_send_frame(struct sk_buff *skb)
/* ------ LDISC part ------ */ /* ------ LDISC part ------ */
/* hci_uart_tty_open /* hci_uart_tty_open
* *
* Called when line discipline changed to HCI_UART. * Called when line discipline changed to HCI_UART.
* *
* Arguments: * Arguments:
* tty pointer to tty info structure * tty pointer to tty info structure
* Return Value: * Return Value:
* 0 if success, otherwise error code * 0 if success, otherwise error code
*/ */
static int hci_uart_tty_open(struct tty_struct *tty) static int hci_uart_tty_open(struct tty_struct *tty)
...@@ -365,15 +365,15 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) ...@@ -365,15 +365,15 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
} }
/* hci_uart_tty_receive() /* hci_uart_tty_receive()
* *
* Called by tty low level driver when receive data is * Called by tty low level driver when receive data is
* available. * available.
* *
* Arguments: tty pointer to tty isntance data * Arguments: tty pointer to tty isntance data
* data pointer to received data * data pointer to received data
* flags pointer to flags for data * flags pointer to flags for data
* count count of received data in bytes * count count of received data in bytes
* *
* Return Value: None * Return Value: None
*/ */
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
...@@ -388,7 +388,10 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f ...@@ -388,7 +388,10 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
spin_lock(&hu->rx_lock); spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count); 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); spin_unlock(&hu->rx_lock);
tty_unthrottle(tty); tty_unthrottle(tty);
......
...@@ -1293,7 +1293,8 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed) ...@@ -1293,7 +1293,8 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
{ {
struct adm8211_priv *priv = dev->priv; struct adm8211_priv *priv = dev->priv;
struct ieee80211_conf *conf = &dev->conf; 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) { if (channel != priv->channel) {
priv->channel = channel; priv->channel = channel;
......
...@@ -1943,12 +1943,12 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1943,12 +1943,12 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
struct at76_priv *priv = hw->priv; struct at76_priv *priv = hw->priv;
at76_dbg(DBG_MAC80211, "%s(): channel %d", 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:"); at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
mutex_lock(&priv->mtx); 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)) if (is_valid_ether_addr(priv->bssid))
at76_join(priv); at76_join(priv);
......
...@@ -457,14 +457,14 @@ static int ar5523_set_chan(struct ar5523 *ar) ...@@ -457,14 +457,14 @@ static int ar5523_set_chan(struct ar5523 *ar)
memset(&reset, 0, sizeof(reset)); memset(&reset, 0, sizeof(reset));
reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ);
reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); 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.maxrdpower = cpu_to_be32(50); /* XXX */
reset.channelchange = cpu_to_be32(1); reset.channelchange = cpu_to_be32(1);
reset.keeprccontent = cpu_to_be32(0); reset.keeprccontent = cpu_to_be32(0);
ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", ar5523_dbg(ar, "set chan flags 0x%x freq %d\n",
be32_to_cpu(reset.flags), 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); return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0);
} }
...@@ -594,7 +594,7 @@ static void ar5523_data_rx_cb(struct urb *urb) ...@@ -594,7 +594,7 @@ static void ar5523_data_rx_cb(struct urb *urb)
rx_status = IEEE80211_SKB_RXCB(data->skb); rx_status = IEEE80211_SKB_RXCB(data->skb);
memset(rx_status, 0, sizeof(*rx_status)); memset(rx_status, 0, sizeof(*rx_status));
rx_status->freq = be32_to_cpu(desc->channel); 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); rx_status->signal = -95 + be32_to_cpu(desc->rssi);
ieee80211_rx_irqsafe(hw, data->skb); ieee80211_rx_irqsafe(hw, data->skb);
...@@ -1153,13 +1153,13 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar, ...@@ -1153,13 +1153,13 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar,
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
u32 sta_rate_set; 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); sta = ieee80211_find_sta(ar->vif, bss_conf->bssid);
if (!sta) { if (!sta) {
ar5523_info(ar, "STA not found!\n"); ar5523_info(ar, "STA not found!\n");
return WLAN_MODE_11b; 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++) { for (bit = 0; bit < band->n_bitrates; bit++) {
if (sta_rate_set & 1) { if (sta_rate_set & 1) {
...@@ -1197,11 +1197,11 @@ static void ar5523_create_rateset(struct ar5523 *ar, ...@@ -1197,11 +1197,11 @@ static void ar5523_create_rateset(struct ar5523 *ar,
ar5523_info(ar, "STA not found. Cannot set rates\n"); ar5523_info(ar, "STA not found. Cannot set rates\n");
sta_rate_set = bss_conf->basic_rates; sta_rate_set = bss_conf->basic_rates;
} else } 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); 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++) { for (bit = 0; bit < band->n_bitrates; bit++) {
BUG_ON(i >= AR5523_MAX_NRATES); BUG_ON(i >= AR5523_MAX_NRATES);
ar5523_dbg(ar, "Considering rate %d : %d\n", ar5523_dbg(ar, "Considering rate %d : %d\n",
......
...@@ -10,6 +10,7 @@ ath5k-y += phy.o ...@@ -10,6 +10,7 @@ ath5k-y += phy.o
ath5k-y += reset.o ath5k-y += reset.o
ath5k-y += attach.o ath5k-y += attach.o
ath5k-y += base.o ath5k-y += base.o
CFLAGS_base.o += -I$(src)
ath5k-y += led.o ath5k-y += led.o
ath5k-y += rfkill.o ath5k-y += rfkill.o
ath5k-y += ani.o ath5k-y += ani.o
......
...@@ -2639,7 +2639,7 @@ int ath5k_start(struct ieee80211_hw *hw) ...@@ -2639,7 +2639,7 @@ int ath5k_start(struct ieee80211_hw *hw)
* be followed by initialization of the appropriate bits * be followed by initialization of the appropriate bits
* and then setup of the interrupt mask. * 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 ah->imask = AR5K_INT_RXOK
| AR5K_INT_RXERR | AR5K_INT_RXERR
| AR5K_INT_RXEOL | AR5K_INT_RXEOL
......
...@@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&ah->lock); mutex_lock(&ah->lock);
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
ret = ath5k_chan_set(ah, conf->channel); ret = ath5k_chan_set(ah, conf->chandef.chan);
if (ret < 0) if (ret < 0)
goto unlock; goto unlock;
} }
...@@ -678,7 +678,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) ...@@ -678,7 +678,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
memcpy(survey, &ah->survey, sizeof(*survey)); memcpy(survey, &ah->survey, sizeof(*survey));
survey->channel = conf->channel; survey->channel = conf->chandef.chan;
survey->noise = ah->ah_noise_floor; survey->noise = ah->ah_noise_floor;
survey->filled = SURVEY_INFO_NOISE_DBM | survey->filled = SURVEY_INFO_NOISE_DBM |
SURVEY_INFO_CHANNEL_TIME | SURVEY_INFO_CHANNEL_TIME |
......
...@@ -97,7 +97,7 @@ TRACE_EVENT(ath5k_tx_complete, ...@@ -97,7 +97,7 @@ TRACE_EVENT(ath5k_tx_complete,
#if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) #if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__)
#undef TRACE_INCLUDE_PATH #undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k #define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE #undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace #define TRACE_INCLUDE_FILE trace
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "hw-ops.h" #include "hw-ops.h"
#include "../regd.h" #include "../regd.h"
#include "ar9002_phy.h" #include "ar9002_phy.h"
#include "ar5008_initvals.h"
/* All code below is for AR5008, AR9001, AR9002 */ /* All code below is for AR5008, AR9001, AR9002 */
...@@ -43,23 +44,16 @@ static const int m2ThreshLowExt_off = 127; ...@@ -43,23 +44,16 @@ static const int m2ThreshLowExt_off = 127;
static const int m1ThreshExt_off = 127; static const int m1ThreshExt_off = 127;
static const int m2ThreshExt_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, static void ar5008_write_bank6(struct ath_hw *ah, unsigned int *writecnt)
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)
{ {
struct ar5416IniArray *array = &ah->iniBank6;
u32 *data = ah->analogBank6Data;
int r; int r;
ENABLE_REGWRITE_BUFFER(ah); ENABLE_REGWRITE_BUFFER(ah);
...@@ -165,7 +159,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) ...@@ -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); ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
/* write Bank 6 with new params */ /* write Bank 6 with new params */
REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); ar5008_write_bank6(ah, &reg_writes);
} }
/** /**
...@@ -469,31 +463,16 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, ...@@ -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) static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
{ {
#define ATH_ALLOC_BANK(bank, size) do { \ int size = ah->iniBank6.ia_rows * sizeof(u32);
bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \
if (!bank) \
goto error; \
} while (0);
struct ath_common *common = ath9k_hw_common(ah);
if (AR_SREV_9280_20_OR_LATER(ah)) if (AR_SREV_9280_20_OR_LATER(ah))
return 0; return 0;
ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); ah->analogBank6Data = devm_kzalloc(ah->dev, size, GFP_KERNEL);
ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); if (!ah->analogBank6Data)
ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); return -ENOMEM;
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);
return 0; 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, ...@@ -517,6 +496,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
u32 ob5GHz = 0, db5GHz = 0; u32 ob5GHz = 0, db5GHz = 0;
u32 ob2GHz = 0, db2GHz = 0; u32 ob2GHz = 0, db2GHz = 0;
int regWrites = 0; int regWrites = 0;
int i;
/* /*
* Software does not need to program bank data * Software does not need to program bank data
...@@ -529,25 +509,8 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, ...@@ -529,25 +509,8 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
/* Setup rf parameters */ /* Setup rf parameters */
eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
/* Setup Bank 0 Write */ for (i = 0; i < ah->iniBank6.ia_rows; i++)
ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1); ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex);
/* 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);
}
}
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */ /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (eepMinorRev >= 2) { if (eepMinorRev >= 2) {
...@@ -568,22 +531,13 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, ...@@ -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 */ /* Write Analog registers */
REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, REG_WRITE_ARRAY(&bank0, 1, regWrites);
regWrites); REG_WRITE_ARRAY(&bank1, 1, regWrites);
REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, REG_WRITE_ARRAY(&bank2, 1, regWrites);
regWrites); REG_WRITE_ARRAY(&bank3, modesIndex, regWrites);
REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, ar5008_write_bank6(ah, &regWrites);
regWrites); REG_WRITE_ARRAY(&bank7, 1, 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);
return true; return true;
} }
......
...@@ -67,12 +67,10 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah) ...@@ -67,12 +67,10 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
} else if (AR_SREV_9100_OR_LATER(ah)) { } else if (AR_SREV_9100_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100); INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100);
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100);
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100); INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100);
} else { } else {
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes); INIT_INI_ARRAY(&ah->iniModes, ar5416Modes);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common);
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC);
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac); INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac);
} }
...@@ -80,20 +78,11 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah) ...@@ -80,20 +78,11 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
/* Common for AR5416, AR913x, AR9160 */ /* Common for AR5416, AR913x, AR9160 */
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain); 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 */ /* Common for AR913x, AR9160 */
if (!AR_SREV_5416(ah)) if (!AR_SREV_5416(ah))
INIT_INI_ARRAY(&ah->iniBank6TPC, INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC_9100);
ar5416Bank6TPC_9100); else
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6TPC);
} }
/* iniAddac needs to be modified for these chips */ /* iniAddac needs to be modified for these chips */
......
...@@ -234,6 +234,7 @@ struct ath_buf { ...@@ -234,6 +234,7 @@ struct ath_buf {
dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
bool bf_stale; bool bf_stale;
struct ieee80211_tx_rate rates[4];
struct ath_buf_state bf_state; struct ath_buf_state bf_state;
}; };
...@@ -311,6 +312,7 @@ struct ath_rx_edma { ...@@ -311,6 +312,7 @@ struct ath_rx_edma {
struct ath_rx { struct ath_rx {
u8 defant; u8 defant;
u8 rxotherant; u8 rxotherant;
bool discard_next;
u32 *rxlink; u32 *rxlink;
u32 num_pkts; u32 num_pkts;
unsigned int rxfilter; unsigned int rxfilter;
...@@ -657,11 +659,10 @@ enum sc_op_flags { ...@@ -657,11 +659,10 @@ enum sc_op_flags {
struct ath_rate_table; struct ath_rate_table;
struct ath9k_vif_iter_data { struct ath9k_vif_iter_data {
const u8 *hw_macaddr; /* phy's hardware address, set u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
* before starting iteration for
* valid bssid mask.
*/
u8 mask[ETH_ALEN]; /* bssid mask */ u8 mask[ETH_ALEN]; /* bssid mask */
bool has_hw_macaddr;
int naps; /* number of AP vifs */ int naps; /* number of AP vifs */
int nmeshes; /* number of mesh vifs */ int nmeshes; /* number of mesh vifs */
int nstations; /* number of station vifs */ int nstations; /* number of station vifs */
......
...@@ -79,7 +79,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, ...@@ -79,7 +79,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
u8 chainmask = ah->txchainmask; u8 chainmask = ah->txchainmask;
u8 rate = 0; 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; rate = sband->bitrates[rateidx].hw_value;
if (vif->bss_conf.use_short_preamble) if (vif->bss_conf.use_short_preamble)
rate |= sband->bitrates[rateidx].hw_value_short; rate |= sband->bitrates[rateidx].hw_value_short;
......
...@@ -208,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) ...@@ -208,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true; return true;
ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", 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; ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING; currCal->calState = CAL_WAITING;
......
...@@ -33,6 +33,12 @@ struct ar5416IniArray { ...@@ -33,6 +33,12 @@ struct ar5416IniArray {
u32 ia_columns; 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 { \ #define INIT_INI_ARRAY(iniarray, array) do { \
(iniarray)->ia_array = (u32 *)(array); \ (iniarray)->ia_array = (u32 *)(array); \
(iniarray)->ia_rows = ARRAY_SIZE(array); \ (iniarray)->ia_rows = ARRAY_SIZE(array); \
......
...@@ -27,20 +27,6 @@ MODULE_AUTHOR("Atheros Communications"); ...@@ -27,20 +27,6 @@ MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
MODULE_LICENSE("Dual BSD/GPL"); 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) int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
{ {
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
...@@ -133,13 +119,14 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel); ...@@ -133,13 +119,14 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah) struct ath_hw *ah)
{ {
struct ieee80211_channel *curchan = hw->conf.channel; struct ieee80211_channel *curchan = hw->conf.chandef.chan;
struct ath9k_channel *channel; struct ath9k_channel *channel;
u8 chan_idx; u8 chan_idx;
chan_idx = curchan->hw_value; chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx]; 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; return channel;
} }
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#define ATH_EP_RND(x, mul) \ #define ATH_EP_RND(x, mul) \
(((x) + ((mul)/2)) / (mul)) (((x) + ((mul)/2)) / (mul))
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
......
...@@ -55,12 +55,6 @@ ath9k_postprocess_radar_event(struct ath_softc *sc, ...@@ -55,12 +55,6 @@ ath9k_postprocess_radar_event(struct ath_softc *sc,
u8 rssi; u8 rssi;
u16 dur; 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 * Only the last 2 bits of the BW info are relevant, they indicate
* which channel the radar was detected in. * which channel the radar was detected in.
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "dfs_pattern_detector.h" #include "dfs_pattern_detector.h"
#include "dfs_pri_detector.h" #include "dfs_pri_detector.h"
#include "ath9k.h"
/* /*
* tolerated deviation of radar time stamp in usecs on both sides * tolerated deviation of radar time stamp in usecs on both sides
...@@ -142,6 +143,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) ...@@ -142,6 +143,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
{ {
u32 sz, i; u32 sz, i;
struct channel_detector *cd; struct channel_detector *cd;
struct ath_common *common = ath9k_hw_common(dpd->ah);
cd = kmalloc(sizeof(*cd), GFP_ATOMIC); cd = kmalloc(sizeof(*cd), GFP_ATOMIC);
if (cd == NULL) if (cd == NULL)
...@@ -165,7 +167,8 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) ...@@ -165,7 +167,8 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq)
return cd; return cd;
fail: 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); channel_detector_exit(dpd, cd);
return NULL; return NULL;
} }
...@@ -216,34 +219,34 @@ static bool ...@@ -216,34 +219,34 @@ static bool
dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
{ {
u32 i; u32 i;
bool ts_wraparound;
struct channel_detector *cd; struct channel_detector *cd;
if (dpd->region == NL80211_DFS_UNSET) { /*
/* * pulses received for a non-supported or un-initialized
* pulses received for a non-supported or un-initialized * domain are treated as detected radars for fail-safety
* domain are treated as detected radars */
*/ if (dpd->region == NL80211_DFS_UNSET)
return true; return true;
}
cd = channel_detector_get(dpd, event->freq); cd = channel_detector_get(dpd, event->freq);
if (cd == NULL) if (cd == NULL)
return false; return false;
ts_wraparound = (event->ts < dpd->last_pulse_ts);
dpd->last_pulse_ts = event->ts; dpd->last_pulse_ts = event->ts;
if (ts_wraparound) { /* reset detector on time stamp wraparound, caused by TSF reset */
/* if (event->ts < dpd->last_pulse_ts)
* reset detector on time stamp wraparound
* with monotonic time stamps, this should never happen
*/
pr_warn("DFS: time stamp wraparound detected, resetting\n");
dpd_reset(dpd); dpd_reset(dpd);
}
/* do type individual pattern matching */ /* do type individual pattern matching */
for (i = 0; i < dpd->num_radar_types; i++) { 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); channel_detector_reset(dpd, cd);
return true; return true;
} }
...@@ -285,9 +288,10 @@ static struct dfs_pattern_detector default_dpd = { ...@@ -285,9 +288,10 @@ static struct dfs_pattern_detector default_dpd = {
}; };
struct dfs_pattern_detector * 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 dfs_pattern_detector *dpd;
struct ath_common *common = ath9k_hw_common(ah);
dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); dpd = kmalloc(sizeof(*dpd), GFP_KERNEL);
if (dpd == NULL) if (dpd == NULL)
...@@ -296,10 +300,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) ...@@ -296,10 +300,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region)
*dpd = default_dpd; *dpd = default_dpd;
INIT_LIST_HEAD(&dpd->channel_detectors); INIT_LIST_HEAD(&dpd->channel_detectors);
dpd->ah = ah;
if (dpd->set_dfs_domain(dpd, region)) if (dpd->set_dfs_domain(dpd, region))
return dpd; 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); kfree(dpd);
return NULL; return NULL;
} }
......
...@@ -80,6 +80,8 @@ struct dfs_pattern_detector { ...@@ -80,6 +80,8 @@ struct dfs_pattern_detector {
enum nl80211_dfs_regions region; enum nl80211_dfs_regions region;
u8 num_radar_types; u8 num_radar_types;
u64 last_pulse_ts; u64 last_pulse_ts;
/* needed for ath_dbg() */
struct ath_hw *ah;
const struct radar_detector_specs *radar_spec; const struct radar_detector_specs *radar_spec;
struct list_head channel_detectors; struct list_head channel_detectors;
...@@ -92,10 +94,10 @@ struct dfs_pattern_detector { ...@@ -92,10 +94,10 @@ struct dfs_pattern_detector {
*/ */
#if defined(CONFIG_ATH9K_DFS_CERTIFIED) #if defined(CONFIG_ATH9K_DFS_CERTIFIED)
extern struct dfs_pattern_detector * 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 #else
static inline struct dfs_pattern_detector * 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; return NULL;
} }
......
...@@ -22,28 +22,6 @@ ...@@ -22,28 +22,6 @@
#include "dfs_pri_detector.h" #include "dfs_pri_detector.h"
#include "dfs_debug.h" #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 * struct pulse_elem - elements in pulse queue
* @ts: time stamp in usecs * @ts: time stamp in usecs
...@@ -393,8 +371,8 @@ static void pri_detector_exit(struct pri_detector *de) ...@@ -393,8 +371,8 @@ static void pri_detector_exit(struct pri_detector *de)
kfree(de); kfree(de);
} }
static bool pri_detector_add_pulse(struct pri_detector *de, static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de,
struct pulse_event *event) struct pulse_event *event)
{ {
u32 max_updated_seq; u32 max_updated_seq;
struct pri_sequence *ps; struct pri_sequence *ps;
...@@ -403,38 +381,33 @@ static bool pri_detector_add_pulse(struct pri_detector *de, ...@@ -403,38 +381,33 @@ static bool pri_detector_add_pulse(struct pri_detector *de,
/* ignore pulses not within width range */ /* ignore pulses not within width range */
if ((rs->width_min > event->width) || (rs->width_max < event->width)) 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 ((ts - de->last_ts) < rs->max_pri_tolerance)
/* if delta to last pulse is too short, don't use this pulse */ /* if delta to last pulse is too short, don't use this pulse */
return false; return NULL;
de->last_ts = ts; de->last_ts = ts;
max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts); max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts);
if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) { if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) {
pr_err("failed to create pulse sequences\n");
pri_detector_reset(de, ts); pri_detector_reset(de, ts);
return false; return false;
} }
ps = pseq_handler_check_detection(de); ps = pseq_handler_check_detection(de);
if (ps != NULL) { if (ps == NULL)
pr_info("DFS: radar found: pri=%d, count=%d, count_false=%d\n", pulse_queue_enqueue(de, ts);
ps->pri, ps->count, ps->count_falses);
pri_detector_reset(de, ts); return ps;
return true;
}
pulse_queue_enqueue(de, ts);
return false;
} }
struct pri_detector * struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs)
pri_detector_init(const struct radar_detector_specs *rs)
{ {
struct pri_detector *de; struct pri_detector *de;
de = kzalloc(sizeof(*de), GFP_KERNEL);
de = kzalloc(sizeof(*de), GFP_ATOMIC);
if (de == NULL) if (de == NULL)
return NULL; return NULL;
de->exit = pri_detector_exit; de->exit = pri_detector_exit;
......
...@@ -19,10 +19,32 @@ ...@@ -19,10 +19,32 @@
#include <linux/list.h> #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 * struct pri_detector - PRI detector element for a dedicated radar type
* @exit(): destructor * @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 * @reset(): clear states and reset to given time stamp
* @rs: detector specs for this detector element * @rs: detector specs for this detector element
* @last_ts: last pulse time stamp considered for this element in usecs * @last_ts: last pulse time stamp considered for this element in usecs
...@@ -34,7 +56,8 @@ ...@@ -34,7 +56,8 @@
*/ */
struct pri_detector { struct pri_detector {
void (*exit) (struct pri_detector *de); 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); void (*reset) (struct pri_detector *de, u64 ts);
/* private: internal use only */ /* private: internal use only */
......
...@@ -308,7 +308,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, ...@@ -308,7 +308,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
while(skb) { while(skb) {
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
padpos = ath9k_cmn_padpos(hdr->frame_control); padpos = ieee80211_hdrlen(hdr->frame_control);
padsize = padpos & 3; padsize = padpos & 3;
if (padsize && skb->len > padpos) { if (padsize && skb->len > padpos) {
if (skb_headroom(skb) < padsize) { if (skb_headroom(skb) < padsize) {
......
...@@ -190,7 +190,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ...@@ -190,7 +190,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
{ {
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(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; struct ath9k_hw_cal_data *caldata = NULL;
enum htc_phymode mode; enum htc_phymode mode;
__be16 htc_mode; __be16 htc_mode;
...@@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, ...@@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf; struct ieee80211_conf *conf = &common->hw->conf;
bool fastcc; bool fastcc;
struct ieee80211_channel *channel = hw->conf.channel; struct ieee80211_channel *channel = hw->conf.chandef.chan;
struct ath9k_hw_cal_data *caldata = NULL; struct ath9k_hw_cal_data *caldata = NULL;
enum htc_phymode mode; enum htc_phymode mode;
__be16 htc_mode; __be16 htc_mode;
...@@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, ...@@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
u32 caps = 0; u32 caps = 0;
int i, j; 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++) { for (i = 0, j = 0; i < sband->n_bitrates; i++) {
if (sta->supp_rates[sband->band] & BIT(i)) { if (sta->supp_rates[sband->band] & BIT(i)) {
...@@ -866,7 +866,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, ...@@ -866,7 +866,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw,
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
/* Add the padding after the header if this is not already done */ /* 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; padsize = padpos & 3;
if (padsize && skb->len > padpos) { if (padsize && skb->len > padpos) {
if (skb_headroom(skb) < padsize) { if (skb_headroom(skb) < padsize) {
...@@ -904,7 +904,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -904,7 +904,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(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; struct ath9k_channel *init_channel;
int ret = 0; int ret = 0;
enum htc_phymode mode; enum htc_phymode mode;
...@@ -1193,15 +1193,17 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1193,15 +1193,17 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
} }
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { 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; int pos = curchan->hw_value;
ath_dbg(common, CONFIG, "Set channel: %d MHz\n", ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
curchan->center_freq); curchan->center_freq);
ath9k_cmn_update_ichannel(&priv->ah->channels[pos], ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
hw->conf.channel, hw->conf.chandef.chan,
hw->conf.channel_type); channel_type);
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
ath_err(common, "Unable to set channel\n"); ath_err(common, "Unable to set channel\n");
......
...@@ -490,7 +490,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, ...@@ -490,7 +490,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
rate->flags |= IEEE80211_TX_RC_SHORT_GI; rate->flags |= IEEE80211_TX_RC_SHORT_GI;
} else { } else {
if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) if (cur_conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
rate->idx += 4; /* No CCK rates */ rate->idx += 4; /* No CCK rates */
} }
...@@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw, ...@@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw,
return; return;
} }
band = hw->conf.channel->band; band = hw->conf.chandef.chan->band;
sband = hw->wiphy->bands[band]; sband = hw->wiphy->bands[band];
for (i = 0; i < sband->n_bitrates; i++) { for (i = 0; i < sband->n_bitrates; i++) {
...@@ -966,7 +966,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ...@@ -966,7 +966,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
struct sk_buff *skb = rxbuf->skb; struct sk_buff *skb = rxbuf->skb;
struct ath_common *common = ath9k_hw_common(priv->ah); struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath_htc_rx_status *rxstatus; struct ath_htc_rx_status *rxstatus;
int hdrlen, padpos, padsize; int hdrlen, padsize;
int last_rssi = ATH_RSSI_DUMMY_MARKER; int last_rssi = ATH_RSSI_DUMMY_MARKER;
__le16 fc; __le16 fc;
...@@ -996,11 +996,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ...@@ -996,11 +996,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
fc = hdr->frame_control; fc = hdr->frame_control;
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
padpos = ath9k_cmn_padpos(fc); padsize = hdrlen & 3;
if (padsize && skb->len >= hdrlen+padsize+FCS_LEN) {
padsize = padpos & 3; memmove(skb->data + padsize, skb->data, hdrlen);
if (padsize && skb->len >= padpos+padsize+FCS_LEN) {
memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize); skb_pull(skb, padsize);
} }
...@@ -1082,8 +1080,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ...@@ -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->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
rx_status->band = hw->conf.channel->band; rx_status->band = hw->conf.chandef.chan->band;
rx_status->freq = hw->conf.channel->center_freq; rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
rx_status->antenna = rxbuf->rxstatus.rs_antenna; rx_status->antenna = rxbuf->rxstatus.rs_antenna;
rx_status->flag |= RX_FLAG_MACTIME_END; rx_status->flag |= RX_FLAG_MACTIME_END;
......
...@@ -139,7 +139,7 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah) ...@@ -139,7 +139,7 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
clockrate = 117; clockrate = 117;
else if (!ah->curchan) /* should really check for CCK instead */ else if (!ah->curchan) /* should really check for CCK instead */
clockrate = ATH9K_CLOCK_RATE_CCK; 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; clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
...@@ -1100,7 +1100,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -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 */ /* 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; ctstimeout = acktimeout;
/* /*
...@@ -1110,7 +1111,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -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 * BA frames in some implementations, but it has been found to fix ACK
* timeout issues in other cases as well. * 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)) { !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
acktimeout += 64 - sifstime - ah->slottime; acktimeout += 64 - sifstime - ah->slottime;
ctstimeout += 48 - sifstime - ah->slottime; ctstimeout += 48 - sifstime - ah->slottime;
...@@ -1697,12 +1699,11 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah, ...@@ -1697,12 +1699,11 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah,
ENABLE_REGWRITE_BUFFER(ah); ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); REG_RMW(ah, AR_STA_ID1, macStaId1
REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
| macStaId1
| AR_STA_ID1_RTS_USE_DEF | AR_STA_ID1_RTS_USE_DEF
| (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | (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); ath_hw_setbssidmask(common);
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
ath9k_hw_write_associd(ah); ath9k_hw_write_associd(ah);
......
...@@ -847,14 +847,7 @@ struct ath_hw { ...@@ -847,14 +847,7 @@ struct ath_hw {
struct ath_hw_ops ops; struct ath_hw_ops ops;
/* Used to program the radio on non single-chip devices */ /* Used to program the radio on non single-chip devices */
u32 *analogBank0Data;
u32 *analogBank1Data;
u32 *analogBank2Data;
u32 *analogBank3Data;
u32 *analogBank6Data; u32 *analogBank6Data;
u32 *analogBank6TPCData;
u32 *analogBank7Data;
u32 *bank6Temp;
int coverage_class; int coverage_class;
u32 slottime; u32 slottime;
...@@ -885,14 +878,8 @@ struct ath_hw { ...@@ -885,14 +878,8 @@ struct ath_hw {
struct ar5416IniArray iniModes; struct ar5416IniArray iniModes;
struct ar5416IniArray iniCommon; struct ar5416IniArray iniCommon;
struct ar5416IniArray iniBank0;
struct ar5416IniArray iniBB_RfGain; struct ar5416IniArray iniBB_RfGain;
struct ar5416IniArray iniBank1;
struct ar5416IniArray iniBank2;
struct ar5416IniArray iniBank3;
struct ar5416IniArray iniBank6; struct ar5416IniArray iniBank6;
struct ar5416IniArray iniBank6TPC;
struct ar5416IniArray iniBank7;
struct ar5416IniArray iniAddac; struct ar5416IniArray iniAddac;
struct ar5416IniArray iniPcieSerdes; struct ar5416IniArray iniPcieSerdes;
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
......
...@@ -577,7 +577,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ...@@ -577,7 +577,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
atomic_set(&ah->intr_ref_cnt, -1); atomic_set(&ah->intr_ref_cnt, -1);
sc->sc_ah = ah; 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) { if (!pdata) {
ah->ah_flags |= AH_USE_EEPROM; ah->ah_flags |= AH_USE_EEPROM;
...@@ -766,7 +766,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) ...@@ -766,7 +766,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SPECTRUM_MGMT | 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) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
......
...@@ -214,7 +214,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int ...@@ -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]; txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
memset(tx_info, 0, sizeof(*tx_info)); 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->flags |= IEEE80211_TX_CTL_NO_ACK;
tx_info->control.rates[0].idx = 0; tx_info->control.rates[0].idx = 0;
tx_info->control.rates[0].count = 1; tx_info->control.rates[0].count = 1;
......
...@@ -615,6 +615,14 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, ...@@ -615,6 +615,14 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_status |= ATH9K_RXERR_DECRYPT; rs->rs_status |= ATH9K_RXERR_DECRYPT;
else if (ads.ds_rxstatus8 & AR_MichaelErr) else if (ads.ds_rxstatus8 & AR_MichaelErr)
rs->rs_status |= ATH9K_RXERR_MIC; 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) if (ads.ds_rxstatus8 & AR_KeyMiss)
......
...@@ -183,6 +183,7 @@ struct ath_htc_rx_status { ...@@ -183,6 +183,7 @@ struct ath_htc_rx_status {
#define ATH9K_RXERR_DECRYPT 0x08 #define ATH9K_RXERR_DECRYPT 0x08
#define ATH9K_RXERR_MIC 0x10 #define ATH9K_RXERR_MIC 0x10
#define ATH9K_RXERR_KEYMISS 0x20 #define ATH9K_RXERR_KEYMISS 0x20
#define ATH9K_RXERR_CORRUPT_DESC 0x40
#define ATH9K_RX_MORE 0x01 #define ATH9K_RX_MORE 0x01
#define ATH9K_RX_MORE_AGGR 0x02 #define ATH9K_RX_MORE_AGGR 0x02
......
...@@ -589,7 +589,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -589,7 +589,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(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; struct ath9k_channel *init_channel;
int r; int r;
...@@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) ...@@ -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; struct ath9k_vif_iter_data *iter_data = data;
int i; int i;
if (iter_data->hw_macaddr) if (iter_data->has_hw_macaddr) {
for (i = 0; i < ETH_ALEN; i++) for (i = 0; i < ETH_ALEN; i++)
iter_data->mask[i] &= iter_data->mask[i] &=
~(iter_data->hw_macaddr[i] ^ mac[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) { switch (vif->type) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
...@@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, ...@@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
* together with the BSSID mask when matching addresses. * together with the BSSID mask when matching addresses.
*/ */
memset(iter_data, 0, sizeof(*iter_data)); memset(iter_data, 0, sizeof(*iter_data));
iter_data->hw_macaddr = common->macaddr;
memset(&iter_data->mask, 0xff, ETH_ALEN); memset(&iter_data->mask, 0xff, ETH_ALEN);
if (vif) if (vif)
...@@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, ...@@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
ieee80211_iterate_active_interfaces_atomic( ieee80211_iterate_active_interfaces_atomic(
sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
ath9k_vif_iter, iter_data); ath9k_vif_iter, iter_data);
memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
} }
/* Called with sc->mutex held. */ /* Called with sc->mutex held. */
...@@ -1188,7 +1193,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1188,7 +1193,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
} }
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { 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 pos = curchan->hw_value;
int old_pos = -1; int old_pos = -1;
unsigned long flags; unsigned long flags;
...@@ -1197,7 +1204,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1197,7 +1204,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
old_pos = ah->curchan - &ah->channels[0]; old_pos = ah->curchan - &ah->channels[0];
ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", 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 */ /* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags); spin_lock_irqsave(&common->cc_lock, flags);
...@@ -1212,7 +1219,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1212,7 +1219,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
ath9k_hw_getnf(ah, ah->curchan); ath9k_hw_getnf(ah, ah->curchan);
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], 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 * If the operating channel changes, change the survey in-use flags
......
...@@ -814,7 +814,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -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 * So, set fourth rate in series to be same as third one for
* above conditions. * 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))) { (conf_is_ht(&sc->hw->conf))) {
u8 dot11rate = rate_table->info[rix].dot11rate; u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy; u8 phy = rate_table->info[rix].phy;
...@@ -1328,7 +1328,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, ...@@ -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, ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
"Operating HT Bandwidth changed to: %d\n", "Operating HT Bandwidth changed to: %d\n",
sc->hw->conf.channel_type); cfg80211_get_chandef_type(&sc->hw->conf.chandef));
} }
} }
......
...@@ -124,13 +124,13 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc, ...@@ -124,13 +124,13 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
SKB_CB_ATHBUF(skb) = bf; SKB_CB_ATHBUF(skb) = bf;
ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype); 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; return true;
} }
static void ath_rx_addbuffer_edma(struct ath_softc *sc, 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_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_buf *bf, *tbf; struct ath_buf *bf, *tbf;
...@@ -155,7 +155,7 @@ static void ath_rx_remove_buffer(struct ath_softc *sc, ...@@ -155,7 +155,7 @@ static void ath_rx_remove_buffer(struct ath_softc *sc,
rx_edma = &sc->rx.rx_edma[qtype]; 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); bf = SKB_CB_ATHBUF(skb);
BUG_ON(!bf); BUG_ON(!bf);
list_add_tail(&bf->list, &sc->rx.rxbuf); list_add_tail(&bf->list, &sc->rx.rxbuf);
...@@ -250,15 +250,9 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) ...@@ -250,15 +250,9 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
static void ath_edma_start_recv(struct ath_softc *sc) static void ath_edma_start_recv(struct ath_softc *sc)
{ {
ath9k_hw_rxena(sc->sc_ah); ath9k_hw_rxena(sc->sc_ah);
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP);
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP);
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_opmode_init(sc); ath_opmode_init(sc);
ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 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) ...@@ -280,49 +274,47 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
sc->sc_ah->caps.rx_status_len; 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); 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, /* Initialize rx descriptors */
"rx", nbufs, 1, 0);
if (error != 0) { error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
ath_err(common, "rx", nbufs, 1, 0);
"failed to allocate rx descriptors: %d\n", if (error != 0) {
error); 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; goto err;
} }
list_for_each_entry(bf, &sc->rx.rxbuf, list) { bf->bf_mpdu = skb;
skb = ath_rxbuf_alloc(common, common->rx_bufsize, bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
GFP_KERNEL); common->rx_bufsize,
if (skb == NULL) { DMA_FROM_DEVICE);
error = -ENOMEM; if (unlikely(dma_mapping_error(sc->dev,
goto err; bf->bf_buf_addr))) {
} dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_mpdu = skb; bf->bf_buf_addr = 0;
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, ath_err(common,
common->rx_bufsize, "dma_mapping_error() on RX init\n");
DMA_FROM_DEVICE); error = -ENOMEM;
if (unlikely(dma_mapping_error(sc->dev, goto err;
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: err:
if (error) if (error)
ath_rx_cleanup(sc); ath_rx_cleanup(sc);
...@@ -340,17 +332,17 @@ void ath_rx_cleanup(struct ath_softc *sc) ...@@ -340,17 +332,17 @@ void ath_rx_cleanup(struct ath_softc *sc)
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
ath_rx_edma_cleanup(sc); ath_rx_edma_cleanup(sc);
return; return;
} else { }
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = bf->bf_mpdu; list_for_each_entry(bf, &sc->rx.rxbuf, list) {
if (skb) { skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_buf_addr, if (skb) {
common->rx_bufsize, dma_unmap_single(sc->dev, bf->bf_buf_addr,
DMA_FROM_DEVICE); common->rx_bufsize,
dev_kfree_skb(skb); DMA_FROM_DEVICE);
bf->bf_buf_addr = 0; dev_kfree_skb(skb);
bf->bf_mpdu = NULL; 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, ...@@ -727,6 +719,13 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
ret = ath9k_hw_rxprocdesc(ah, tds, &trs); ret = ath9k_hw_rxprocdesc(ah, tds, &trs);
if (ret == -EINPROGRESS) if (ret == -EINPROGRESS)
return NULL; 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); list_del(&bf->list);
...@@ -863,7 +862,7 @@ static int ath9k_process_rate(struct ath_common *common, ...@@ -863,7 +862,7 @@ static int ath9k_process_rate(struct ath_common *common,
unsigned int i = 0; unsigned int i = 0;
struct ath_softc __maybe_unused *sc = common->priv; struct ath_softc __maybe_unused *sc = common->priv;
band = hw->conf.channel->band; band = hw->conf.chandef.chan->band;
sband = hw->wiphy->bands[band]; sband = hw->wiphy->bands[band];
if (rx_stats->rs_rate & 0x80) { if (rx_stats->rs_rate & 0x80) {
...@@ -933,14 +932,20 @@ static void ath9k_process_rssi(struct ath_common *common, ...@@ -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 * 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. * decryption key or real decryption error. This let us keep statistics there.
*/ */
static int ath9k_rx_skb_preprocess(struct ath_common *common, static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
struct ath_rx_status *rx_stats, struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rx_status, struct ieee80211_rx_status *rx_status,
bool *decrypt_error) 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 * everything but the rate is checked here, the rate check is done
...@@ -958,14 +963,15 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, ...@@ -958,14 +963,15 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
if (ath9k_process_rate(common, hw, rx_stats, rx_status)) if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL; return -EINVAL;
rx_status->band = hw->conf.channel->band; rx_status->band = hw->conf.chandef.chan->band;
rx_status->freq = hw->conf.channel->center_freq; rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->signal = ah->noise + rx_stats->rs_rssi; rx_status->signal = ah->noise + rx_stats->rs_rssi;
rx_status->antenna = rx_stats->rs_antenna; rx_status->antenna = rx_stats->rs_antenna;
rx_status->flag |= RX_FLAG_MACTIME_END; rx_status->flag |= RX_FLAG_MACTIME_END;
if (rx_stats->rs_moreaggr) if (rx_stats->rs_moreaggr)
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
sc->rx.discard_next = false;
return 0; return 0;
} }
...@@ -985,7 +991,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, ...@@ -985,7 +991,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
fc = hdr->frame_control; 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 /* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for * packet payload is non-zero. The general calculation for
...@@ -1166,6 +1172,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ...@@ -1166,6 +1172,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
u64 tsf = 0; u64 tsf = 0;
u32 tsf_lower = 0; u32 tsf_lower = 0;
unsigned long flags; unsigned long flags;
dma_addr_t new_buf_addr;
if (edma) if (edma)
dma_type = DMA_BIDIRECTIONAL; dma_type = DMA_BIDIRECTIONAL;
...@@ -1242,8 +1249,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ...@@ -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, retval = ath9k_rx_skb_preprocess(sc, hdr, &rs, rxs,
rxs, &decrypt_error); &decrypt_error);
if (retval) if (retval)
goto requeue_drop_frag; goto requeue_drop_frag;
...@@ -1264,10 +1271,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ...@@ -1264,10 +1271,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
goto requeue_drop_frag; 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 */ /* Unmap the frame */
dma_unmap_single(sc->dev, bf->bf_buf_addr, dma_unmap_single(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, common->rx_bufsize, dma_type);
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); skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
if (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) ...@@ -1277,21 +1294,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
ath9k_rx_skb_postprocess(common, hdr_skb, &rs, ath9k_rx_skb_postprocess(common, hdr_skb, &rs,
rxs, decrypt_error); 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) { if (rs.rs_more) {
RX_STAT_INC(rx_frags); RX_STAT_INC(rx_frags);
/* /*
...@@ -1309,6 +1311,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ...@@ -1309,6 +1311,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
sc->rx.frag = skb; sc->rx.frag = skb;
goto requeue; goto requeue;
} }
if (rs.rs_status & ATH9K_RXERR_CORRUPT_DESC)
goto requeue_drop_frag;
if (sc->rx.frag) { if (sc->rx.frag) {
int space = skb->len - skb_tailroom(hdr_skb); int space = skb->len - skb_tailroom(hdr_skb);
......
...@@ -1493,9 +1493,6 @@ enum { ...@@ -1493,9 +1493,6 @@ enum {
#define AR9271_RADIO_RF_RST 0x20 #define AR9271_RADIO_RF_RST 0x20
#define AR9271_GATE_MAC_CTL 0x4000 #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_STA_AP 0x00010000
#define AR_STA_ID1_ADHOC 0x00020000 #define AR_STA_ID1_ADHOC 0x00020000
#define AR_STA_ID1_PWR_SAV 0x00040000 #define AR_STA_ID1_PWR_SAV 0x00040000
......
...@@ -157,6 +157,13 @@ static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) ...@@ -157,6 +157,13 @@ static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
seqno << IEEE80211_SEQ_SEQ_SHIFT); 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) static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{ {
struct ath_txq *txq = tid->ac->txq; struct ath_txq *txq = tid->ac->txq;
...@@ -189,6 +196,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ...@@ -189,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); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
sendbar = true; sendbar = true;
} else { } else {
ath_set_rates(tid->an->vif, tid->an->sta, bf);
ath_tx_send_normal(sc, txq, NULL, skb); 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, ...@@ -407,7 +415,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
tx_info = IEEE80211_SKB_CB(skb); 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; retries = ts->ts_longretry + 1;
for (i = 0; i < ts->ts_rateindex; i++) for (i = 0; i < ts->ts_rateindex; i++)
...@@ -516,8 +524,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ...@@ -516,8 +524,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
* not a holding desc. * not a holding desc.
*/ */
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || if (bf_next != NULL || !bf_last->bf_stale)
bf_next != NULL || !bf_last->bf_stale)
list_move_tail(&bf->list, &bf_head); list_move_tail(&bf->list, &bf_head);
if (!txpending || (tid->state & AGGR_CLEANUP)) { if (!txpending || (tid->state & AGGR_CLEANUP)) {
...@@ -537,8 +544,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ...@@ -537,8 +544,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!txfail); !txfail);
} else { } else {
/* retry the un-acked ones */ /* retry the un-acked ones */
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && if (bf->bf_next == NULL && bf_last->bf_stale) {
bf->bf_next == NULL && bf_last->bf_stale) {
struct ath_buf *tbf; struct ath_buf *tbf;
tbf = ath_clone_txbuf(sc, bf_last); tbf = ath_clone_txbuf(sc, bf_last);
...@@ -738,8 +744,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -738,8 +744,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
bool first_subfrm) bool first_subfrm)
{ {
#define FIRST_DESC_NDELIMS 60 #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; u32 nsymbits, nsymbols;
u16 minlen; u16 minlen;
u8 flags, rix; u8 flags, rix;
...@@ -780,8 +784,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -780,8 +784,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
if (tid->an->mpdudensity == 0) if (tid->an->mpdudensity == 0)
return ndelim; return ndelim;
rix = tx_info->control.rates[0].idx; rix = bf->rates[0].idx;
flags = tx_info->control.rates[0].flags; flags = bf->rates[0].flags;
width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 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, ...@@ -860,6 +864,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
bf_first = bf; bf_first = bf;
if (!rl) { if (!rl) {
ath_set_rates(tid->an->vif, tid->an->sta, bf);
aggr_limit = ath_lookup_rate(sc, bf, tid); aggr_limit = ath_lookup_rate(sc, bf, tid);
rl = 1; rl = 1;
} }
...@@ -1000,14 +1005,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1000,14 +1005,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
skb = bf->bf_mpdu; skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb); tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates; rates = bf->rates;
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
/* set dur_update_en for l-sig computation except for PS-Poll frames */ /* set dur_update_en for l-sig computation except for PS-Poll frames */
info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
info->rtscts_rate = fi->rtscts_rate; 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; bool is_40, is_sgi, is_sp;
int phy; int phy;
...@@ -1745,6 +1750,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ...@@ -1745,6 +1750,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return; return;
} }
ath_set_rates(tid->an->vif, tid->an->sta, bf);
bf->bf_state.bf_type = BUF_AMPDU; bf->bf_state.bf_type = BUF_AMPDU;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
list_add(&bf->list, &bf_head); list_add(&bf->list, &bf_head);
...@@ -1894,49 +1900,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ...@@ -1894,49 +1900,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
return bf; 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 */ /* Upon failure caller should free skb */
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl) struct ath_tx_control *txctl)
...@@ -1947,8 +1910,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -1947,8 +1910,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_vif *vif = info->control.vif; struct ieee80211_vif *vif = info->control.vif;
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_txq *txq = txctl->txq; struct ath_txq *txq = txctl->txq;
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf;
int padpos, padsize; int padpos, padsize;
int frmlen = skb->len + FCS_LEN; int frmlen = skb->len + FCS_LEN;
u8 tidno;
int q; int q;
/* NOTE: sta can be NULL according to net/mac80211.h */ /* NOTE: sta can be NULL according to net/mac80211.h */
...@@ -1971,7 +1937,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -1971,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 */ /* 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; padsize = padpos & 3;
if (padsize && skb->len > padpos) { if (padsize && skb->len > padpos) {
if (skb_headroom(skb) < padsize) if (skb_headroom(skb) < padsize)
...@@ -2004,8 +1970,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -2004,8 +1970,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
txq->stopped = true; 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); ath_txq_unlock(sc, txq);
return 0; return 0;
...@@ -2033,7 +2032,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -2033,7 +2032,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
/* Frame was ACKed */ /* Frame was ACKed */
tx_info->flags |= IEEE80211_TX_STAT_ACK; tx_info->flags |= IEEE80211_TX_STAT_ACK;
padpos = ath9k_cmn_padpos(hdr->frame_control); padpos = ieee80211_hdrlen(hdr->frame_control);
padsize = padpos & 3; padsize = padpos & 3;
if (padsize && skb->len>padpos+padsize) { if (padsize && skb->len>padpos+padsize) {
/* /*
...@@ -2264,6 +2263,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ...@@ -2264,6 +2263,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
struct ath_txq *txq; struct ath_txq *txq;
struct ath_buf *bf, *lastbf; struct ath_buf *bf, *lastbf;
struct list_head bf_head; struct list_head bf_head;
struct list_head *fifo_list;
int status; int status;
for (;;) { for (;;) {
...@@ -2291,20 +2291,24 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ...@@ -2291,20 +2291,24 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
TX_STAT_INC(txq->axq_qnum, txprocdesc); 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); ath_txq_unlock(sc, txq);
return; return;
} }
bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], bf = list_first_entry(fifo_list, struct ath_buf, 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; lastbf = bf->bf_lastbf;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], if (list_is_last(&lastbf->list, fifo_list)) {
&lastbf->list); list_splice_tail_init(fifo_list, &bf_head);
if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
if (!list_empty(&txq->axq_q)) { if (!list_empty(&txq->axq_q)) {
...@@ -2315,6 +2319,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ...@@ -2315,6 +2319,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
list_splice_tail_init(&txq->axq_q, &bf_q); list_splice_tail_init(&txq->axq_q, &bf_q);
ath_tx_txqaddbuf(sc, txq, &bf_q, true); 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); ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
......
...@@ -654,8 +654,8 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf, ...@@ -654,8 +654,8 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
goto out; goto out;
case 'P': case 'P':
err = carl9170_set_channel(ar, ar->hw->conf.channel, err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
ar->hw->conf.channel_type); cfg80211_get_chandef_type(&ar->hw->conf.chandef));
if (err < 0) if (err < 0)
count = err; count = err;
......
...@@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) ...@@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
if (conf_is_ht40(&ar->hw->conf)) if (conf_is_ht40(&ar->hw->conf))
val = 0x010a; val = 0x010a;
else { else {
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
val = 0x105; val = 0x105;
else else
val = 0x104; val = 0x104;
...@@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar) ...@@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar)
rts_rate = 0x1da; rts_rate = 0x1da;
cts_rate = 0x10a; cts_rate = 0x10a;
} else { } else {
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) {
/* 11 mbit CCK */ /* 11 mbit CCK */
rts_rate = 033; rts_rate = 033;
cts_rate = 003; cts_rate = 003;
...@@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar) ...@@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar)
return 0; 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) vif->bss_conf.use_short_slot)
slottime = 9; slottime = 9;
...@@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar) ...@@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar)
basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
rcu_read_unlock(); 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 */ mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
else else
mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
......
...@@ -929,6 +929,9 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -929,6 +929,9 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
} }
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 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 */ /* adjust slot time for 5 GHz */
err = carl9170_set_slot_time(ar); err = carl9170_set_slot_time(ar);
if (err) if (err)
...@@ -938,8 +941,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -938,8 +941,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
if (err) if (err)
goto out; goto out;
err = carl9170_set_channel(ar, hw->conf.channel, err = carl9170_set_channel(ar, hw->conf.chandef.chan,
hw->conf.channel_type); channel_type);
if (err) if (err)
goto out; goto out;
...@@ -957,7 +960,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -957,7 +960,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
} }
if (changed & IEEE80211_CONF_CHANGE_POWER) { 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) if (err)
goto out; goto out;
} }
......
...@@ -1331,7 +1331,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) ...@@ -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_ETSI for 2GHz and CTL_FCC for 5GHz.
*/ */
ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, 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 */ /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
...@@ -1341,7 +1341,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) ...@@ -1341,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 */ /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
return; return;
if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) {
modes = mode_list_2ghz; modes = mode_list_2ghz;
nr_modes = ARRAY_SIZE(mode_list_2ghz); nr_modes = ARRAY_SIZE(mode_list_2ghz);
} else { } else {
......
...@@ -118,6 +118,12 @@ ...@@ -118,6 +118,12 @@
void ath_hw_setbssidmask(struct ath_common *common) void ath_hw_setbssidmask(struct ath_common *common)
{ {
void *ah = common->ah; 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_BSSMSKL, get_unaligned_le32(common->bssidmask));
REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4));
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
#define AR_MIBC_CMC 0x00000004 #define AR_MIBC_CMC 0x00000004
#define AR_MIBC_MCS 0x00000008 #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() * BSSID mask registers. See ath_hw_set_bssid_mask()
* for detailed documentation about these registers. * for detailed documentation about these registers.
......
...@@ -191,8 +191,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, ...@@ -191,8 +191,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
* - Phy info * - Phy info
*/ */
static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
struct sk_buff *skb, struct sk_buff *skb)
volatile struct vring_rx_desc *d)
{ {
struct wireless_dev *wdev = wil->wdev; struct wireless_dev *wdev = wil->wdev;
struct wil6210_rtap { struct wil6210_rtap {
...@@ -216,6 +215,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, ...@@ -216,6 +215,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
__le16 vendor_skip; __le16 vendor_skip;
u8 vendor_data[0]; u8 vendor_data[0];
} __packed; } __packed;
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
struct wil6210_rtap_vendor *rtap_vendor; struct wil6210_rtap_vendor *rtap_vendor;
int rtap_len = sizeof(struct wil6210_rtap); int rtap_len = sizeof(struct wil6210_rtap);
int phy_length = 0; /* phy info header size, bytes */ int phy_length = 0; /* phy info header size, bytes */
...@@ -312,6 +312,8 @@ static void wil_swap_ethaddr(void *data) ...@@ -312,6 +312,8 @@ static void wil_swap_ethaddr(void *data)
/** /**
* reap 1 frame from @swhead * reap 1 frame from @swhead
* *
* Rx descriptor copied to skb->cb
*
* Safe to call from IRQ * Safe to call from IRQ
*/ */
static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
...@@ -320,12 +322,15 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -320,12 +322,15 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
struct device *dev = wil_to_dev(wil); struct device *dev = wil_to_dev(wil);
struct net_device *ndev = wil_to_ndev(wil); struct net_device *ndev = wil_to_ndev(wil);
volatile struct vring_rx_desc *d; volatile struct vring_rx_desc *d;
struct vring_rx_desc *d1;
struct sk_buff *skb; struct sk_buff *skb;
dma_addr_t pa; dma_addr_t pa;
unsigned int sz = RX_BUF_LEN; unsigned int sz = RX_BUF_LEN;
u8 ftype; u8 ftype;
u8 ds_bits; u8 ds_bits;
BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
if (wil_vring_is_empty(vring)) if (wil_vring_is_empty(vring))
return NULL; return NULL;
...@@ -340,11 +345,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -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); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
skb_trim(skb, d->dma.length); 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 */ /* use radiotap header only if required */
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 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_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
...@@ -360,7 +368,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -360,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 * 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 * 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) { if (ftype != IEEE80211_FTYPE_DATA) {
wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
/* TODO: process it */ /* TODO: process it */
...@@ -375,7 +383,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -375,7 +383,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
return NULL; return NULL;
} }
ds_bits = wil_rxdesc_ds_bits(d); ds_bits = wil_rxdesc_ds_bits(d1);
if (ds_bits == 1) { if (ds_bits == 1) {
/* /*
* HW bug - in ToDS mode, i.e. Rx on AP side, * HW bug - in ToDS mode, i.e. Rx on AP side,
...@@ -517,6 +525,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, ...@@ -517,6 +525,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
.vring_cfg = { .vring_cfg = {
.tx_sw_ring = { .tx_sw_ring = {
.max_mpdu_size = cpu_to_le16(TX_BUF_LEN), .max_mpdu_size = cpu_to_le16(TX_BUF_LEN),
.ring_size = cpu_to_le16(size),
}, },
.ringid = id, .ringid = id,
.cidxtid = (cid & 0xf) | ((tid & 0xf) << 4), .cidxtid = (cid & 0xf) | ((tid & 0xf) << 4),
...@@ -548,7 +557,6 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, ...@@ -548,7 +557,6 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
goto out; goto out;
cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); 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), rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd),
WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
...@@ -779,9 +787,14 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid) ...@@ -779,9 +787,14 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
while (!wil_vring_is_empty(vring)) { 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 = &dd;
dma_addr_t pa; dma_addr_t pa;
struct sk_buff *skb; struct sk_buff *skb;
dd = *d1;
if (!(d->dma.status & TX_DMA_STATUS_DU)) if (!(d->dma.status & TX_DMA_STATUS_DU))
break; break;
......
...@@ -339,24 +339,59 @@ union vring_desc { ...@@ -339,24 +339,59 @@ union vring_desc {
struct vring_rx_desc rx; struct vring_rx_desc rx;
} __packed; } __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); 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 */ #endif /* WIL6210_TXRX_H */
...@@ -980,7 +980,7 @@ static inline int b43_is_mode(struct b43_wl *wl, int type) ...@@ -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) 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) static inline int b43_bus_may_powerdown(struct b43_wldev *wldev)
......
...@@ -3852,7 +3852,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -3852,7 +3852,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
dev = wl->current_dev; dev = wl->current_dev;
/* Switch the band (if necessary). This might change the active core. */ /* 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) if (err)
goto out_unlock_mutex; goto out_unlock_mutex;
...@@ -3882,8 +3882,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -3882,8 +3882,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
/* Switch to the requested channel. /* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */ * The firmware takes care of races with the TX handler. */
if (conf->channel->hw_value != phy->channel) if (conf->chandef.chan->hw_value != phy->channel)
b43_switch_channel(dev, conf->channel->hw_value); b43_switch_channel(dev, conf->chandef.chan->hw_value);
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); 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, ...@@ -5006,7 +5006,7 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0) if (idx != 0)
return -ENOENT; return -ENOENT;
survey->channel = conf->channel; survey->channel = conf->chandef.chan;
survey->filled = SURVEY_INFO_NOISE_DBM; survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = dev->stats.link_noise; survey->noise = dev->stats.link_noise;
......
...@@ -30,6 +30,17 @@ ...@@ -30,6 +30,17 @@
#include "radio_2059.h" #include "radio_2059.h"
#include "main.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. * Radio 2059.
**************************************************/ **************************************************/
...@@ -37,8 +48,9 @@ ...@@ -37,8 +48,9 @@
static void b43_radio_2059_channel_setup(struct b43_wldev *dev, static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
const struct b43_phy_ht_channeltab_e_radio2059 *e) const struct b43_phy_ht_channeltab_e_radio2059 *e)
{ {
u8 i; static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3, };
u16 routing; u16 r;
int core;
b43_radio_write(dev, 0x16, e->radio_syn16); b43_radio_write(dev, 0x16, e->radio_syn16);
b43_radio_write(dev, 0x17, e->radio_syn17); b43_radio_write(dev, 0x17, e->radio_syn17);
...@@ -53,25 +65,17 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, ...@@ -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, 0x41, e->radio_syn41);
b43_radio_write(dev, 0x43, e->radio_syn43); b43_radio_write(dev, 0x43, e->radio_syn43);
b43_radio_write(dev, 0x47, e->radio_syn47); b43_radio_write(dev, 0x47, e->radio_syn47);
b43_radio_write(dev, 0x4a, e->radio_syn4a);
b43_radio_write(dev, 0x58, e->radio_syn58); for (core = 0; core < 3; core++) {
b43_radio_write(dev, 0x5a, e->radio_syn5a); r = routing[core];
b43_radio_write(dev, 0x6a, e->radio_syn6a); b43_radio_write(dev, r | 0x4a, e->radio_rxtx4a);
b43_radio_write(dev, 0x6d, e->radio_syn6d); b43_radio_write(dev, r | 0x58, e->radio_rxtx58);
b43_radio_write(dev, 0x6e, e->radio_syn6e); b43_radio_write(dev, r | 0x5a, e->radio_rxtx5a);
b43_radio_write(dev, 0x92, e->radio_syn92); b43_radio_write(dev, r | 0x6a, e->radio_rxtx6a);
b43_radio_write(dev, 0x98, e->radio_syn98); b43_radio_write(dev, r | 0x6d, e->radio_rxtx6d);
b43_radio_write(dev, r | 0x6e, e->radio_rxtx6e);
for (i = 0; i < 2; i++) { b43_radio_write(dev, r | 0x92, e->radio_rxtx92);
routing = i ? R2059_RXRX1 : R2059_TXRX0; b43_radio_write(dev, r | 0x98, e->radio_rxtx98);
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);
} }
udelay(50); udelay(50);
...@@ -87,7 +91,7 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, ...@@ -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) 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] = { const u16 radio_values[3][2] = {
{ 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 },
}; };
...@@ -106,17 +110,17 @@ static void b43_radio_2059_init(struct b43_wldev *dev) ...@@ -106,17 +110,17 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
b43_radio_mask(dev, 0xc0, ~0x0080); b43_radio_mask(dev, 0xc0, ~0x0080);
if (1) { /* FIXME */ if (1) { /* FIXME */
b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); b43_radio_set(dev, R2059_C3 | 0x4, 0x1);
udelay(10); udelay(10);
b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1);
b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); 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); udelay(100);
b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); b43_radio_mask(dev, R2059_C3 | 0x4, ~0x2);
for (i = 0; i < 10000; i++) { 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; i = 0;
break; break;
} }
...@@ -125,7 +129,7 @@ static void b43_radio_2059_init(struct b43_wldev *dev) ...@@ -125,7 +129,7 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
if (i) if (i)
b43err(dev->wl, "radio 0x945 timeout\n"); 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); b43_radio_set(dev, 0xa, 0x60);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
...@@ -390,14 +394,14 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev) ...@@ -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, 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] = { static const u16 ctl_regs[3][2] = {
{ B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, }, { 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_C2, B43_PHY_HT_AFE_C2_OVER, },
{ B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_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; int core;
if (core_sel == 0) { if (core_sel == 0) {
...@@ -411,13 +415,13 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, ...@@ -411,13 +415,13 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
continue; continue;
switch (rssi_type) { 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 << 8);
b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10); 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 << 9);
b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10); 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, b43_radio_write(dev, radio_r[core] | 0x159,
0x11); 0x11);
break; break;
...@@ -429,8 +433,8 @@ static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel, ...@@ -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, static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, enum ht_rssi_type type,
u8 nsamp) s32 *buf, u8 nsamp)
{ {
u16 phy_regs_values[12]; u16 phy_regs_values[12];
static const u16 phy_regs_to_save[] = { static const u16 phy_regs_to_save[] = {
...@@ -504,15 +508,17 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) ...@@ -504,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, static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1,
B43_PHY_HT_TXPCTL_CMD_C2, B43_PHY_HT_TXPCTL_CMD_C2,
B43_PHY_HT_TXPCTL_CMD_C3 }; 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; int i;
if (!enable) { if (!enable) {
if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) {
/* We disable enabled TX pwr ctl, save it's state */ /* We disable enabled TX pwr ctl, save it's state */
/* for (i = 0; i < 3; i++)
* TODO: find the registers. On N-PHY they were 0x1ed phy_ht->tx_pwr_idx[i] =
* and 0x1ee, we need 3 such a registers for HT-PHY b43_phy_read(dev, status_regs[i]);
*/
} }
b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits);
} else { } else {
...@@ -536,13 +542,25 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) ...@@ -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) static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
{ {
struct b43_phy_ht *phy_ht = dev->phy.ht; 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]; 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); b43_phy_ht_tx_tone(dev);
udelay(20); 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_stop_playback(dev);
b43_phy_ht_reset_cca(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) ...@@ -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[1] = rssi_buf[2] & 0xff;
phy_ht->idle_tssi[2] = rssi_buf[4] & 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) static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
...@@ -946,6 +980,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev) ...@@ -946,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(dev, false);
b43_phy_ht_tx_power_ctl_idle_tssi(dev); b43_phy_ht_tx_power_ctl_idle_tssi(dev);
b43_phy_ht_tx_power_ctl_setup(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); b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
return 0; return 0;
...@@ -1011,8 +1046,9 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) ...@@ -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, static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel) unsigned int new_channel)
{ {
struct ieee80211_channel *channel = dev->wl->hw->conf.channel; struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; 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 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14)) if ((new_channel < 1) || (new_channel > 14))
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ #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_DEP_CNT 0x0C6 /* Sample depth count */
#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ #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 0x122 /* TSSI mode */
#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */ #define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */
#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */ #define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */
...@@ -53,6 +56,8 @@ ...@@ -53,6 +56,8 @@
#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0 #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 0xFF00 /* Power 1 */
#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8 #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 0x222
#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F #define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
#define B43_PHY_HT_RSSI_C1 0x219 #define B43_PHY_HT_RSSI_C1 0x219
...@@ -97,6 +102,7 @@ ...@@ -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 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 0x00FF
#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 #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) #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
......
...@@ -808,8 +808,9 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on) ...@@ -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, static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel) unsigned int new_channel)
{ {
struct ieee80211_channel *channel = dev->wl->hw->conf.channel; struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; 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 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14)) if ((new_channel < 1) || (new_channel > 14))
......
...@@ -281,8 +281,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) ...@@ -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, 0xFFC0, 0x000A);
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
(dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && (dev->dev->board_type == SSB_BOARD_BU4312) ||
(sprom->boardflags_lo & B43_BFL_FEM))) { (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, 0xFFC0, 0x0001);
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001);
......
此差异已折叠。
...@@ -54,10 +54,15 @@ ...@@ -54,10 +54,15 @@
#define B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT 7 #define B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT 7
#define B43_NPHY_C1_INITGAIN_TRRX 0x1000 /* TR RX index */ #define B43_NPHY_C1_INITGAIN_TRRX 0x1000 /* TR RX index */
#define B43_NPHY_C1_INITGAIN_TRTX 0x2000 /* TR TX 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_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_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_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_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_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_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 */ #define B43_NPHY_C1_CLIPWBTHRES B43_PHY_N(0x027) /* Core 1 clip wideband threshold */
...@@ -107,10 +112,15 @@ ...@@ -107,10 +112,15 @@
#define B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT 7 #define B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT 7
#define B43_NPHY_C2_INITGAIN_TRRX 0x1000 /* TR RX index */ #define B43_NPHY_C2_INITGAIN_TRRX 0x1000 /* TR RX index */
#define B43_NPHY_C2_INITGAIN_TRTX 0x2000 /* TR TX 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_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_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_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_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_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_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 */ #define B43_NPHY_C2_CLIPWBTHRES B43_PHY_N(0x03D) /* Core 2 clip wideband threshold */
...@@ -706,10 +716,146 @@ ...@@ -706,10 +716,146 @@
#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power control init */ #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 0x00FF /* Power index init 1 */
#define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 #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_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_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_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_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_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
r20, r21, r22, r23, r24, r25, r26, r27, r28) \ r20) \
.radio_syn16 = r00, \ .radio_syn16 = r00, \
.radio_syn17 = r01, \ .radio_syn17 = r01, \
.radio_syn22 = r02, \ .radio_syn22 = r02, \
...@@ -41,22 +41,14 @@ ...@@ -41,22 +41,14 @@
.radio_syn41 = r10, \ .radio_syn41 = r10, \
.radio_syn43 = r11, \ .radio_syn43 = r11, \
.radio_syn47 = r12, \ .radio_syn47 = r12, \
.radio_syn4a = r13, \ .radio_rxtx4a = r13, \
.radio_syn58 = r14, \ .radio_rxtx58 = r14, \
.radio_syn5a = r15, \ .radio_rxtx5a = r15, \
.radio_syn6a = r16, \ .radio_rxtx6a = r16, \
.radio_syn6d = r17, \ .radio_rxtx6d = r17, \
.radio_syn6e = r18, \ .radio_rxtx6e = r18, \
.radio_syn92 = r19, \ .radio_rxtx92 = r19, \
.radio_syn98 = r20, \ .radio_rxtx98 = 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
#define PHYREGS(r0, r1, r2, r3, r4, r5) \ #define PHYREGS(r0, r1, r2, r3, r4, r5) \
.phy_regs.bw1 = r0, \ .phy_regs.bw1 = r0, \
...@@ -70,91 +62,78 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi ...@@ -70,91 +62,78 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi
{ .freq = 2412, { .freq = 2412,
RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
}, },
{ .freq = 2417, { .freq = 2417,
RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
}, },
{ .freq = 2422, { .freq = 2422,
RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
}, },
{ .freq = 2427, { .freq = 2427,
RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
}, },
{ .freq = 2432, { .freq = 2432,
RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
}, },
{ .freq = 2437, { .freq = 2437,
RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
}, },
{ .freq = 2442, { .freq = 2442,
RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
}, },
{ .freq = 2447, { .freq = 2447,
RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
}, },
{ .freq = 2452, { .freq = 2452,
RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
}, },
{ .freq = 2457, { .freq = 2457,
RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
}, },
{ .freq = 2462, { .freq = 2462,
RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
}, },
{ .freq = 2467, { .freq = 2467,
RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b), PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
}, },
{ .freq = 2472, { .freq = 2472,
RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
0x00, 0x00, 0x00, 0xf0, 0x00), 0x00, 0x00, 0x00, 0xf0, 0x00),
PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
}, },
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#include "phy_ht.h" #include "phy_ht.h"
#define R2059_SYN 0x000 #define R2059_C1 0x000
#define R2059_TXRX0 0x400 #define R2059_C2 0x400
#define R2059_RXRX1 0x800 #define R2059_C3 0x800
#define R2059_ALL 0xC00 #define R2059_ALL 0xC00
/* Values for various registers uploaded on channel switching */ /* Values for various registers uploaded on channel switching */
...@@ -28,14 +28,6 @@ struct b43_phy_ht_channeltab_e_radio2059 { ...@@ -28,14 +28,6 @@ struct b43_phy_ht_channeltab_e_radio2059 {
u8 radio_syn41; u8 radio_syn41;
u8 radio_syn43; u8 radio_syn43;
u8 radio_syn47; 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_rxtx4a;
u8 radio_rxtx58; u8 radio_rxtx58;
u8 radio_rxtx5a; u8 radio_rxtx5a;
......
...@@ -2174,7 +2174,7 @@ static const u16 b43_ntab_loftlt1_r3[] = { ...@@ -2174,7 +2174,7 @@ static const u16 b43_ntab_loftlt1_r3[] = {
/* volatile tables, PHY revision >= 3 */ /* volatile tables, PHY revision >= 3 */
/* indexed by antswctl2g */ /* 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, 0x0082, 0x0082, 0x0211, 0x0222, 0x0328,
0x0000, 0x0000, 0x0000, 0x0144, 0x0000, 0x0000, 0x0000, 0x0000, 0x0144, 0x0000,
...@@ -3095,9 +3095,55 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, ...@@ -3095,9 +3095,55 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
} }
#define ntab_upload(dev, offset, data) do { \ #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) } 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 */ /* Static tables */
ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
...@@ -3130,48 +3176,13 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) ...@@ -3130,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); ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
} }
#define ntab_upload_r3(dev, offset, data) do { \ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ void b43_nphy_tables_init(struct b43_wldev *dev)
} while (0)
void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
{ {
struct ssb_sprom *sprom = dev->dev->bus_sprom; if (dev->phy.rev >= 3)
b43_nphy_tables_init_rev3(dev);
/* 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]);
else else
B43_WARN_ON(1); b43_nphy_tables_init_rev0(dev);
} }
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
......
...@@ -115,22 +115,22 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( ...@@ -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_NOISEVAR11_SIZE 256
#define B43_NTAB_C0_ESTPLT B43_NTAB8 (0x1A, 0x000) /* Estimate Power Lookup Table Core 0 */ #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_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 B43_NTAB8 (0x1A, 0x040) /* Adjust Power Lookup Table Core 0 */
#define B43_NTAB_C0_ADJPLT_SIZE 128 #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 B43_NTAB32(0x1A, 0x0C0) /* Gain Control Lookup Table Core 0 */
#define B43_NTAB_C0_GAINCTL_SIZE 128 #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 B43_NTAB32(0x1A, 0x140) /* IQ Lookup Table Core 0 */
#define B43_NTAB_C0_IQLT_SIZE 128 #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 B43_NTAB16(0x1A, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 0 */
#define B43_NTAB_C0_LOFEEDTH_SIZE 128 #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 B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
#define B43_NTAB_C1_LOFEEDTH_SIZE 128 #define B43_NTAB_C1_LOFEEDTH_SIZE 128
...@@ -154,15 +154,17 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( ...@@ -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_CHANEST_R3 B43_NTAB32(22, 0) /* channel estimate */
#define B43_NTAB_FRAMELT_R3 B43_NTAB8(24, 0) /* frame lookup */ #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_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_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_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_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_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_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_40_SIZE 18
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_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); ...@@ -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, void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
unsigned int nr_elements, const void *_data); unsigned int nr_elements, const void *_data);
void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); void b43_nphy_tables_init(struct b43_wldev *dev);
void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev);
......
...@@ -2720,7 +2720,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2720,7 +2720,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
goto out_unlock_mutex; goto out_unlock_mutex;
/* Switch the PHY mode (if necessary). */ /* Switch the PHY mode (if necessary). */
switch (conf->channel->band) { switch (conf->chandef.chan->band) {
case IEEE80211_BAND_2GHZ: case IEEE80211_BAND_2GHZ:
if (phy->type == B43legacy_PHYTYPE_B) if (phy->type == B43legacy_PHYTYPE_B)
new_phymode = B43legacy_PHYMODE_B; new_phymode = B43legacy_PHYMODE_B;
...@@ -2748,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2748,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
/* Switch to the requested channel. /* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */ * The firmware takes care of races with the TX handler. */
if (conf->channel->hw_value != phy->channel) if (conf->chandef.chan->hw_value != phy->channel)
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); b43legacy_radio_selectchannel(dev, conf->chandef.chan->hw_value,
0);
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); 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, ...@@ -3558,7 +3559,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx != 0) if (idx != 0)
return -ENOENT; return -ENOENT;
survey->channel = conf->channel; survey->channel = conf->chandef.chan;
survey->filled = SURVEY_INFO_NOISE_DBM; survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = dev->stats.link_noise; survey->noise = dev->stats.link_noise;
......
...@@ -37,15 +37,6 @@ config BRCMFMAC_SDIO ...@@ -37,15 +37,6 @@ config BRCMFMAC_SDIO
IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
use the driver for a SDIO wireless card. 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 config BRCMFMAC_USB
bool "USB bus interface support for FullMAC driver" bool "USB bus interface support for FullMAC driver"
depends on USB depends on USB
......
...@@ -30,7 +30,8 @@ brcmfmac-objs += \ ...@@ -30,7 +30,8 @@ brcmfmac-objs += \
p2p.o \ p2p.o \
dhd_cdc.o \ dhd_cdc.o \
dhd_common.o \ dhd_common.o \
dhd_linux.o dhd_linux.o \
btcoex.o
brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
dhd_sdio.o \ dhd_sdio.o \
bcmsdh.o \ bcmsdh.o \
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/mmc/sdio.h> #include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/platform_data/brcmfmac-sdio.h>
#include <defs.h> #include <defs.h>
#include <brcm_hw_ids.h> #include <brcm_hw_ids.h>
...@@ -37,16 +38,15 @@ ...@@ -37,16 +38,15 @@
#define SDIOH_API_ACCESS_RETRY_LIMIT 2 #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_bus *bus_if = dev_get_drvdata(dev_id);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 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 * be cleared until dpc
*/ */
if (sdiodev->irq_en) { if (sdiodev->irq_en) {
...@@ -59,72 +59,12 @@ static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) ...@@ -59,72 +59,12 @@ static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) static void brcmf_sdio_ib_irqhandler(struct sdio_func *func)
{
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)
{ {
struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(INTR, "ib intr triggered\n"); brcmf_dbg(INTR, "IB intr triggered\n");
brcmf_sdbrcm_isr(sdiodev->bus); brcmf_sdbrcm_isr(sdiodev->bus);
} }
...@@ -136,12 +76,56 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) ...@@ -136,12 +76,56 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) 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]); if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler); brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); sdiodev->pdata->oob_irq_nr);
sdio_release_host(sdiodev->func[1]); 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; return 0;
} }
...@@ -150,14 +134,31 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) ...@@ -150,14 +134,31 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
{ {
brcmf_dbg(SDIO, "Entering\n"); brcmf_dbg(SDIO, "Entering\n");
sdio_claim_host(sdiodev->func[1]); if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
sdio_release_irq(sdiodev->func[2]); sdio_claim_host(sdiodev->func[1]);
sdio_release_irq(sdiodev->func[1]); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
sdio_release_host(sdiodev->func[1]); 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; return 0;
} }
#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
int int
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
...@@ -457,36 +458,80 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, ...@@ -457,36 +458,80 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
return err; return err;
} }
int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, int
u8 *buf, uint nbytes) brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
u8 *data, uint size)
{ {
struct sk_buff *mypkt; int bcmerror = 0;
bool write = rw ? SDIOH_WRITE : SDIOH_READ; struct sk_buff *pkt;
int err; 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; /* Determine initial transfer parameters */
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 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); sdio_claim_host(sdiodev->func[1]);
if (!mypkt) {
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", /* Do the transfer(s) */
nbytes); while (size) {
return -EIO; /* 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. */ dev_kfree_skb(pkt);
if (write)
memcpy(mypkt->data, buf, nbytes);
err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write, /* Return the window to backplane enumeration space for core access */
SDIO_FUNC_1, addr, mypkt); 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. */ sdio_release_host(sdiodev->func[1]);
if (!err && !write)
memcpy(buf, mypkt->data, nbytes);
brcmu_pkt_buf_free_skb(mypkt); return bcmerror;
return err;
} }
int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/sched.h> /* request_irq() */ #include <linux/sched.h> /* request_irq() */
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/brcmfmac-sdio.h>
#include <net/cfg80211.h> #include <net/cfg80211.h>
#include <defs.h> #include <defs.h>
...@@ -40,32 +41,30 @@ ...@@ -40,32 +41,30 @@
#define DMA_ALIGN_MASK 0x03 #define DMA_ALIGN_MASK 0x03
#define SDIO_DEVICE_ID_BROADCOM_43143 43143
#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
#define SDIO_DEVICE_ID_BROADCOM_4335 0x4335
#define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC1_BLOCKSIZE 64
#define SDIO_FUNC2_BLOCKSIZE 512 #define SDIO_FUNC2_BLOCKSIZE 512
/* devices we support, null terminated */ /* devices we support, null terminated */
static const struct sdio_device_id brcmf_sdmmc_ids[] = { 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_43241)},
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {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_4330)},
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, {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 */ }, { /* end: all zeroes */ },
}; };
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
#ifdef CONFIG_BRCMFMAC_SDIO_OOB static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
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 bool static bool
brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
...@@ -424,33 +423,6 @@ void brcmf_sdioh_detach(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, static int brcmf_ops_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
...@@ -491,15 +463,13 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, ...@@ -491,15 +463,13 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
dev_set_drvdata(&func->dev, bus_if); dev_set_drvdata(&func->dev, bus_if);
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
sdiodev->dev = &sdiodev->func[1]->dev; sdiodev->dev = &sdiodev->func[1]->dev;
sdiodev->pdata = brcmfmac_sdio_pdata;
atomic_set(&sdiodev->suspend, false); atomic_set(&sdiodev->suspend, false);
init_waitqueue_head(&sdiodev->request_byte_wait); init_waitqueue_head(&sdiodev->request_byte_wait);
init_waitqueue_head(&sdiodev->request_word_wait); init_waitqueue_head(&sdiodev->request_word_wait);
init_waitqueue_head(&sdiodev->request_chain_wait); init_waitqueue_head(&sdiodev->request_chain_wait);
init_waitqueue_head(&sdiodev->request_buffer_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"); brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
err = brcmf_sdio_probe(sdiodev); err = brcmf_sdio_probe(sdiodev);
...@@ -594,7 +564,7 @@ static const struct dev_pm_ops brcmf_sdio_pm_ops = { ...@@ -594,7 +564,7 @@ static const struct dev_pm_ops brcmf_sdio_pm_ops = {
static struct sdio_driver brcmf_sdmmc_driver = { static struct sdio_driver brcmf_sdmmc_driver = {
.probe = brcmf_ops_sdio_probe, .probe = brcmf_ops_sdio_probe,
.remove = brcmf_ops_sdio_remove, .remove = brcmf_ops_sdio_remove,
.name = "brcmfmac", .name = BRCMFMAC_SDIO_PDATA_NAME,
.id_table = brcmf_sdmmc_ids, .id_table = brcmf_sdmmc_ids,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.drv = { .drv = {
...@@ -603,72 +573,51 @@ static struct sdio_driver brcmf_sdmmc_driver = { ...@@ -603,72 +573,51 @@ static struct sdio_driver brcmf_sdmmc_driver = {
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
}; };
#ifdef CONFIG_BRCMFMAC_SDIO_OOB
static int brcmf_sdio_pd_probe(struct platform_device *pdev) static int brcmf_sdio_pd_probe(struct platform_device *pdev)
{ {
struct resource *res; int ret;
struct brcmf_sdio_oobirq *oobirq_entry;
int i, ret;
INIT_LIST_HEAD(&oobirq_lh); brcmf_dbg(SDIO, "Enter\n");
for (i = 0; ; i++) { brcmfmac_sdio_pdata = pdev->dev.platform_data;
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
if (!res)
break;
oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq), if (brcmfmac_sdio_pdata->power_on)
GFP_KERNEL); brcmfmac_sdio_pdata->power_on();
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;
ret = sdio_register_driver(&brcmf_sdmmc_driver); ret = sdio_register_driver(&brcmf_sdmmc_driver);
if (ret) if (ret)
brcmf_err("sdio_register_driver failed: %d\n", ret); brcmf_err("sdio_register_driver failed: %d\n", ret);
return ret; return ret;
} }
static struct platform_driver brcmf_sdio_pd = { static int brcmf_sdio_pd_remove(struct platform_device *pdev)
.probe = brcmf_sdio_pd_probe,
.driver = {
.name = "brcmf_sdio_pd"
}
};
void brcmf_sdio_exit(void)
{ {
brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Enter\n");
if (brcmfmac_sdio_pdata->power_off)
brcmfmac_sdio_pdata->power_off();
sdio_unregister_driver(&brcmf_sdmmc_driver); sdio_unregister_driver(&brcmf_sdmmc_driver);
platform_driver_unregister(&brcmf_sdio_pd); return 0;
} }
void brcmf_sdio_init(void) static struct platform_driver brcmf_sdio_pd = {
{ .remove = brcmf_sdio_pd_remove,
int ret; .driver = {
.name = BRCMFMAC_SDIO_PDATA_NAME
brcmf_dbg(SDIO, "Enter\n"); }
};
ret = platform_driver_register(&brcmf_sdio_pd);
if (ret)
brcmf_err("platform_driver_register failed: %d\n", ret);
}
#else
void brcmf_sdio_exit(void) void brcmf_sdio_exit(void)
{ {
brcmf_dbg(SDIO, "Enter\n"); 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) void brcmf_sdio_init(void)
...@@ -677,9 +626,12 @@ void brcmf_sdio_init(void) ...@@ -677,9 +626,12 @@ void brcmf_sdio_init(void)
brcmf_dbg(SDIO, "Enter\n"); 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) if (ret)
brcmf_err("sdio_register_driver failed: %d\n", ret); brcmf_err("driver registration failed: %d\n", ret);
} }
#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
/*
* 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",
&reg_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, &param27);
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;
}
此差异已折叠。
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
/******************************************************************************* /*******************************************************************************
* IO codes that are interpreted by dongle firmware * IO codes that are interpreted by dongle firmware
******************************************************************************/ ******************************************************************************/
#define BRCMF_C_GET_VERSION 1
#define BRCMF_C_UP 2 #define BRCMF_C_UP 2
#define BRCMF_C_DOWN 3 #define BRCMF_C_DOWN 3
#define BRCMF_C_SET_PROMISC 10 #define BRCMF_C_SET_PROMISC 10
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册