You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/iwlwifi/pcie/trans.c
This commit is contained in:
@@ -325,6 +325,7 @@
|
||||
<title>functions/definitions</title>
|
||||
!Finclude/net/mac80211.h ieee80211_rx_status
|
||||
!Finclude/net/mac80211.h mac80211_rx_flags
|
||||
!Finclude/net/mac80211.h mac80211_tx_info_flags
|
||||
!Finclude/net/mac80211.h mac80211_tx_control_flags
|
||||
!Finclude/net/mac80211.h mac80211_rate_control_flags
|
||||
!Finclude/net/mac80211.h ieee80211_tx_rate
|
||||
|
||||
+1
-1
@@ -5792,7 +5792,7 @@ M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
|
||||
M: Samuel Ortiz <sameo@linux.intel.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: linux-nfc@lists.01.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
S: Supported
|
||||
F: net/nfc/
|
||||
F: include/net/nfc/
|
||||
F: include/uapi/linux/nfc.h
|
||||
|
||||
@@ -31,7 +31,7 @@ static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
|
||||
}
|
||||
|
||||
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
|
||||
static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
|
||||
{
|
||||
u32 v;
|
||||
int i;
|
||||
@@ -55,7 +55,7 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
|
||||
}
|
||||
}
|
||||
|
||||
static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
|
||||
static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
|
||||
{
|
||||
int max_retries = 10;
|
||||
u16 ret = 0;
|
||||
@@ -98,7 +98,7 @@ static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
|
||||
static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
|
||||
u8 address, u16 data)
|
||||
{
|
||||
int max_retries = 10;
|
||||
@@ -137,6 +137,13 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
|
||||
}
|
||||
|
||||
static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
|
||||
u8 address, u16 data)
|
||||
{
|
||||
bcma_pcie_mdio_write(pc, device, address, data);
|
||||
return bcma_pcie_mdio_read(pc, device, address);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Workarounds.
|
||||
**************************************************/
|
||||
@@ -203,6 +210,25 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
|
||||
}
|
||||
}
|
||||
|
||||
static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up)
|
||||
{
|
||||
u16 data;
|
||||
|
||||
if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
|
||||
data = up ? 0x74 : 0x7C;
|
||||
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
|
||||
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
|
||||
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
|
||||
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
|
||||
} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
|
||||
data = up ? 0x75 : 0x7D;
|
||||
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
|
||||
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
|
||||
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
|
||||
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Init.
|
||||
**************************************************/
|
||||
@@ -262,7 +288,7 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
|
||||
|
||||
void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
|
||||
static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
@@ -274,4 +300,33 @@ void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
|
||||
bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
|
||||
bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
|
||||
|
||||
void bcma_core_pci_up(struct bcma_bus *bus)
|
||||
{
|
||||
struct bcma_drv_pci *pc;
|
||||
|
||||
if (bus->hosttype != BCMA_HOSTTYPE_PCI)
|
||||
return;
|
||||
|
||||
pc = &bus->drv_pci[0];
|
||||
|
||||
bcma_core_pci_power_save(pc, true);
|
||||
|
||||
bcma_core_pci_extend_L1timer(pc, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_pci_up);
|
||||
|
||||
void bcma_core_pci_down(struct bcma_bus *bus)
|
||||
{
|
||||
struct bcma_drv_pci *pc;
|
||||
|
||||
if (bus->hosttype != BCMA_HOSTTYPE_PCI)
|
||||
return;
|
||||
|
||||
pc = &bus->drv_pci[0];
|
||||
|
||||
bcma_core_pci_extend_L1timer(pc, false);
|
||||
|
||||
bcma_core_pci_power_save(pc, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_pci_down);
|
||||
|
||||
@@ -581,6 +581,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
|
||||
int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
struct bcma_drv_pci_host *pc_host;
|
||||
int readrq;
|
||||
|
||||
if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
|
||||
/* This is not a device on the PCI-core bridge. */
|
||||
@@ -595,6 +596,11 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
|
||||
dev->irq = bcma_core_irq(pc_host->pdev->core);
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
|
||||
readrq = pcie_get_readrq(dev);
|
||||
if (readrq > 128) {
|
||||
pr_info("change PCIe max read request size from %i to 128\n", readrq);
|
||||
pcie_set_readrq(dev, 128);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
|
||||
|
||||
@@ -43,7 +43,7 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file,
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
ret = kstrtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -89,7 +89,7 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
ret = kstrtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -135,7 +135,7 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
|
||||
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
ret = kstrtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -486,7 +486,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
|
||||
if (firmwarelen - offset < txlen)
|
||||
txlen = firmwarelen - offset;
|
||||
|
||||
tx_blocks = (txlen + blksz_dl - 1) / blksz_dl;
|
||||
tx_blocks = DIV_ROUND_UP(txlen, blksz_dl);
|
||||
|
||||
memcpy(fwbuf, &firmware[offset], txlen);
|
||||
}
|
||||
@@ -873,7 +873,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
|
||||
}
|
||||
|
||||
blksz = SDIO_BLOCK_SIZE;
|
||||
buf_block_len = (nb + blksz - 1) / blksz;
|
||||
buf_block_len = DIV_ROUND_UP(nb, blksz);
|
||||
|
||||
sdio_claim_host(card->func);
|
||||
|
||||
|
||||
@@ -637,6 +637,7 @@ static int ath10k_ce_completed_send_next_nolock(struct ce_state *ce_state,
|
||||
ath10k_pci_wake(ar);
|
||||
src_ring->hw_index =
|
||||
ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
src_ring->hw_index &= nentries_mask;
|
||||
ath10k_pci_sleep(ar);
|
||||
}
|
||||
read_index = src_ring->hw_index;
|
||||
@@ -950,10 +951,12 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
|
||||
|
||||
ath10k_pci_wake(ar);
|
||||
src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
src_ring->sw_index &= src_ring->nentries_mask;
|
||||
src_ring->hw_index = src_ring->sw_index;
|
||||
|
||||
src_ring->write_index =
|
||||
ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
|
||||
src_ring->write_index &= src_ring->nentries_mask;
|
||||
ath10k_pci_sleep(ar);
|
||||
|
||||
src_ring->per_transfer_context = (void **)ptr;
|
||||
@@ -1035,8 +1038,10 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
|
||||
|
||||
ath10k_pci_wake(ar);
|
||||
dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
|
||||
dest_ring->sw_index &= dest_ring->nentries_mask;
|
||||
dest_ring->write_index =
|
||||
ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
|
||||
dest_ring->write_index &= dest_ring->nentries_mask;
|
||||
ath10k_pci_sleep(ar);
|
||||
|
||||
dest_ring->per_transfer_context = (void **)ptr;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define ATH10K_SCAN_ID 0
|
||||
#define WMI_READY_TIMEOUT (5 * HZ)
|
||||
#define ATH10K_FLUSH_TIMEOUT_HZ (5*HZ)
|
||||
#define ATH10K_NUM_CHANS 38
|
||||
|
||||
/* Antenna noise floor */
|
||||
#define ATH10K_DEFAULT_NOISE_FLOOR -95
|
||||
@@ -285,6 +286,7 @@ struct ath10k {
|
||||
u32 hw_max_tx_power;
|
||||
u32 ht_cap_info;
|
||||
u32 vht_cap_info;
|
||||
u32 num_rf_chains;
|
||||
|
||||
struct targetdef *targetdef;
|
||||
struct hostdef *hostdef;
|
||||
@@ -374,6 +376,12 @@ struct ath10k {
|
||||
|
||||
struct work_struct restart_work;
|
||||
|
||||
/* cycle count is reported twice for each visited channel during scan.
|
||||
* access protected by data_lock */
|
||||
u32 survey_last_rx_clear_count;
|
||||
u32 survey_last_cycle_count;
|
||||
struct survey_info survey[ATH10K_NUM_CHANS];
|
||||
|
||||
#ifdef CONFIG_ATH10K_DEBUGFS
|
||||
struct ath10k_debug debug;
|
||||
#endif
|
||||
|
||||
@@ -804,6 +804,37 @@ static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
u32 flags, info;
|
||||
bool is_ip4, is_ip6;
|
||||
bool is_tcp, is_udp;
|
||||
bool ip_csum_ok, tcpudp_csum_ok;
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
flags = __le32_to_cpu(rxd->attention.flags);
|
||||
info = __le32_to_cpu(rxd->msdu_start.info1);
|
||||
|
||||
is_ip4 = !!(info & RX_MSDU_START_INFO1_IPV4_PROTO);
|
||||
is_ip6 = !!(info & RX_MSDU_START_INFO1_IPV6_PROTO);
|
||||
is_tcp = !!(info & RX_MSDU_START_INFO1_TCP_PROTO);
|
||||
is_udp = !!(info & RX_MSDU_START_INFO1_UDP_PROTO);
|
||||
ip_csum_ok = !(flags & RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL);
|
||||
tcpudp_csum_ok = !(flags & RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL);
|
||||
|
||||
if (!is_ip4 && !is_ip6)
|
||||
return CHECKSUM_NONE;
|
||||
if (!is_tcp && !is_udp)
|
||||
return CHECKSUM_NONE;
|
||||
if (!ip_csum_ok)
|
||||
return CHECKSUM_NONE;
|
||||
if (!tcpudp_csum_ok)
|
||||
return CHECKSUM_NONE;
|
||||
|
||||
return CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
|
||||
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
struct htt_rx_indication *rx)
|
||||
{
|
||||
@@ -815,6 +846,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
u8 *fw_desc;
|
||||
int i, j;
|
||||
int ret;
|
||||
int ip_summed;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
@@ -889,6 +921,11 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The skb is not yet processed and it may be
|
||||
* reallocated. Since the offload is in the original
|
||||
* skb extract the checksum now and assign it later */
|
||||
ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
|
||||
|
||||
info.skb = msdu_head;
|
||||
info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
|
||||
info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
|
||||
@@ -914,6 +951,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
if (ath10k_htt_rx_hdr_is_amsdu((void *)info.skb->data))
|
||||
ath10k_dbg(ATH10K_DBG_HTT, "htt mpdu is amsdu\n");
|
||||
|
||||
info.skb->ip_summed = ip_summed;
|
||||
|
||||
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt mpdu: ",
|
||||
info.skb->data, info.skb->len);
|
||||
ath10k_process_rx(htt->ar, &info);
|
||||
@@ -980,6 +1019,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
||||
info.status = HTT_RX_IND_MPDU_STATUS_OK;
|
||||
info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
info.skb->ip_summed = ath10k_htt_rx_get_csum_state(info.skb);
|
||||
|
||||
if (tkip_mic_err) {
|
||||
ath10k_warn("tkip mic error\n");
|
||||
|
||||
@@ -465,6 +465,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
flags1 = 0;
|
||||
flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
|
||||
flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
|
||||
flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD;
|
||||
flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD;
|
||||
|
||||
frags_paddr = ATH10K_SKB_CB(txfrag)->paddr;
|
||||
|
||||
|
||||
@@ -1406,9 +1406,9 @@ static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw,
|
||||
return;
|
||||
|
||||
qos_ctl = ieee80211_get_qos_ctl(hdr);
|
||||
memmove(qos_ctl, qos_ctl + IEEE80211_QOS_CTL_LEN,
|
||||
skb->len - ieee80211_hdrlen(hdr->frame_control));
|
||||
skb_trim(skb, skb->len - IEEE80211_QOS_CTL_LEN);
|
||||
memmove(skb->data + IEEE80211_QOS_CTL_LEN,
|
||||
skb->data, (void *)qos_ctl - (void *)skb->data);
|
||||
skb_pull(skb, IEEE80211_QOS_CTL_LEN);
|
||||
}
|
||||
|
||||
static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
|
||||
@@ -1925,6 +1925,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
memset(arvif, 0, sizeof(*arvif));
|
||||
|
||||
arvif->ar = ar;
|
||||
arvif->vif = vif;
|
||||
|
||||
@@ -2338,6 +2340,8 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
|
||||
arg.ssids[i].len = req->ssids[i].ssid_len;
|
||||
arg.ssids[i].ssid = req->ssids[i].ssid;
|
||||
}
|
||||
} else {
|
||||
arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
|
||||
}
|
||||
|
||||
if (req->n_channels) {
|
||||
@@ -2934,6 +2938,41 @@ static void ath10k_restart_complete(struct ieee80211_hw *hw)
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct survey_info *ar_survey = &ar->survey[idx];
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
if (sband && idx >= sband->n_channels) {
|
||||
idx -= sband->n_channels;
|
||||
sband = NULL;
|
||||
}
|
||||
|
||||
if (!sband)
|
||||
sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (!sband || idx >= sband->n_channels) {
|
||||
ret = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
memcpy(survey, ar_survey, sizeof(*survey));
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
survey->channel = &sband->channels[idx];
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops ath10k_ops = {
|
||||
.tx = ath10k_tx,
|
||||
.start = ath10k_start,
|
||||
@@ -2955,6 +2994,7 @@ static const struct ieee80211_ops ath10k_ops = {
|
||||
.flush = ath10k_flush,
|
||||
.tx_last_beacon = ath10k_tx_last_beacon,
|
||||
.restart_complete = ath10k_restart_complete,
|
||||
.get_survey = ath10k_get_survey,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ath10k_suspend,
|
||||
.resume = ath10k_resume,
|
||||
@@ -3076,9 +3116,15 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
| BIT(NL80211_IFTYPE_P2P_GO)
|
||||
| BIT(NL80211_IFTYPE_AP)
|
||||
}
|
||||
},
|
||||
{
|
||||
.max = 3,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
},
|
||||
{
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination ath10k_if_comb = {
|
||||
@@ -3093,19 +3139,18 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
|
||||
{
|
||||
struct ieee80211_sta_vht_cap vht_cap = {0};
|
||||
u16 mcs_map;
|
||||
int i;
|
||||
|
||||
vht_cap.vht_supported = 1;
|
||||
vht_cap.cap = ar->vht_cap_info;
|
||||
|
||||
/* FIXME: check dynamically how many streams board supports */
|
||||
mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
|
||||
IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
|
||||
mcs_map = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i < ar->num_rf_chains)
|
||||
mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2);
|
||||
else
|
||||
mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2);
|
||||
}
|
||||
|
||||
vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
|
||||
vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
|
||||
@@ -3168,7 +3213,7 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
|
||||
if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
|
||||
ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
for (i = 0; i < WMI_MAX_SPATIAL_STREAM; i++)
|
||||
for (i = 0; i < ar->num_rf_chains; i++)
|
||||
ht_cap.mcs.rx_mask[i] = 0xFF;
|
||||
|
||||
ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
|
||||
@@ -3310,6 +3355,8 @@ int ath10k_mac_register(struct ath10k *ar)
|
||||
ar->hw->wiphy->iface_combinations = &ath10k_if_comb;
|
||||
ar->hw->wiphy->n_iface_combinations = 1;
|
||||
|
||||
ar->hw->netdev_features = NETIF_F_HW_CSUM;
|
||||
|
||||
ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
|
||||
ath10k_reg_notifier);
|
||||
if (ret) {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "ce.h"
|
||||
#include "pci.h"
|
||||
|
||||
unsigned int ath10k_target_ps;
|
||||
static unsigned int ath10k_target_ps;
|
||||
module_param(ath10k_target_ps, uint, 0644);
|
||||
MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
|
||||
|
||||
@@ -56,6 +56,8 @@ static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
|
||||
static void ath10k_pci_stop_ce(struct ath10k *ar);
|
||||
static void ath10k_pci_device_reset(struct ath10k *ar);
|
||||
static int ath10k_pci_reset_target(struct ath10k *ar);
|
||||
static int ath10k_pci_start_intr(struct ath10k *ar);
|
||||
static void ath10k_pci_stop_intr(struct ath10k *ar);
|
||||
|
||||
static const struct ce_attr host_ce_config_wlan[] = {
|
||||
/* host->target HTC control and raw streams */
|
||||
@@ -1254,10 +1256,25 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath10k_pci_disable_irqs(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
|
||||
disable_irq(ar_pci->pdev->irq + i);
|
||||
}
|
||||
|
||||
static void ath10k_pci_hif_stop(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
||||
|
||||
/* Irqs are never explicitly re-enabled. They are implicitly re-enabled
|
||||
* by ath10k_pci_start_intr(). */
|
||||
ath10k_pci_disable_irqs(ar);
|
||||
|
||||
ath10k_pci_stop_ce(ar);
|
||||
|
||||
/* At this point, asynchronous threads are stopped, the target should
|
||||
@@ -1267,6 +1284,8 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
|
||||
ath10k_pci_process_ce(ar);
|
||||
ath10k_pci_cleanup_ce(ar);
|
||||
ath10k_pci_buffer_cleanup(ar);
|
||||
|
||||
ar_pci->started = 0;
|
||||
}
|
||||
|
||||
static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
||||
@@ -1740,8 +1759,15 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
|
||||
|
||||
static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int ret;
|
||||
|
||||
ret = ath10k_pci_start_intr(ar);
|
||||
if (ret) {
|
||||
ath10k_err("could not start interrupt handling (%d)\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring the target up cleanly.
|
||||
*
|
||||
@@ -1756,15 +1782,11 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
||||
|
||||
ret = ath10k_pci_reset_target(ar);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_irq;
|
||||
|
||||
if (ath10k_target_ps) {
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
|
||||
} else {
|
||||
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
/* Force AWAKE forever */
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save disabled\n");
|
||||
ath10k_do_pci_wake(ar);
|
||||
}
|
||||
|
||||
ret = ath10k_pci_ce_init(ar);
|
||||
if (ret)
|
||||
@@ -1785,16 +1807,22 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
||||
err_ce:
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
err_ps:
|
||||
if (!ath10k_target_ps)
|
||||
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
ath10k_do_pci_sleep(ar);
|
||||
err_irq:
|
||||
ath10k_pci_stop_intr(ar);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_pci_hif_power_down(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_pci_stop_intr(ar);
|
||||
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
if (!ath10k_target_ps)
|
||||
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
ath10k_do_pci_sleep(ar);
|
||||
}
|
||||
|
||||
@@ -1990,8 +2018,13 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
|
||||
ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW,
|
||||
ath10k_pci_msi_fw_handler,
|
||||
IRQF_SHARED, "ath10k_pci", ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_warn("request_irq(%d) failed %d\n",
|
||||
ar_pci->pdev->irq + MSI_ASSIGN_FW, ret);
|
||||
|
||||
pci_disable_msi(ar_pci->pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = MSI_ASSIGN_CE_INITIAL; i <= MSI_ASSIGN_CE_MAX; i++) {
|
||||
ret = request_irq(ar_pci->pdev->irq + i,
|
||||
@@ -2239,6 +2272,9 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
|
||||
case ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND:
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n");
|
||||
break;
|
||||
case ATH10K_PCI_FEATURE_SOC_POWER_SAVE:
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "QCA98XX SoC power save enabled\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2274,6 +2310,9 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
goto err_ar_pci;
|
||||
}
|
||||
|
||||
if (ath10k_target_ps)
|
||||
set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features);
|
||||
|
||||
ath10k_pci_dump_features(ar_pci);
|
||||
|
||||
ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops);
|
||||
@@ -2358,22 +2397,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
ar_pci->cacheline_sz = dma_get_cache_alignment();
|
||||
|
||||
ret = ath10k_pci_start_intr(ar);
|
||||
if (ret) {
|
||||
ath10k_err("could not start interrupt handling (%d)\n", ret);
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
ret = ath10k_core_register(ar);
|
||||
if (ret) {
|
||||
ath10k_err("could not register driver core (%d)\n", ret);
|
||||
goto err_intr;
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_intr:
|
||||
ath10k_pci_stop_intr(ar);
|
||||
err_iomap:
|
||||
pci_iounmap(pdev, mem);
|
||||
err_master:
|
||||
@@ -2410,7 +2441,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
|
||||
tasklet_kill(&ar_pci->msi_fw_err);
|
||||
|
||||
ath10k_core_unregister(ar);
|
||||
ath10k_pci_stop_intr(ar);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_iounmap(pdev, ar_pci->mem);
|
||||
|
||||
@@ -153,6 +153,7 @@ struct service_to_pipe {
|
||||
enum ath10k_pci_features {
|
||||
ATH10K_PCI_FEATURE_MSI_X = 0,
|
||||
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND = 1,
|
||||
ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 2,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_PCI_FEATURE_COUNT
|
||||
@@ -335,20 +336,22 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
|
||||
return ioread32(ar_pci->mem + offset);
|
||||
}
|
||||
|
||||
extern unsigned int ath10k_target_ps;
|
||||
|
||||
void ath10k_do_pci_wake(struct ath10k *ar);
|
||||
void ath10k_do_pci_sleep(struct ath10k *ar);
|
||||
|
||||
static inline void ath10k_pci_wake(struct ath10k *ar)
|
||||
{
|
||||
if (ath10k_target_ps)
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
ath10k_do_pci_wake(ar);
|
||||
}
|
||||
|
||||
static inline void ath10k_pci_sleep(struct ath10k *ar)
|
||||
{
|
||||
if (ath10k_target_ps)
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
ath10k_do_pci_sleep(ar);
|
||||
}
|
||||
|
||||
|
||||
@@ -390,9 +390,82 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int freq_to_idx(struct ath10k *ar, int freq)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
int band, ch, idx = 0;
|
||||
|
||||
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
|
||||
sband = ar->hw->wiphy->bands[band];
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
for (ch = 0; ch < sband->n_channels; ch++, idx++)
|
||||
if (sband->channels[ch].center_freq == freq)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ATH10K_DBG_WMI, "WMI_CHAN_INFO_EVENTID\n");
|
||||
struct wmi_chan_info_event *ev;
|
||||
struct survey_info *survey;
|
||||
u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count;
|
||||
int idx;
|
||||
|
||||
ev = (struct wmi_chan_info_event *)skb->data;
|
||||
|
||||
err_code = __le32_to_cpu(ev->err_code);
|
||||
freq = __le32_to_cpu(ev->freq);
|
||||
cmd_flags = __le32_to_cpu(ev->cmd_flags);
|
||||
noise_floor = __le32_to_cpu(ev->noise_floor);
|
||||
rx_clear_count = __le32_to_cpu(ev->rx_clear_count);
|
||||
cycle_count = __le32_to_cpu(ev->cycle_count);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_WMI,
|
||||
"chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n",
|
||||
err_code, freq, cmd_flags, noise_floor, rx_clear_count,
|
||||
cycle_count);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
if (!ar->scan.in_progress) {
|
||||
ath10k_warn("chan info event without a scan request?\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
idx = freq_to_idx(ar, freq);
|
||||
if (idx >= ARRAY_SIZE(ar->survey)) {
|
||||
ath10k_warn("chan info: invalid frequency %d (idx %d out of bounds)\n",
|
||||
freq, idx);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
|
||||
/* During scanning chan info is reported twice for each
|
||||
* visited channel. The reported cycle count is global
|
||||
* and per-channel cycle count must be calculated */
|
||||
|
||||
cycle_count -= ar->survey_last_cycle_count;
|
||||
rx_clear_count -= ar->survey_last_rx_clear_count;
|
||||
|
||||
survey = &ar->survey[idx];
|
||||
survey->channel_time = WMI_CHAN_INFO_MSEC(cycle_count);
|
||||
survey->channel_time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count);
|
||||
survey->noise = noise_floor;
|
||||
survey->filled = SURVEY_INFO_CHANNEL_TIME |
|
||||
SURVEY_INFO_CHANNEL_TIME_RX |
|
||||
SURVEY_INFO_NOISE_DBM;
|
||||
}
|
||||
|
||||
ar->survey_last_rx_clear_count = rx_clear_count;
|
||||
ar->survey_last_cycle_count = cycle_count;
|
||||
|
||||
exit:
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
|
||||
@@ -868,6 +941,13 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
|
||||
(__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16;
|
||||
ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff);
|
||||
ar->phy_capability = __le32_to_cpu(ev->phy_capability);
|
||||
ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
|
||||
|
||||
if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) {
|
||||
ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n",
|
||||
ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM);
|
||||
ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM;
|
||||
}
|
||||
|
||||
ar->ath_common.regulatory.current_rd =
|
||||
__le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
|
||||
@@ -892,7 +972,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
|
||||
}
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_WMI,
|
||||
"wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u\n",
|
||||
"wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n",
|
||||
__le32_to_cpu(ev->sw_version),
|
||||
__le32_to_cpu(ev->sw_version_1),
|
||||
__le32_to_cpu(ev->abi_version),
|
||||
@@ -901,7 +981,8 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
|
||||
__le32_to_cpu(ev->vht_cap_info),
|
||||
__le32_to_cpu(ev->vht_supp_mcs),
|
||||
__le32_to_cpu(ev->sys_cap_info),
|
||||
__le32_to_cpu(ev->num_mem_reqs));
|
||||
__le32_to_cpu(ev->num_mem_reqs),
|
||||
__le32_to_cpu(ev->num_rf_chains));
|
||||
|
||||
complete(&ar->wmi.service_ready);
|
||||
}
|
||||
|
||||
@@ -2931,6 +2931,11 @@ struct wmi_chan_info_event {
|
||||
__le32 cycle_count;
|
||||
} __packed;
|
||||
|
||||
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
|
||||
|
||||
/* FIXME: empirically extrapolated */
|
||||
#define WMI_CHAN_INFO_MSEC(x) ((x) / 76595)
|
||||
|
||||
/* Beacon filter wmi command info */
|
||||
#define BCN_FLT_MAX_SUPPORTED_IES 256
|
||||
#define BCN_FLT_MAX_ELEMS_IE_LIST (BCN_FLT_MAX_SUPPORTED_IES / 32)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/average.h>
|
||||
#include <linux/leds.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
/* RX/TX descriptor hw structs
|
||||
* TODO: Driver part should only see sw structs */
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
@@ -165,28 +166,36 @@ static const struct ieee80211_rate ath5k_rates[] = {
|
||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE },
|
||||
{ .bitrate = 60,
|
||||
.hw_value = ATH5K_RATE_CODE_6M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 90,
|
||||
.hw_value = ATH5K_RATE_CODE_9M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 120,
|
||||
.hw_value = ATH5K_RATE_CODE_12M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 180,
|
||||
.hw_value = ATH5K_RATE_CODE_18M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 240,
|
||||
.hw_value = ATH5K_RATE_CODE_24M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 360,
|
||||
.hw_value = ATH5K_RATE_CODE_36M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 480,
|
||||
.hw_value = ATH5K_RATE_CODE_48M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
{ .bitrate = 540,
|
||||
.hw_value = ATH5K_RATE_CODE_54M,
|
||||
.flags = 0 },
|
||||
.flags = IEEE80211_RATE_SUPPORTS_5MHZ |
|
||||
IEEE80211_RATE_SUPPORTS_10MHZ },
|
||||
};
|
||||
|
||||
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
|
||||
@@ -435,11 +444,27 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
|
||||
* Called with ah->lock.
|
||||
*/
|
||||
int
|
||||
ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan)
|
||||
ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
|
||||
"channel set, resetting (%u -> %u MHz)\n",
|
||||
ah->curchan->center_freq, chan->center_freq);
|
||||
ah->curchan->center_freq, chandef->chan->center_freq);
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
ah->ah_bwmode = AR5K_BWMODE_5MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
ah->ah_bwmode = AR5K_BWMODE_10MHZ;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* To switch channels clear any pending DMA operations;
|
||||
@@ -447,7 +472,7 @@ ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan)
|
||||
* hardware at the new frequency, and then re-enable
|
||||
* the relevant bits of the h/w.
|
||||
*/
|
||||
return ath5k_reset(ah, chan, true);
|
||||
return ath5k_reset(ah, chandef->chan, true);
|
||||
}
|
||||
|
||||
void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
@@ -1400,6 +1425,16 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
|
||||
|
||||
rxs->rate_idx = ath5k_hw_to_driver_rix(ah, rs->rs_rate);
|
||||
rxs->flag |= ath5k_rx_decrypted(ah, skb, rs);
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
rxs->flag |= RX_FLAG_5MHZ;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
rxs->flag |= RX_FLAG_10MHZ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rxs->rate_idx >= 0 && rs->rs_rate ==
|
||||
ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
|
||||
@@ -2507,6 +2542,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
|
||||
/* SW support for IBSS_RSN is provided by mac80211 */
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
|
||||
|
||||
/* both antennas can be configured as RX or TX */
|
||||
hw->wiphy->available_antennas_tx = 0x3;
|
||||
hw->wiphy->available_antennas_rx = 0x3;
|
||||
|
||||
@@ -101,7 +101,7 @@ void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
|
||||
|
||||
void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
|
||||
struct ieee80211_vif *vif);
|
||||
int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
|
||||
int ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef);
|
||||
void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
|
||||
void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
|
||||
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
|
||||
@@ -245,9 +245,11 @@ static ssize_t write_file_beacon(struct file *file,
|
||||
struct ath5k_hw *ah = file->private_data;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
if (strncmp(buf, "disable", 7) == 0) {
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
|
||||
pr_info("debugfs disable beacons\n");
|
||||
@@ -345,9 +347,11 @@ static ssize_t write_file_debug(struct file *file,
|
||||
unsigned int i;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
|
||||
if (strncmp(buf, dbg_info[i].name,
|
||||
strlen(dbg_info[i].name)) == 0) {
|
||||
@@ -448,9 +452,11 @@ static ssize_t write_file_antenna(struct file *file,
|
||||
unsigned int i;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
if (strncmp(buf, "diversity", 9) == 0) {
|
||||
ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
|
||||
pr_info("debug: enable diversity\n");
|
||||
@@ -619,9 +625,11 @@ static ssize_t write_file_frameerrors(struct file *file,
|
||||
struct ath5k_statistics *st = &ah->stats;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
if (strncmp(buf, "clear", 5) == 0) {
|
||||
st->rxerr_crc = 0;
|
||||
st->rxerr_phy = 0;
|
||||
@@ -766,9 +774,11 @@ static ssize_t write_file_ani(struct file *file,
|
||||
struct ath5k_hw *ah = file->private_data;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
if (strncmp(buf, "sens-low", 8) == 0) {
|
||||
ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
|
||||
} else if (strncmp(buf, "sens-high", 9) == 0) {
|
||||
@@ -862,9 +872,11 @@ static ssize_t write_file_queue(struct file *file,
|
||||
struct ath5k_hw *ah = file->private_data;
|
||||
char buf[20];
|
||||
|
||||
if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
count = min_t(size_t, count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, userbuf, count))
|
||||
return -EFAULT;
|
||||
|
||||
buf[count] = '\0';
|
||||
if (strncmp(buf, "start", 5) == 0)
|
||||
ieee80211_wake_queues(ah->hw);
|
||||
else if (strncmp(buf, "stop", 4) == 0)
|
||||
|
||||
@@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
mutex_lock(&ah->lock);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||
ret = ath5k_chan_set(ah, conf->chandef.chan);
|
||||
ret = ath5k_chan_set(ah, &conf->chandef);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user