mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts: drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
This commit is contained in:
commit
1e13f863ca
|
@ -146,6 +146,7 @@
|
|||
!Finclude/net/cfg80211.h cfg80211_rx_mgmt
|
||||
!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status
|
||||
!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify
|
||||
!Finclude/net/cfg80211.h cfg80211_cqm_pktloss_notify
|
||||
!Finclude/net/cfg80211.h cfg80211_michael_mic_failure
|
||||
</chapter>
|
||||
<chapter>
|
||||
|
@ -332,10 +333,16 @@
|
|||
<title>functions/definitions</title>
|
||||
!Finclude/net/mac80211.h ieee80211_rx_status
|
||||
!Finclude/net/mac80211.h mac80211_rx_flags
|
||||
!Finclude/net/mac80211.h mac80211_tx_control_flags
|
||||
!Finclude/net/mac80211.h mac80211_rate_control_flags
|
||||
!Finclude/net/mac80211.h ieee80211_tx_rate
|
||||
!Finclude/net/mac80211.h ieee80211_tx_info
|
||||
!Finclude/net/mac80211.h ieee80211_tx_info_clear_status
|
||||
!Finclude/net/mac80211.h ieee80211_rx
|
||||
!Finclude/net/mac80211.h ieee80211_rx_ni
|
||||
!Finclude/net/mac80211.h ieee80211_rx_irqsafe
|
||||
!Finclude/net/mac80211.h ieee80211_tx_status
|
||||
!Finclude/net/mac80211.h ieee80211_tx_status_ni
|
||||
!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
|
||||
!Finclude/net/mac80211.h ieee80211_rts_get
|
||||
!Finclude/net/mac80211.h ieee80211_rts_duration
|
||||
|
@ -346,6 +353,7 @@
|
|||
!Finclude/net/mac80211.h ieee80211_stop_queue
|
||||
!Finclude/net/mac80211.h ieee80211_wake_queues
|
||||
!Finclude/net/mac80211.h ieee80211_stop_queues
|
||||
!Finclude/net/mac80211.h ieee80211_queue_stopped
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
|
@ -354,6 +362,13 @@
|
|||
!Pinclude/net/mac80211.h Frame filtering
|
||||
!Finclude/net/mac80211.h ieee80211_filter_flags
|
||||
</chapter>
|
||||
|
||||
<chapter id="workqueue">
|
||||
<title>The mac80211 workqueue</title>
|
||||
!Pinclude/net/mac80211.h mac80211 workqueue
|
||||
!Finclude/net/mac80211.h ieee80211_queue_work
|
||||
!Finclude/net/mac80211.h ieee80211_queue_delayed_work
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="advanced">
|
||||
|
@ -374,6 +389,9 @@
|
|||
!Finclude/net/mac80211.h set_key_cmd
|
||||
!Finclude/net/mac80211.h ieee80211_key_conf
|
||||
!Finclude/net/mac80211.h ieee80211_key_flags
|
||||
!Finclude/net/mac80211.h ieee80211_tkip_key_type
|
||||
!Finclude/net/mac80211.h ieee80211_get_tkip_key
|
||||
!Finclude/net/mac80211.h ieee80211_key_removed
|
||||
</chapter>
|
||||
|
||||
<chapter id="powersave">
|
||||
|
@ -417,6 +435,18 @@
|
|||
supported by mac80211, add notes about supporting hw crypto
|
||||
with it.
|
||||
</para>
|
||||
!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces
|
||||
!Finclude/net/mac80211.h ieee80211_iterate_active_interfaces_atomic
|
||||
</chapter>
|
||||
|
||||
<chapter id="station-handling">
|
||||
<title>Station handling</title>
|
||||
<para>TODO</para>
|
||||
!Finclude/net/mac80211.h ieee80211_sta
|
||||
!Finclude/net/mac80211.h sta_notify_cmd
|
||||
!Finclude/net/mac80211.h ieee80211_find_sta
|
||||
!Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
|
||||
!Finclude/net/mac80211.h ieee80211_sta_block_awake
|
||||
</chapter>
|
||||
|
||||
<chapter id="hardware-scan-offload">
|
||||
|
@ -424,6 +454,28 @@
|
|||
<para>TBD</para>
|
||||
!Finclude/net/mac80211.h ieee80211_scan_completed
|
||||
</chapter>
|
||||
|
||||
<chapter id="aggregation">
|
||||
<title>Aggregation</title>
|
||||
<sect1>
|
||||
<title>TX A-MPDU aggregation</title>
|
||||
!Pnet/mac80211/agg-tx.c TX A-MPDU aggregation
|
||||
!Cnet/mac80211/agg-tx.c
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>RX A-MPDU aggregation</title>
|
||||
!Pnet/mac80211/agg-rx.c RX A-MPDU aggregation
|
||||
!Cnet/mac80211/agg-rx.c
|
||||
</sect1>
|
||||
!Finclude/net/mac80211.h ieee80211_ampdu_mlme_action
|
||||
</chapter>
|
||||
|
||||
<chapter id="smps">
|
||||
<title>Spatial Multiplexing Powersave (SMPS)</title>
|
||||
!Pinclude/net/mac80211.h Spatial multiplexing power save
|
||||
!Finclude/net/mac80211.h ieee80211_request_smps
|
||||
!Finclude/net/mac80211.h ieee80211_smps_mode
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
<part id="rate-control">
|
||||
|
@ -435,9 +487,16 @@
|
|||
interface and how it relates to mac80211 and drivers.
|
||||
</para>
|
||||
</partintro>
|
||||
<chapter id="dummy">
|
||||
<title>dummy chapter</title>
|
||||
<chapter id="ratecontrol-api">
|
||||
<title>Rate Control API</title>
|
||||
<para>TBD</para>
|
||||
!Finclude/net/mac80211.h ieee80211_start_tx_ba_session
|
||||
!Finclude/net/mac80211.h ieee80211_start_tx_ba_cb_irqsafe
|
||||
!Finclude/net/mac80211.h ieee80211_stop_tx_ba_session
|
||||
!Finclude/net/mac80211.h ieee80211_stop_tx_ba_cb_irqsafe
|
||||
!Finclude/net/mac80211.h rate_control_changed
|
||||
!Finclude/net/mac80211.h ieee80211_tx_rate_control
|
||||
!Finclude/net/mac80211.h rate_control_send_low
|
||||
</chapter>
|
||||
</part>
|
||||
|
||||
|
@ -485,6 +544,13 @@
|
|||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="aggregation-internals">
|
||||
<title>Aggregation</title>
|
||||
!Fnet/mac80211/sta_info.h sta_ampdu_mlme
|
||||
!Fnet/mac80211/sta_info.h tid_ampdu_tx
|
||||
!Fnet/mac80211/sta_info.h tid_ampdu_rx
|
||||
</chapter>
|
||||
|
||||
<chapter id="synchronisation">
|
||||
<title>Synchronisation</title>
|
||||
<para>TBD</para>
|
||||
|
|
|
@ -161,8 +161,7 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
|
|||
static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = urb->context;
|
||||
struct ar9170_usb *aru = (struct ar9170_usb *)
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
|
||||
if (unlikely(!aru)) {
|
||||
dev_kfree_skb_irq(skb);
|
||||
|
@ -219,8 +218,7 @@ static void ar9170_usb_irq_completed(struct urb *urb)
|
|||
static void ar9170_usb_rx_completed(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = urb->context;
|
||||
struct ar9170_usb *aru = (struct ar9170_usb *)
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
int err;
|
||||
|
||||
if (!aru)
|
||||
|
|
|
@ -168,6 +168,8 @@ struct ath_common {
|
|||
struct ath_regulatory regulatory;
|
||||
const struct ath_ops *ops;
|
||||
const struct ath_bus_ops *bus_ops;
|
||||
|
||||
bool btcoex_enabled;
|
||||
};
|
||||
|
||||
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
config ATH5K
|
||||
tristate "Atheros 5xxx wireless cards support"
|
||||
depends on PCI && MAC80211
|
||||
depends on (PCI || ATHEROS_AR231X) && MAC80211
|
||||
select MAC80211_LEDS
|
||||
select LEDS_CLASS
|
||||
select NEW_LEDS
|
||||
select AVERAGE
|
||||
select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
|
||||
select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Atheros 5xxx chipset.
|
||||
|
@ -38,3 +40,16 @@ config ATH5K_DEBUG
|
|||
|
||||
modprobe ath5k debug=0x00000400
|
||||
|
||||
config ATH5K_AHB
|
||||
bool "Atheros 5xxx AHB bus support"
|
||||
depends on (ATHEROS_AR231X && !PCI)
|
||||
---help---
|
||||
This adds support for WiSoC type chipsets of the 5xxx Atheros
|
||||
family.
|
||||
|
||||
config ATH5K_PCI
|
||||
bool "Atheros 5xxx PCI bus support"
|
||||
depends on (!ATHEROS_AR231X && PCI)
|
||||
---help---
|
||||
This adds support for PCI type chipsets of the 5xxx Atheros
|
||||
family.
|
||||
|
|
|
@ -15,4 +15,6 @@ ath5k-y += rfkill.o
|
|||
ath5k-y += ani.o
|
||||
ath5k-y += sysfs.o
|
||||
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
|
||||
ath5k-$(CONFIG_ATH5K_AHB) += ahb.o
|
||||
ath5k-$(CONFIG_ATH5K_PCI) += pci.o
|
||||
obj-$(CONFIG_ATH5K) += ath5k.o
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
* Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* 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/nl80211.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <ar231x_platform.h>
|
||||
#include "ath5k.h"
|
||||
#include "debug.h"
|
||||
#include "base.h"
|
||||
#include "reg.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* return bus cachesize in 4B word units */
|
||||
static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
|
||||
{
|
||||
*csz = L1_CACHE_BYTES >> 2;
|
||||
}
|
||||
|
||||
bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
||||
{
|
||||
struct ath5k_softc *sc = common->priv;
|
||||
struct platform_device *pdev = to_platform_device(sc->dev);
|
||||
struct ar231x_board_config *bcfg = pdev->dev.platform_data;
|
||||
u16 *eeprom, *eeprom_end;
|
||||
|
||||
|
||||
|
||||
bcfg = pdev->dev.platform_data;
|
||||
eeprom = (u16 *) bcfg->radio;
|
||||
eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
|
||||
|
||||
eeprom += off;
|
||||
if (eeprom > eeprom_end)
|
||||
return -EINVAL;
|
||||
|
||||
*data = *eeprom;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath5k_hw_read_srev(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ath5k_softc *sc = ah->ah_sc;
|
||||
struct platform_device *pdev = to_platform_device(sc->dev);
|
||||
struct ar231x_board_config *bcfg = pdev->dev.platform_data;
|
||||
ah->ah_mac_srev = bcfg->devid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ath_bus_ops ath_ahb_bus_ops = {
|
||||
.ath_bus_type = ATH_AHB,
|
||||
.read_cachesize = ath5k_ahb_read_cachesize,
|
||||
.eeprom_read = ath5k_ahb_eeprom_read,
|
||||
};
|
||||
|
||||
/*Initialization*/
|
||||
static int ath_ahb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ar231x_board_config *bcfg = pdev->dev.platform_data;
|
||||
struct ath5k_softc *sc;
|
||||
struct ieee80211_hw *hw;
|
||||
struct resource *res;
|
||||
void __iomem *mem;
|
||||
int irq;
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "no platform data specified\n");
|
||||
ret = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no memory resource found\n");
|
||||
ret = -ENXIO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
mem = ioremap_nocache(res->start, res->end - res->start + 1);
|
||||
if (mem == NULL) {
|
||||
dev_err(&pdev->dev, "ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no IRQ resource found\n");
|
||||
ret = -ENXIO;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
irq = res->start;
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
|
||||
if (hw == NULL) {
|
||||
dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
sc = hw->priv;
|
||||
sc->hw = hw;
|
||||
sc->dev = &pdev->dev;
|
||||
sc->iobase = mem;
|
||||
sc->irq = irq;
|
||||
sc->devid = bcfg->devid;
|
||||
|
||||
if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
|
||||
/* Enable WMAC AHB arbitration */
|
||||
reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
|
||||
reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
|
||||
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
|
||||
|
||||
/* Enable global WMAC swapping */
|
||||
reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
|
||||
reg |= AR5K_AR2315_BYTESWAP_WMAC;
|
||||
__raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
|
||||
} else {
|
||||
/* Enable WMAC DMA access (assuming 5312 or 231x*/
|
||||
/* TODO: check other platforms */
|
||||
reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
|
||||
if (to_platform_device(sc->dev)->id == 0)
|
||||
reg |= AR5K_AR5312_ENABLE_WLAN0;
|
||||
else
|
||||
reg |= AR5K_AR5312_ENABLE_WLAN1;
|
||||
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
|
||||
}
|
||||
|
||||
ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
|
||||
ret = -ENODEV;
|
||||
goto err_free_hw;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, hw);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_hw:
|
||||
ieee80211_free_hw(hw);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
err_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath_ahb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ar231x_board_config *bcfg = pdev->dev.platform_data;
|
||||
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
|
||||
struct ath5k_softc *sc;
|
||||
u32 reg;
|
||||
|
||||
if (!hw)
|
||||
return 0;
|
||||
|
||||
sc = hw->priv;
|
||||
|
||||
if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
|
||||
/* Disable WMAC AHB arbitration */
|
||||
reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
|
||||
reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
|
||||
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
|
||||
} else {
|
||||
/*Stop DMA access */
|
||||
reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
|
||||
if (to_platform_device(sc->dev)->id == 0)
|
||||
reg &= ~AR5K_AR5312_ENABLE_WLAN0;
|
||||
else
|
||||
reg &= ~AR5K_AR5312_ENABLE_WLAN1;
|
||||
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
|
||||
}
|
||||
|
||||
ath5k_deinit_softc(sc);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ath_ahb_driver = {
|
||||
.probe = ath_ahb_probe,
|
||||
.remove = ath_ahb_remove,
|
||||
.driver = {
|
||||
.name = "ar231x-wmac",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init
|
||||
ath5k_ahb_init(void)
|
||||
{
|
||||
return platform_driver_register(&ath_ahb_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
ath5k_ahb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ath_ahb_driver);
|
||||
}
|
||||
|
||||
module_init(ath5k_ahb_init);
|
||||
module_exit(ath5k_ahb_exit);
|
|
@ -58,19 +58,19 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
|
|||
{
|
||||
/* TODO:
|
||||
* ANI documents suggest the following five levels to use, but the HAL
|
||||
* and ath9k use only use the last two levels, making this
|
||||
* and ath9k use only the last two levels, making this
|
||||
* essentially an on/off option. There *may* be a reason for this (???),
|
||||
* so i stick with the HAL version for now...
|
||||
*/
|
||||
#if 0
|
||||
static const s8 hi[] = { -18, -18, -16, -14, -12 };
|
||||
static const s8 lo[] = { -52, -56, -60, -64, -70 };
|
||||
static const s8 hi[] = { -18, -18, -16, -14, -12 };
|
||||
static const s8 sz[] = { -34, -41, -48, -55, -62 };
|
||||
static const s8 fr[] = { -70, -72, -75, -78, -80 };
|
||||
#else
|
||||
static const s8 sz[] = { -55, -62 };
|
||||
static const s8 lo[] = { -64, -70 };
|
||||
static const s8 hi[] = { -14, -12 };
|
||||
static const s8 sz[] = { -55, -62 };
|
||||
static const s8 fr[] = { -78, -80 };
|
||||
#endif
|
||||
if (level < 0 || level >= ARRAY_SIZE(sz)) {
|
||||
|
|
|
@ -158,15 +158,6 @@
|
|||
#define AR5K_INI_RFGAIN_5GHZ 0
|
||||
#define AR5K_INI_RFGAIN_2GHZ 1
|
||||
|
||||
/* TODO: Clean this up */
|
||||
#define AR5K_INI_VAL_11A 0
|
||||
#define AR5K_INI_VAL_11A_TURBO 1
|
||||
#define AR5K_INI_VAL_11B 2
|
||||
#define AR5K_INI_VAL_11G 3
|
||||
#define AR5K_INI_VAL_11G_TURBO 4
|
||||
#define AR5K_INI_VAL_XR 0
|
||||
#define AR5K_INI_VAL_MAX 5
|
||||
|
||||
/*
|
||||
* Some tuneable values (these should be changeable by the user)
|
||||
* TODO: Make use of them and add more options OR use debug/configfs
|
||||
|
@ -222,42 +213,66 @@
|
|||
|
||||
/* Initial values */
|
||||
#define AR5K_INIT_CYCRSSI_THR1 2
|
||||
#define AR5K_INIT_TX_LATENCY 502
|
||||
#define AR5K_INIT_USEC 39
|
||||
#define AR5K_INIT_USEC_TURBO 79
|
||||
#define AR5K_INIT_USEC_32 31
|
||||
#define AR5K_INIT_SLOT_TIME 396
|
||||
#define AR5K_INIT_SLOT_TIME_TURBO 480
|
||||
#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
|
||||
#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
|
||||
#define AR5K_INIT_PROG_IFS 920
|
||||
#define AR5K_INIT_PROG_IFS_TURBO 960
|
||||
#define AR5K_INIT_EIFS 3440
|
||||
#define AR5K_INIT_EIFS_TURBO 6880
|
||||
#define AR5K_INIT_SIFS 560
|
||||
#define AR5K_INIT_SIFS_TURBO 480
|
||||
|
||||
/* Tx retry limits */
|
||||
#define AR5K_INIT_SH_RETRY 10
|
||||
#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
|
||||
/* For station mode */
|
||||
#define AR5K_INIT_SSH_RETRY 32
|
||||
#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
|
||||
#define AR5K_INIT_TX_RETRY 10
|
||||
|
||||
#define AR5K_INIT_TRANSMIT_LATENCY ( \
|
||||
(AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
|
||||
(AR5K_INIT_USEC) \
|
||||
)
|
||||
#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
|
||||
(AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
|
||||
(AR5K_INIT_USEC_TURBO) \
|
||||
)
|
||||
#define AR5K_INIT_PROTO_TIME_CNTRL ( \
|
||||
(AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
|
||||
(AR5K_INIT_PROG_IFS) \
|
||||
)
|
||||
#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
|
||||
(AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
|
||||
(AR5K_INIT_PROG_IFS_TURBO) \
|
||||
)
|
||||
|
||||
/* Slot time */
|
||||
#define AR5K_INIT_SLOT_TIME_TURBO 6
|
||||
#define AR5K_INIT_SLOT_TIME_DEFAULT 9
|
||||
#define AR5K_INIT_SLOT_TIME_HALF_RATE 13
|
||||
#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21
|
||||
#define AR5K_INIT_SLOT_TIME_B 20
|
||||
#define AR5K_SLOT_TIME_MAX 0xffff
|
||||
|
||||
/* SIFS */
|
||||
#define AR5K_INIT_SIFS_TURBO 6
|
||||
/* XXX: 8 from initvals 10 from standard */
|
||||
#define AR5K_INIT_SIFS_DEFAULT_BG 8
|
||||
#define AR5K_INIT_SIFS_DEFAULT_A 16
|
||||
#define AR5K_INIT_SIFS_HALF_RATE 32
|
||||
#define AR5K_INIT_SIFS_QUARTER_RATE 64
|
||||
|
||||
/* Used to calculate tx time for non 5/10/40MHz
|
||||
* operation */
|
||||
/* It's preamble time + signal time (16 + 4) */
|
||||
#define AR5K_INIT_OFDM_PREAMPLE_TIME 20
|
||||
/* Preamble time for 40MHz (turbo) operation (min ?) */
|
||||
#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14
|
||||
#define AR5K_INIT_OFDM_SYMBOL_TIME 4
|
||||
#define AR5K_INIT_OFDM_PLCP_BITS 22
|
||||
|
||||
/* Rx latency for 5 and 10MHz operation (max ?) */
|
||||
#define AR5K_INIT_RX_LAT_MAX 63
|
||||
/* Tx latencies from initvals (5212 only but no problem
|
||||
* because we only tweak them on 5212) */
|
||||
#define AR5K_INIT_TX_LAT_A 54
|
||||
#define AR5K_INIT_TX_LAT_BG 384
|
||||
/* Tx latency for 40MHz (turbo) operation (min ?) */
|
||||
#define AR5K_INIT_TX_LAT_MIN 32
|
||||
/* Default Tx/Rx latencies (same for 5211)*/
|
||||
#define AR5K_INIT_TX_LATENCY_5210 54
|
||||
#define AR5K_INIT_RX_LATENCY_5210 29
|
||||
|
||||
/* Tx frame to Tx data start delay */
|
||||
#define AR5K_INIT_TXF2TXD_START_DEFAULT 14
|
||||
#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12
|
||||
#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13
|
||||
|
||||
/* We need to increase PHY switch and agc settling time
|
||||
* on turbo mode */
|
||||
#define AR5K_SWITCH_SETTLING 5760
|
||||
#define AR5K_SWITCH_SETTLING_TURBO 7168
|
||||
|
||||
#define AR5K_AGC_SETTLING 28
|
||||
/* 38 on 5210 but shouldn't matter */
|
||||
#define AR5K_AGC_SETTLING_TURBO 37
|
||||
|
||||
|
||||
/* GENERIC CHIPSET DEFINITIONS */
|
||||
|
@ -304,12 +319,19 @@ struct ath5k_srev_name {
|
|||
#define AR5K_SREV_AR5311B 0x30 /* Spirit */
|
||||
#define AR5K_SREV_AR5211 0x40 /* Oahu */
|
||||
#define AR5K_SREV_AR5212 0x50 /* Venice */
|
||||
#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */
|
||||
#define AR5K_SREV_AR5212_V4 0x54 /* ??? */
|
||||
#define AR5K_SREV_AR5213 0x55 /* ??? */
|
||||
#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */
|
||||
#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */
|
||||
#define AR5K_SREV_AR5213A 0x59 /* Hainan */
|
||||
#define AR5K_SREV_AR2413 0x78 /* Griffin lite */
|
||||
#define AR5K_SREV_AR2414 0x70 /* Griffin */
|
||||
#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */
|
||||
#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */
|
||||
#define AR5K_SREV_AR5424 0x90 /* Condor */
|
||||
#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */
|
||||
#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */
|
||||
#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
|
||||
#define AR5K_SREV_AR5414 0xa0 /* Eagle */
|
||||
#define AR5K_SREV_AR2415 0xb0 /* Talon */
|
||||
|
@ -405,12 +427,10 @@ struct ath5k_srev_name {
|
|||
|
||||
enum ath5k_driver_mode {
|
||||
AR5K_MODE_11A = 0,
|
||||
AR5K_MODE_11A_TURBO = 1,
|
||||
AR5K_MODE_11B = 2,
|
||||
AR5K_MODE_11G = 3,
|
||||
AR5K_MODE_11G_TURBO = 4,
|
||||
AR5K_MODE_11B = 1,
|
||||
AR5K_MODE_11G = 2,
|
||||
AR5K_MODE_XR = 0,
|
||||
AR5K_MODE_MAX = 5
|
||||
AR5K_MODE_MAX = 3
|
||||
};
|
||||
|
||||
enum ath5k_ant_mode {
|
||||
|
@ -424,6 +444,12 @@ enum ath5k_ant_mode {
|
|||
AR5K_ANTMODE_MAX,
|
||||
};
|
||||
|
||||
enum ath5k_bw_mode {
|
||||
AR5K_BWMODE_DEFAULT = 0, /* 20MHz, default operation */
|
||||
AR5K_BWMODE_5MHZ = 1, /* Quarter rate */
|
||||
AR5K_BWMODE_10MHZ = 2, /* Half rate */
|
||||
AR5K_BWMODE_40MHZ = 3 /* Turbo */
|
||||
};
|
||||
|
||||
/****************\
|
||||
TX DEFINITIONS
|
||||
|
@ -656,7 +682,6 @@ struct ath5k_gain {
|
|||
|
||||
/* channel_flags */
|
||||
#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
|
||||
#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
|
||||
#define CHANNEL_CCK 0x0020 /* CCK channel */
|
||||
#define CHANNEL_OFDM 0x0040 /* OFDM channel */
|
||||
#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
|
||||
|
@ -668,16 +693,10 @@ struct ath5k_gain {
|
|||
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
|
||||
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
|
||||
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
|
||||
#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
|
||||
#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
|
||||
#define CHANNEL_108A CHANNEL_T
|
||||
#define CHANNEL_108G CHANNEL_TG
|
||||
#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
|
||||
|
||||
#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
|
||||
CHANNEL_TURBO)
|
||||
#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ)
|
||||
|
||||
#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO)
|
||||
#define CHANNEL_MODES CHANNEL_ALL
|
||||
|
||||
/*
|
||||
|
@ -1026,7 +1045,6 @@ struct ath5k_hw {
|
|||
enum ath5k_int ah_imr;
|
||||
|
||||
struct ieee80211_channel *ah_current_channel;
|
||||
bool ah_turbo;
|
||||
bool ah_calibration;
|
||||
bool ah_single_chip;
|
||||
|
||||
|
@ -1035,6 +1053,7 @@ struct ath5k_hw {
|
|||
u32 ah_phy;
|
||||
u32 ah_mac_srev;
|
||||
u16 ah_mac_version;
|
||||
u16 ah_mac_revision;
|
||||
u16 ah_phy_revision;
|
||||
u16 ah_radio_5ghz_revision;
|
||||
u16 ah_radio_2ghz_revision;
|
||||
|
@ -1044,6 +1063,8 @@ struct ath5k_hw {
|
|||
|
||||
u32 ah_limit_tx_retries;
|
||||
u8 ah_coverage_class;
|
||||
bool ah_ack_bitrate_high;
|
||||
u8 ah_bwmode;
|
||||
|
||||
/* Antenna Control */
|
||||
u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
|
||||
|
@ -1132,36 +1153,50 @@ struct ath5k_hw {
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
extern const struct ieee80211_ops ath5k_hw_ops;
|
||||
|
||||
/* Attach/Detach Functions */
|
||||
int ath5k_hw_attach(struct ath5k_softc *sc);
|
||||
void ath5k_hw_detach(struct ath5k_hw *ah);
|
||||
/* Initialization and detach functions */
|
||||
int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
|
||||
void ath5k_deinit_softc(struct ath5k_softc *sc);
|
||||
int ath5k_hw_init(struct ath5k_softc *sc);
|
||||
void ath5k_hw_deinit(struct ath5k_hw *ah);
|
||||
|
||||
int ath5k_sysfs_register(struct ath5k_softc *sc);
|
||||
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
|
||||
|
||||
/*Chip id helper functions */
|
||||
const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
|
||||
int ath5k_hw_read_srev(struct ath5k_hw *ah);
|
||||
|
||||
/* LED functions */
|
||||
int ath5k_init_leds(struct ath5k_softc *sc);
|
||||
void ath5k_led_enable(struct ath5k_softc *sc);
|
||||
void ath5k_led_off(struct ath5k_softc *sc);
|
||||
void ath5k_unregister_leds(struct ath5k_softc *sc);
|
||||
|
||||
|
||||
/* Reset Functions */
|
||||
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
|
||||
int ath5k_hw_on_hold(struct ath5k_hw *ah);
|
||||
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||
struct ieee80211_channel *channel, bool change_channel);
|
||||
struct ieee80211_channel *channel, bool fast, bool skip_pcu);
|
||||
int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
|
||||
bool is_set);
|
||||
/* Power management functions */
|
||||
|
||||
|
||||
/* Clock rate related functions */
|
||||
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
|
||||
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
|
||||
void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
|
||||
|
||||
|
||||
/* DMA Related Functions */
|
||||
void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
|
||||
int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
|
||||
u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
|
||||
void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
|
||||
int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
|
||||
int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
|
||||
int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
|
||||
int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue);
|
||||
u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
|
||||
int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
|
||||
u32 phys_addr);
|
||||
|
@ -1171,38 +1206,43 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
|
|||
int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
|
||||
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
|
||||
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
|
||||
/* Init/Stop functions */
|
||||
void ath5k_hw_dma_init(struct ath5k_hw *ah);
|
||||
int ath5k_hw_dma_stop(struct ath5k_hw *ah);
|
||||
|
||||
/* EEPROM access functions */
|
||||
int ath5k_eeprom_init(struct ath5k_hw *ah);
|
||||
void ath5k_eeprom_detach(struct ath5k_hw *ah);
|
||||
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
|
||||
|
||||
|
||||
/* Protocol Control Unit Functions */
|
||||
/* Helpers */
|
||||
int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
|
||||
int len, struct ieee80211_rate *rate);
|
||||
unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
|
||||
unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
|
||||
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
|
||||
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
|
||||
/* BSSID Functions */
|
||||
/* RX filter control*/
|
||||
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
|
||||
void ath5k_hw_set_bssid(struct ath5k_hw *ah);
|
||||
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
|
||||
/* Receive start/stop functions */
|
||||
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
|
||||
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
|
||||
/* RX Filter functions */
|
||||
void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
|
||||
u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
|
||||
void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
|
||||
/* Receive (DRU) start/stop functions */
|
||||
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
|
||||
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
|
||||
/* Beacon control functions */
|
||||
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
|
||||
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
|
||||
void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
|
||||
void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
|
||||
bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
|
||||
/* ACK bit rate */
|
||||
void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
|
||||
/* Clock rate related functions */
|
||||
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
|
||||
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
|
||||
void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
|
||||
/* Init function */
|
||||
void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||
u8 mode);
|
||||
|
||||
/* Queue Control Unit, DFS Control Unit Functions */
|
||||
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
|
||||
|
@ -1215,7 +1255,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
|
|||
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
|
||||
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
|
||||
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
|
||||
int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
|
||||
int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time);
|
||||
/* Init function */
|
||||
int ath5k_hw_init_queues(struct ath5k_hw *ah);
|
||||
|
||||
/* Hardware Descriptor Functions */
|
||||
int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
|
||||
|
@ -1225,6 +1267,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
|
|||
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
|
||||
u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
|
||||
|
||||
|
||||
/* GPIO Functions */
|
||||
void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
|
||||
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
|
||||
|
@ -1234,11 +1277,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
|
|||
void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
|
||||
u32 interrupt_level);
|
||||
|
||||
/* rfkill Functions */
|
||||
|
||||
/* RFkill Functions */
|
||||
void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
|
||||
void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
|
||||
|
||||
/* Misc functions */
|
||||
|
||||
/* Misc functions TODO: Cleanup */
|
||||
int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
|
||||
int ath5k_hw_get_capability(struct ath5k_hw *ah,
|
||||
enum ath5k_capability_type cap_type, u32 capability,
|
||||
|
@ -1246,19 +1291,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
|
|||
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
|
||||
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
|
||||
|
||||
|
||||
/* Initial register settings functions */
|
||||
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
|
||||
|
||||
/* Initialize RF */
|
||||
int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel,
|
||||
unsigned int mode);
|
||||
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
|
||||
|
||||
/* PHY functions */
|
||||
/* Misc PHY functions */
|
||||
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
|
||||
int ath5k_hw_phy_disable(struct ath5k_hw *ah);
|
||||
/* Gain_F optimization */
|
||||
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
|
||||
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
|
||||
/* PHY/RF channel functions */
|
||||
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
|
||||
int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
|
||||
/* PHY calibration */
|
||||
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
|
||||
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
|
||||
|
@ -1267,18 +1313,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
|
|||
/* Spur mitigation */
|
||||
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel);
|
||||
void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel);
|
||||
/* Misc PHY functions */
|
||||
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
|
||||
int ath5k_hw_phy_disable(struct ath5k_hw *ah);
|
||||
/* Antenna control */
|
||||
void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
|
||||
void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
|
||||
/* TX power setup */
|
||||
int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
u8 ee_mode, u8 txpower);
|
||||
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
|
||||
/* Init function */
|
||||
int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
u8 mode, u8 ee_mode, u8 freq, bool fast);
|
||||
|
||||
/*
|
||||
* Functions used internaly
|
||||
|
@ -1294,6 +1336,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
|
|||
return &(ath5k_hw_common(ah)->regulatory);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATHEROS_AR231X
|
||||
#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
|
||||
|
||||
static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
|
||||
{
|
||||
/* On AR2315 and AR2317 the PCI clock domain registers
|
||||
* are outside of the WMAC register space */
|
||||
if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
|
||||
(ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
|
||||
return AR5K_AR2315_PCI_BASE + reg;
|
||||
|
||||
return ah->ah_iobase + reg;
|
||||
}
|
||||
|
||||
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
|
||||
{
|
||||
return __raw_readl(ath5k_ahb_reg(ah, reg));
|
||||
}
|
||||
|
||||
static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
|
||||
{
|
||||
__raw_writel(val, ath5k_ahb_reg(ah, reg));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
|
||||
{
|
||||
return ioread32(ah->ah_iobase + reg);
|
||||
|
@ -1304,6 +1372,24 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
|
|||
iowrite32(val, ah->ah_iobase + reg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
|
||||
{
|
||||
return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
|
||||
}
|
||||
|
||||
static inline void ath5k_read_cachesize(struct ath_common *common, int *csz)
|
||||
{
|
||||
common->bus_ops->read_cachesize(common, csz);
|
||||
}
|
||||
|
||||
static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
return common->bus_ops->eeprom_read(common, off, data);
|
||||
}
|
||||
|
||||
static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
|
||||
{
|
||||
u32 retval = 0, bit, i;
|
||||
|
|
|
@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
|||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_attach - Check if hw is supported and init the needed structs
|
||||
* ath5k_hw_init - Check if hw is supported and init the needed structs
|
||||
*
|
||||
* @sc: The &struct ath5k_softc we got from the driver's attach function
|
||||
* @sc: The &struct ath5k_softc we got from the driver's init_softc function
|
||||
*
|
||||
* Check if the device is supported, perform a POST and initialize the needed
|
||||
* structs. Returns -ENOMEM if we don't have memory for the needed structs,
|
||||
* -ENODEV if the device is not supported or prints an error msg if something
|
||||
* else went wrong.
|
||||
*/
|
||||
int ath5k_hw_attach(struct ath5k_softc *sc)
|
||||
int ath5k_hw_init(struct ath5k_softc *sc)
|
||||
{
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
|
@ -115,7 +115,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
* HW information
|
||||
*/
|
||||
ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
|
||||
ah->ah_turbo = false;
|
||||
ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
|
||||
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
|
||||
ah->ah_imr = 0;
|
||||
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
|
||||
|
@ -128,7 +128,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
/*
|
||||
* Find the mac version
|
||||
*/
|
||||
srev = ath5k_hw_reg_read(ah, AR5K_SREV);
|
||||
ath5k_hw_read_srev(ah);
|
||||
srev = ah->ah_mac_srev;
|
||||
if (srev < AR5K_SREV_AR5311)
|
||||
ah->ah_version = AR5K_AR5210;
|
||||
else if (srev < AR5K_SREV_AR5212)
|
||||
|
@ -136,6 +137,10 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
else
|
||||
ah->ah_version = AR5K_AR5212;
|
||||
|
||||
/* Get the MAC revision */
|
||||
ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
|
||||
ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
|
||||
|
||||
/* Fill the ath5k_hw struct with the needed functions */
|
||||
ret = ath5k_hw_init_desc_functions(ah);
|
||||
if (ret)
|
||||
|
@ -146,9 +151,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* Get MAC, PHY and RADIO revisions */
|
||||
ah->ah_mac_srev = srev;
|
||||
ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
|
||||
/* Get PHY and RADIO revisions */
|
||||
ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
|
||||
0xffffffff;
|
||||
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
|
||||
|
@ -273,7 +276,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
/*
|
||||
* Write PCI-E power save settings
|
||||
*/
|
||||
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
|
||||
if ((ah->ah_version == AR5K_AR5212) && pdev && (pdev->is_pcie)) {
|
||||
ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
|
||||
ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
|
||||
|
||||
|
@ -305,8 +308,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
/* Get misc capabilities */
|
||||
ret = ath5k_hw_set_capabilities(ah);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
|
||||
sc->pdev->device);
|
||||
ATH5K_ERR(sc, "unable to get device capabilities\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -346,11 +348,11 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
|
|||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_detach - Free the ath5k_hw struct
|
||||
* ath5k_hw_deinit - Free the ath5k_hw struct
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
void ath5k_hw_detach(struct ath5k_hw *ah)
|
||||
void ath5k_hw_deinit(struct ath5k_hw *ah)
|
||||
{
|
||||
__set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,7 +169,10 @@ struct ath5k_vif {
|
|||
/* Software Carrier, keeps track of the driver state
|
||||
* associated with an instance of a device */
|
||||
struct ath5k_softc {
|
||||
struct pci_dev *pdev; /* for dma mapping */
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev; /* for dma mapping */
|
||||
int irq;
|
||||
u16 devid;
|
||||
void __iomem *iobase; /* address of the device */
|
||||
struct mutex lock; /* dev-level lock */
|
||||
struct ieee80211_hw *hw; /* IEEE 802.11 common */
|
||||
|
|
|
@ -49,7 +49,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
|
|||
|
||||
/* Set supported modes */
|
||||
__set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
|
||||
__set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
|
||||
} else {
|
||||
/*
|
||||
* XXX The tranceiver supports frequencies from 4920 to 6100GHz
|
||||
|
@ -74,11 +73,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
|
|||
/* Set supported modes */
|
||||
__set_bit(AR5K_MODE_11A,
|
||||
ah->ah_capabilities.cap_mode);
|
||||
__set_bit(AR5K_MODE_11A_TURBO,
|
||||
ah->ah_capabilities.cap_mode);
|
||||
if (ah->ah_version == AR5K_AR5212)
|
||||
__set_bit(AR5K_MODE_11G_TURBO,
|
||||
ah->ah_capabilities.cap_mode);
|
||||
}
|
||||
|
||||
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
|
||||
|
|
|
@ -312,6 +312,7 @@ static const struct {
|
|||
{ ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
|
||||
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
|
||||
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
|
||||
{ ATH5K_DEBUG_DMA, "dma", "dma start/stop" },
|
||||
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
|
||||
{ ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
|
||||
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" },
|
||||
|
|
|
@ -95,6 +95,7 @@ struct ath5k_dbg_info {
|
|||
* @ATH5K_DEBUG_DUMP_RX: print received skb content
|
||||
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
|
||||
* @ATH5K_DEBUG_DUMPBANDS: dump bands
|
||||
* @ATH5K_DEBUG_DMA: debug dma start/stop
|
||||
* @ATH5K_DEBUG_TRACE: trace function calls
|
||||
* @ATH5K_DEBUG_DESC: descriptor setup
|
||||
* @ATH5K_DEBUG_ANY: show at any debug level
|
||||
|
@ -118,6 +119,7 @@ enum ath5k_debug_level {
|
|||
ATH5K_DEBUG_DUMP_RX = 0x00000100,
|
||||
ATH5K_DEBUG_DUMP_TX = 0x00000200,
|
||||
ATH5K_DEBUG_DUMPBANDS = 0x00000400,
|
||||
ATH5K_DEBUG_DMA = 0x00000800,
|
||||
ATH5K_DEBUG_ANI = 0x00002000,
|
||||
ATH5K_DEBUG_DESC = 0x00004000,
|
||||
ATH5K_DEBUG_ANY = 0xffffffff
|
||||
|
|
|
@ -26,9 +26,10 @@
|
|||
#include "debug.h"
|
||||
#include "base.h"
|
||||
|
||||
/*
|
||||
* TX Descriptors
|
||||
*/
|
||||
|
||||
/************************\
|
||||
* TX Control descriptors *
|
||||
\************************/
|
||||
|
||||
/*
|
||||
* Initialize the 2-word tx control descriptor on 5210/5211
|
||||
|
@ -335,6 +336,11 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************\
|
||||
* TX Status descriptors *
|
||||
\***********************/
|
||||
|
||||
/*
|
||||
* Proccess the tx status descriptor on 5210/5211
|
||||
*/
|
||||
|
@ -476,9 +482,10 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RX Descriptors
|
||||
*/
|
||||
|
||||
/****************\
|
||||
* RX Descriptors *
|
||||
\****************/
|
||||
|
||||
/*
|
||||
* Initialize an rx control descriptor
|
||||
|
@ -666,6 +673,11 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********\
|
||||
* Attach *
|
||||
\********/
|
||||
|
||||
/*
|
||||
* Init function pointers inside ath5k_hw struct
|
||||
*/
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "debug.h"
|
||||
#include "base.h"
|
||||
|
||||
|
||||
/*********\
|
||||
* Receive *
|
||||
\*********/
|
||||
|
@ -57,7 +58,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
|
|||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
|
||||
static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
@ -69,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
|
|||
for (i = 1000; i > 0 &&
|
||||
(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
|
||||
i--)
|
||||
udelay(10);
|
||||
udelay(100);
|
||||
|
||||
if (i)
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"failed to stop RX DMA !\n");
|
||||
|
||||
return i ? 0 : -EBUSY;
|
||||
}
|
||||
|
@ -90,11 +95,18 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
|
|||
* @ah: The &struct ath5k_hw
|
||||
* @phys_addr: RX descriptor address
|
||||
*
|
||||
* XXX: Should we check if rx is enabled before setting rxdp ?
|
||||
* Returns -EIO if rx is active
|
||||
*/
|
||||
void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
|
||||
int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
|
||||
{
|
||||
if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"tried to set RXDP while rx was active !\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,7 +137,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
|
||||
/* Return if queue is declared inactive */
|
||||
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
|
||||
return -EIO;
|
||||
return -EINVAL;
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
|
@ -173,10 +185,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
*
|
||||
* Stop DMA transmit on a specific hw queue and drain queue so we don't
|
||||
* have any pending frames. Returns -EBUSY if we still have pending frames,
|
||||
* -EINVAL if queue number is out of range.
|
||||
* -EINVAL if queue number is out of range or inactive.
|
||||
*
|
||||
*/
|
||||
int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
||||
static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
unsigned int i = 40;
|
||||
u32 tx_queue, pending;
|
||||
|
@ -185,7 +197,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
|
||||
/* Return if queue is declared inactive */
|
||||
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
|
||||
return -EIO;
|
||||
return -EINVAL;
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
|
@ -211,12 +223,31 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
|
||||
ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Enable DCU early termination to quickly
|
||||
* flush any pending frames from QCU
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_DCU_EARLY);
|
||||
|
||||
/*
|
||||
* Schedule TX disable and wait until queue is empty
|
||||
*/
|
||||
AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
|
||||
|
||||
/*Check for pending frames*/
|
||||
/* Wait for queue to stop */
|
||||
for (i = 1000; i > 0 &&
|
||||
(AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);
|
||||
i--)
|
||||
udelay(100);
|
||||
|
||||
if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"queue %i didn't stop !\n", queue);
|
||||
|
||||
/* Check for pending frames */
|
||||
i = 1000;
|
||||
do {
|
||||
pending = ath5k_hw_reg_read(ah,
|
||||
AR5K_QUEUE_STATUS(queue)) &
|
||||
|
@ -247,12 +278,12 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
|
||||
|
||||
/* Wait a while and disable mechanism */
|
||||
udelay(200);
|
||||
udelay(400);
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
|
||||
AR5K_QUIET_CTL1_QT_EN);
|
||||
|
||||
/* Re-check for pending frames */
|
||||
i = 40;
|
||||
i = 100;
|
||||
do {
|
||||
pending = ath5k_hw_reg_read(ah,
|
||||
AR5K_QUEUE_STATUS(queue)) &
|
||||
|
@ -262,18 +293,53 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
|
|||
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
|
||||
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
|
||||
|
||||
if (pending)
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"quiet mechanism didn't work q:%i !\n",
|
||||
queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable DCU early termination
|
||||
*/
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_DCU_EARLY);
|
||||
|
||||
/* Clear register */
|
||||
ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
|
||||
if (pending)
|
||||
if (pending) {
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"tx dma didn't stop (q:%i, frm:%i) !\n",
|
||||
queue, pending);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Check for success on 5210 else return error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_stop_beacon_queue - Stop beacon queue
|
||||
*
|
||||
* @ah The &struct ath5k_hw
|
||||
* @queue The queue number
|
||||
*
|
||||
* Returns -EIO if queue didn't stop
|
||||
*/
|
||||
int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
int ret;
|
||||
ret = ath5k_hw_stop_tx_dma(ah, queue);
|
||||
if (ret) {
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
|
||||
"beacon queue didn't stop !\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
|
||||
*
|
||||
|
@ -427,6 +493,7 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************\
|
||||
* Interrupt masking *
|
||||
\*******************/
|
||||
|
@ -688,3 +755,92 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
|
|||
return old_mask;
|
||||
}
|
||||
|
||||
|
||||
/********************\
|
||||
Init/Stop functions
|
||||
\********************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_dma_init - Initialize DMA unit
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Set DMA size and pre-enable interrupts
|
||||
* (driver handles tx/rx buffer setup and
|
||||
* dma start/stop)
|
||||
*
|
||||
* XXX: Save/restore RXDP/TXDP registers ?
|
||||
*/
|
||||
void ath5k_hw_dma_init(struct ath5k_hw *ah)
|
||||
{
|
||||
/*
|
||||
* Set Rx/Tx DMA Configuration
|
||||
*
|
||||
* Set standard DMA size (128). Note that
|
||||
* a DMA size of 512 causes rx overruns and tx errors
|
||||
* on pci-e cards (tested on 5424 but since rx overruns
|
||||
* also occur on 5416/5418 with madwifi we set 128
|
||||
* for all PCI-E cards to be safe).
|
||||
*
|
||||
* XXX: need to check 5210 for this
|
||||
* TODO: Check out tx triger level, it's always 64 on dumps but I
|
||||
* guess we can tweak it and see how it goes ;-)
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
|
||||
AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
|
||||
AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
|
||||
}
|
||||
|
||||
/* Pre-enable interrupts on 5211/5212*/
|
||||
if (ah->ah_version != AR5K_AR5210)
|
||||
ath5k_hw_set_imr(ah, ah->ah_imr);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_dma_stop - stop DMA unit
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Stop tx/rx DMA and interrupts. Returns
|
||||
* -EBUSY if tx or rx dma failed to stop.
|
||||
*
|
||||
* XXX: Sometimes DMA unit hangs and we have
|
||||
* stuck frames on tx queues, only a reset
|
||||
* can fix that.
|
||||
*/
|
||||
int ath5k_hw_dma_stop(struct ath5k_hw *ah)
|
||||
{
|
||||
int i, qmax, err;
|
||||
err = 0;
|
||||
|
||||
/* Disable interrupts */
|
||||
ath5k_hw_set_imr(ah, 0);
|
||||
|
||||
/* Stop rx dma */
|
||||
err = ath5k_hw_stop_rx_dma(ah);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Clear any pending interrupts
|
||||
* and disable tx dma */
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
|
||||
qmax = AR5K_NUM_TX_QUEUES;
|
||||
} else {
|
||||
/* PISR/SISR Not available on 5210 */
|
||||
ath5k_hw_reg_read(ah, AR5K_ISR);
|
||||
qmax = AR5K_NUM_TX_QUEUES_NOQCU;
|
||||
}
|
||||
|
||||
for (i = 0; i < qmax; i++) {
|
||||
err = ath5k_hw_stop_tx_dma(ah, i);
|
||||
/* -EINVAL -> queue inactive */
|
||||
if (err != -EINVAL)
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -28,45 +28,16 @@
|
|||
#include "debug.h"
|
||||
#include "base.h"
|
||||
|
||||
/*
|
||||
* Read from eeprom
|
||||
*/
|
||||
static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
|
||||
{
|
||||
u32 status, timeout;
|
||||
|
||||
/*
|
||||
* Initialize EEPROM access
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
|
||||
(void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
|
||||
} else {
|
||||
ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
|
||||
AR5K_EEPROM_CMD_READ);
|
||||
}
|
||||
|
||||
for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
|
||||
status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
|
||||
if (status & AR5K_EEPROM_STAT_RDDONE) {
|
||||
if (status & AR5K_EEPROM_STAT_RDERR)
|
||||
return -EIO;
|
||||
*data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
|
||||
0xffff);
|
||||
return 0;
|
||||
}
|
||||
udelay(15);
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/******************\
|
||||
* Helper functions *
|
||||
\******************/
|
||||
|
||||
/*
|
||||
* Translate binary channel representation in EEPROM to frequency
|
||||
*/
|
||||
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
|
||||
unsigned int mode)
|
||||
unsigned int mode)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
|
@ -89,6 +60,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
|
|||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*********\
|
||||
* Parsers *
|
||||
\*********/
|
||||
|
||||
/*
|
||||
* Initialize eeprom & capabilities structs
|
||||
*/
|
||||
|
@ -198,7 +174,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
|
|||
*
|
||||
* XXX: Serdes values seem to be fixed so
|
||||
* no need to read them here, we write them
|
||||
* during ath5k_hw_attach */
|
||||
* during ath5k_hw_init */
|
||||
AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
|
||||
ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
|
||||
true : false;
|
||||
|
@ -647,6 +623,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read power calibration for RF5111 chips
|
||||
*
|
||||
|
@ -1514,6 +1491,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read per channel calibration info from EEPROM
|
||||
*
|
||||
|
@ -1607,15 +1585,6 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ath5k_eeprom_detach(struct ath5k_hw *ah)
|
||||
{
|
||||
u8 mode;
|
||||
|
||||
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
|
||||
ath5k_eeprom_free_pcal_info(ah, mode);
|
||||
}
|
||||
|
||||
/* Read conformance test limits used for regulatory control */
|
||||
static int
|
||||
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
|
||||
|
@ -1756,6 +1725,44 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the MAC address from eeprom
|
||||
*/
|
||||
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
|
||||
{
|
||||
u8 mac_d[ETH_ALEN] = {};
|
||||
u32 total, offset;
|
||||
u16 data;
|
||||
int octet, ret;
|
||||
|
||||
ret = ath5k_hw_nvram_read(ah, 0x20, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
|
||||
ret = ath5k_hw_nvram_read(ah, offset, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
total += data;
|
||||
mac_d[octet + 1] = data & 0xff;
|
||||
mac_d[octet] = data >> 8;
|
||||
octet += 2;
|
||||
}
|
||||
|
||||
if (!total || total == 3 * 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(mac, mac_d, ETH_ALEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************\
|
||||
* Init/Detach functions *
|
||||
\***********************/
|
||||
|
||||
/*
|
||||
* Initialize eeprom data structure
|
||||
*/
|
||||
|
@ -1787,35 +1794,11 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the MAC address from eeprom
|
||||
*/
|
||||
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
|
||||
void
|
||||
ath5k_eeprom_detach(struct ath5k_hw *ah)
|
||||
{
|
||||
u8 mac_d[ETH_ALEN] = {};
|
||||
u32 total, offset;
|
||||
u16 data;
|
||||
int octet, ret;
|
||||
u8 mode;
|
||||
|
||||
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
|
||||
ret = ath5k_hw_eeprom_read(ah, offset, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
total += data;
|
||||
mac_d[octet + 1] = data & 0xff;
|
||||
mac_d[octet] = data >> 8;
|
||||
octet += 2;
|
||||
}
|
||||
|
||||
if (!total || total == 3 * 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(mac, mac_d, ETH_ALEN);
|
||||
|
||||
return 0;
|
||||
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
|
||||
ath5k_eeprom_free_pcal_info(ah, mode);
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ enum ath5k_eeprom_freq_bands{
|
|||
#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
|
||||
|
||||
#define AR5K_EEPROM_READ(_o, _v) do { \
|
||||
ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
|
||||
ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
|
|
@ -44,7 +44,7 @@ struct ath5k_ini {
|
|||
|
||||
struct ath5k_ini_mode {
|
||||
u16 mode_register;
|
||||
u32 mode_value[5];
|
||||
u32 mode_value[3];
|
||||
};
|
||||
|
||||
/* Initial register settings for AR5210 */
|
||||
|
@ -391,76 +391,74 @@ static const struct ath5k_ini ar5211_ini[] = {
|
|||
*/
|
||||
static const struct ath5k_ini_mode ar5211_ini_mode[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a aTurbo b g (OFDM) */
|
||||
{ 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00000015, 0x0000001d, 0x00000015 } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_DCU_GBL_IFS_SLOT,
|
||||
{ 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
|
||||
{ 0x00000168, 0x000001b8, 0x00000168 } },
|
||||
{ AR5K_DCU_GBL_IFS_SIFS,
|
||||
{ 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
|
||||
{ 0x00000230, 0x000000b0, 0x00000230 } },
|
||||
{ AR5K_DCU_GBL_IFS_EIFS,
|
||||
{ 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
|
||||
{ 0x00000d98, 0x00001f48, 0x00000d98 } },
|
||||
{ AR5K_DCU_GBL_IFS_MISC,
|
||||
{ 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
|
||||
{ 0x0000a0e0, 0x00005880, 0x0000a0e0 } },
|
||||
{ AR5K_TIME_OUT,
|
||||
{ 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
|
||||
{ 0x04000400, 0x20003000, 0x04000400 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
|
||||
{ AR5K_PHY_TURBO,
|
||||
{ 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
|
||||
{ 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } },
|
||||
{ AR5K_PHY(8),
|
||||
{ 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
|
||||
{ AR5K_PHY(9),
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
|
||||
{ AR5K_PHY(10),
|
||||
{ 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
|
||||
{ AR5K_PHY(13),
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY(14),
|
||||
{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY(17),
|
||||
{ 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
|
||||
{ AR5K_PHY(18),
|
||||
{ 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
|
||||
{ AR5K_PHY(20),
|
||||
{ 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
|
||||
{ 0x02020200, 0x02010200, 0x02020200 } },
|
||||
{ AR5K_PHY_RF_CTL2,
|
||||
{ 0x00000e0e, 0x00000707, 0x00000e0e } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x05010000, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000007, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY_SETTLING,
|
||||
{ 0x1372169c, 0x137216a8, 0x1372169c } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
|
||||
{ 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
|
||||
{ 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
|
||||
{ AR5K_PHY_AGCCTL,
|
||||
{ 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
|
||||
{ 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
|
||||
{ AR5K_PHY_NF,
|
||||
{ 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
|
||||
{ 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
|
||||
{ 0x00002710, 0x0000157c, 0x00002710 } },
|
||||
{ AR5K_PHY(70),
|
||||
{ 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
|
||||
{ 0x00000190, 0x00000084, 0x00000190 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
|
||||
{ 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
|
||||
{ AR5K_PHY_PCDAC_TXPOWER_BASE,
|
||||
{ 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
|
||||
{ 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
|
||||
{ AR5K_RF_BUFFER_CONTROL_4,
|
||||
{ 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
|
||||
{ 0x00000010, 0x00000010, 0x00000010 } },
|
||||
};
|
||||
|
||||
/* Initial register settings for AR5212 */
|
||||
|
@ -677,89 +675,87 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
|
|||
/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
|
||||
static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
/* A/XR B G */
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
|
||||
{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
|
||||
{ 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
|
||||
{ AR5K_DCU_GBL_IFS_SIFS,
|
||||
{ 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
|
||||
{ 0x00000230, 0x000000b0, 0x00000160 } },
|
||||
{ AR5K_DCU_GBL_IFS_SLOT,
|
||||
{ 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
|
||||
{ 0x00000168, 0x000001b8, 0x0000018c } },
|
||||
{ AR5K_DCU_GBL_IFS_EIFS,
|
||||
{ 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
|
||||
{ 0x00000e60, 0x00001f1c, 0x00003e38 } },
|
||||
{ AR5K_DCU_GBL_IFS_MISC,
|
||||
{ 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
|
||||
{ 0x0000a0e0, 0x00005880, 0x0000b0e0 } },
|
||||
{ AR5K_TIME_OUT,
|
||||
{ 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
|
||||
{ AR5K_PHY_TURBO,
|
||||
{ 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
|
||||
{ 0x03e803e8, 0x04200420, 0x08400840 } },
|
||||
{ AR5K_PHY(8),
|
||||
{ 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
|
||||
{ 0x02020200, 0x02010200, 0x02020200 } },
|
||||
{ AR5K_PHY_RF_CTL2,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
|
||||
{ 0x00000e0e, 0x00000707, 0x00000e0e } },
|
||||
{ AR5K_PHY_SETTLING,
|
||||
{ 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
|
||||
{ 0x1372161c, 0x13721722, 0x137216a2 } },
|
||||
{ AR5K_PHY_AGCCTL,
|
||||
{ 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
|
||||
{ 0x00009d10, 0x00009d18, 0x00009d18 } },
|
||||
{ AR5K_PHY_NF,
|
||||
{ 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
|
||||
{ 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
|
||||
{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
|
||||
{ 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
|
||||
{ 0x409a4190, 0x409a4190, 0x409a4190 } },
|
||||
{ AR5K_PHY(70),
|
||||
{ 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
|
||||
{ 0x000001b8, 0x00000084, 0x00000108 } },
|
||||
{ AR5K_PHY_OFDM_SELFCORR,
|
||||
{ 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
|
||||
{ 0x10058a05, 0x10058a05, 0x10058a05 } },
|
||||
{ 0xa230,
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
|
||||
{ 0x00000000, 0x00000000, 0x00000108 } },
|
||||
};
|
||||
|
||||
/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
|
||||
static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00008015, 0x00008015, 0x00008015 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
|
||||
{ 0x128d8fa7, 0x04e00f95, 0x12e00fab } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
|
||||
{ 0x0a020001, 0x05010100, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
|
||||
{ 0x00000007, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
|
||||
{ 0x0018da5a, 0x0018ca69, 0x0018ca69 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
|
||||
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
|
||||
{ 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
|
||||
{ 0x3137665e, 0x3137665e, 0x3137665e } },
|
||||
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb080 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
|
||||
{ 0x00002710, 0x0000157c, 0x00002af8 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
|
||||
{ 0xf7b81020, 0xf7b80d20, 0xf7b81020 } },
|
||||
{ AR5K_PHY_GAIN_2GHZ,
|
||||
{ 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
|
||||
{ 0x642c416a, 0x6440416a, 0x6440416a } },
|
||||
{ AR5K_PHY_CCK_RX_CTL_4,
|
||||
{ 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
|
||||
{ 0x1883800a, 0x1873800a, 0x1883800a } },
|
||||
};
|
||||
|
||||
static const struct ath5k_ini rf5111_ini_common_end[] = {
|
||||
|
@ -782,38 +778,38 @@ static const struct ath5k_ini rf5111_ini_common_end[] = {
|
|||
/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
|
||||
static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00008015, 0x00008015, 0x00008015 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
|
||||
{ 0x128d93a7, 0x04e01395, 0x12e013ab } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
|
||||
{ 0x0a020001, 0x05020100, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
|
||||
{ 0x00000007, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
|
||||
{ 0x0018da6d, 0x0018ca75, 0x0018ca75 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
|
||||
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
|
||||
{ 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
|
||||
{ 0x3137665e, 0x3137665e, 0x3137665e } },
|
||||
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
|
||||
{ 0x000007d0, 0x0000044c, 0x00000898 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
|
||||
{ 0xf7b81020, 0xf7b80d10, 0xf7b81010 } },
|
||||
{ AR5K_PHY_CCKTXCTL,
|
||||
{ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
|
||||
{ 0x00000000, 0x00000008, 0x00000008 } },
|
||||
{ AR5K_PHY_CCK_CROSSCORR,
|
||||
{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ AR5K_PHY_GAIN_2GHZ,
|
||||
{ 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
|
||||
{ 0x642c0140, 0x6442c160, 0x6442c160 } },
|
||||
{ AR5K_PHY_CCK_RX_CTL_4,
|
||||
{ 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
|
||||
{ 0x1883800a, 0x1873800a, 0x1883800a } },
|
||||
};
|
||||
|
||||
static const struct ath5k_ini rf5112_ini_common_end[] = {
|
||||
|
@ -833,66 +829,66 @@ static const struct ath5k_ini rf5112_ini_common_end[] = {
|
|||
/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
|
||||
static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00000015, 0x00000015, 0x00000015 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
|
||||
{ 0x128d93a7, 0x04e01395, 0x12e013ab } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
|
||||
{ 0x0a020001, 0x05020100, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
|
||||
{ 0x00000007, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
|
||||
{ 0x0018fa61, 0x001a1a63, 0x001a1a63 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
|
||||
{ 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
|
||||
{ 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
|
||||
{ 0x3139605e, 0x3139605e, 0x3139605e } },
|
||||
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
|
||||
{ 0x000007d0, 0x0000044c, 0x00000898 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
|
||||
{ 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
|
||||
{ AR5K_PHY_CCKTXCTL,
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ AR5K_PHY_CCK_CROSSCORR,
|
||||
{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ AR5K_PHY_GAIN_2GHZ,
|
||||
{ 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
|
||||
{ 0x002ec1e0, 0x002ac120, 0x002ac120 } },
|
||||
{ AR5K_PHY_CCK_RX_CTL_4,
|
||||
{ 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
|
||||
{ 0x1883800a, 0x1863800a, 0x1883800a } },
|
||||
{ 0xa300,
|
||||
{ 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
|
||||
{ 0x18010000, 0x18010000, 0x18010000 } },
|
||||
{ 0xa304,
|
||||
{ 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
|
||||
{ 0x30032602, 0x30032602, 0x30032602 } },
|
||||
{ 0xa308,
|
||||
{ 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
|
||||
{ 0x48073e06, 0x48073e06, 0x48073e06 } },
|
||||
{ 0xa30c,
|
||||
{ 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
|
||||
{ 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
|
||||
{ 0xa310,
|
||||
{ 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
|
||||
{ 0x641a600f, 0x641a600f, 0x641a600f } },
|
||||
{ 0xa314,
|
||||
{ 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
|
||||
{ 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
|
||||
{ 0xa318,
|
||||
{ 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
|
||||
{ 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
|
||||
{ 0xa31c,
|
||||
{ 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
|
||||
{ 0x90cf865b, 0x8ecf865b, 0x8ecf865b } },
|
||||
{ 0xa320,
|
||||
{ 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
|
||||
{ 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } },
|
||||
{ 0xa324,
|
||||
{ 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
|
||||
{ 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } },
|
||||
{ 0xa328,
|
||||
{ 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
|
||||
{ 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } },
|
||||
{ 0xa32c,
|
||||
{ 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
|
||||
{ 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } },
|
||||
{ 0xa330,
|
||||
{ 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
|
||||
{ 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } },
|
||||
{ 0xa334,
|
||||
{ 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
|
||||
{ 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
|
||||
};
|
||||
|
||||
static const struct ath5k_ini rf5413_ini_common_end[] = {
|
||||
|
@ -972,38 +968,38 @@ static const struct ath5k_ini rf5413_ini_common_end[] = {
|
|||
/* XXX: a mode ? */
|
||||
static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00000015, 0x00000015, 0x00000015 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
|
||||
{ 0x128d93a7, 0x04e01395, 0x12e013ab } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
|
||||
{ 0x0a020001, 0x05020000, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
|
||||
{ 0x00000e00, 0x00000e00, 0x00000e00 } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
|
||||
{ 0x00000002, 0x0000000a, 0x0000000a } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
|
||||
{ 0x0018da6d, 0x001a6a64, 0x001a6a64 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
|
||||
{ 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
|
||||
{ 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
|
||||
{ 0x3137665e, 0x3137665e, 0x3139605e } },
|
||||
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
|
||||
{ 0x000007d0, 0x0000044c, 0x00000898 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
|
||||
{ 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
|
||||
{ AR5K_PHY_CCKTXCTL,
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ AR5K_PHY_CCK_CROSSCORR,
|
||||
{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ AR5K_PHY_GAIN_2GHZ,
|
||||
{ 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
|
||||
{ 0x002c0140, 0x0042c140, 0x0042c140 } },
|
||||
{ AR5K_PHY_CCK_RX_CTL_4,
|
||||
{ 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
|
||||
{ 0x1883800a, 0x1863800a, 0x1883800a } },
|
||||
};
|
||||
|
||||
static const struct ath5k_ini rf2413_ini_common_end[] = {
|
||||
|
@ -1094,52 +1090,50 @@ static const struct ath5k_ini rf2413_ini_common_end[] = {
|
|||
/* XXX: a mode ? */
|
||||
static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
|
||||
{ AR5K_TXCFG,
|
||||
/* a/XR aTurbo b g (DYN) gTurbo */
|
||||
{ 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
|
||||
/* A/XR B G */
|
||||
{ 0x00000015, 0x00000015, 0x00000015 } },
|
||||
{ AR5K_USEC_5211,
|
||||
{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
|
||||
{ AR5K_PHY_TURBO,
|
||||
{ 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
|
||||
{ 0x128d93a7, 0x04e01395, 0x12e013ab } },
|
||||
{ AR5K_PHY_RF_CTL3,
|
||||
{ 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
|
||||
{ 0x0a020001, 0x05020100, 0x0a020001 } },
|
||||
{ AR5K_PHY_RF_CTL4,
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
|
||||
{ AR5K_PHY_PA_CTL,
|
||||
{ 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
|
||||
{ 0x00000003, 0x0000000b, 0x0000000b } },
|
||||
{ AR5K_PHY_SETTLING,
|
||||
{ 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
|
||||
{ 0x1372161c, 0x13721722, 0x13721422 } },
|
||||
{ AR5K_PHY_GAIN,
|
||||
{ 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
|
||||
{ 0x0018fa61, 0x00199a65, 0x00199a65 } },
|
||||
{ AR5K_PHY_DESIRED_SIZE,
|
||||
{ 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
|
||||
{ 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
|
||||
{ AR5K_PHY_SIG,
|
||||
{ 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
|
||||
{ 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
|
||||
{ AR5K_PHY_AGCCOARSE,
|
||||
{ 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
|
||||
{ 0x3139605e, 0x3139605e, 0x3139605e } },
|
||||
{ AR5K_PHY_WEAK_OFDM_LOW_THR,
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ 0x050cb081, 0x050cb081, 0x050cb081 } },
|
||||
{ AR5K_PHY_RX_DELAY,
|
||||
{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
|
||||
{ 0x000007d0, 0x0000044c, 0x00000898 } },
|
||||
{ AR5K_PHY_FRAME_CTL_5211,
|
||||
{ 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
|
||||
{ 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
|
||||
{ AR5K_PHY_CCKTXCTL,
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ 0x00000000, 0x00000000, 0x00000000 } },
|
||||
{ AR5K_PHY_CCK_CROSSCORR,
|
||||
{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
|
||||
{ AR5K_PHY_GAIN_2GHZ,
|
||||
{ 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
|
||||
{ 0x00000140, 0x0052c140, 0x0052c140 } },
|
||||
{ AR5K_PHY_CCK_RX_CTL_4,
|
||||
{ 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
|
||||
{ 0x1883800a, 0x1863800a, 0x1883800a } },
|
||||
{ 0xa324,
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa328,
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa32c,
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa330,
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa334,
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
{ 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
|
||||
};
|
||||
|
||||
static const struct ath5k_ini rf2425_ini_common_end[] = {
|
||||
|
@ -1368,15 +1362,15 @@ static const struct ath5k_ini rf5112_ini_bbgain[] = {
|
|||
* Write initial register dump
|
||||
*/
|
||||
static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
|
||||
const struct ath5k_ini *ini_regs, bool change_channel)
|
||||
const struct ath5k_ini *ini_regs, bool skip_pcu)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Write initial registers */
|
||||
for (i = 0; i < size; i++) {
|
||||
/* On channel change there is
|
||||
* no need to mess with PCU */
|
||||
if (change_channel &&
|
||||
/* Skip PCU registers if
|
||||
* requested */
|
||||
if (skip_pcu &&
|
||||
ini_regs[i].ini_register >= AR5K_PCU_MIN &&
|
||||
ini_regs[i].ini_register <= AR5K_PCU_MAX)
|
||||
continue;
|
||||
|
@ -1409,7 +1403,7 @@ static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
|
|||
|
||||
}
|
||||
|
||||
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
||||
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
|
||||
{
|
||||
/*
|
||||
* Write initial register settings
|
||||
|
@ -1427,7 +1421,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
* Write initial settings common for all modes
|
||||
*/
|
||||
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
|
||||
ar5212_ini_common_start, change_channel);
|
||||
ar5212_ini_common_start, skip_pcu);
|
||||
|
||||
/* Second set of mode-specific settings */
|
||||
switch (ah->ah_radio) {
|
||||
|
@ -1439,12 +1433,12 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5111_ini_common_end),
|
||||
rf5111_ini_common_end, change_channel);
|
||||
rf5111_ini_common_end, skip_pcu);
|
||||
|
||||
/* Baseband gain table */
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5111_ini_bbgain),
|
||||
rf5111_ini_bbgain, change_channel);
|
||||
rf5111_ini_bbgain, skip_pcu);
|
||||
|
||||
break;
|
||||
case AR5K_RF5112:
|
||||
|
@ -1455,11 +1449,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_common_end),
|
||||
rf5112_ini_common_end, change_channel);
|
||||
rf5112_ini_common_end, skip_pcu);
|
||||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_bbgain),
|
||||
rf5112_ini_bbgain, change_channel);
|
||||
rf5112_ini_bbgain, skip_pcu);
|
||||
|
||||
break;
|
||||
case AR5K_RF5413:
|
||||
|
@ -1470,11 +1464,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5413_ini_common_end),
|
||||
rf5413_ini_common_end, change_channel);
|
||||
rf5413_ini_common_end, skip_pcu);
|
||||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_bbgain),
|
||||
rf5112_ini_bbgain, change_channel);
|
||||
rf5112_ini_bbgain, skip_pcu);
|
||||
|
||||
break;
|
||||
case AR5K_RF2316:
|
||||
|
@ -1486,7 +1480,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf2413_ini_common_end),
|
||||
rf2413_ini_common_end, change_channel);
|
||||
rf2413_ini_common_end, skip_pcu);
|
||||
|
||||
/* Override settings from rf2413_ini_common_end */
|
||||
if (ah->ah_radio == AR5K_RF2316) {
|
||||
|
@ -1498,9 +1492,32 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_bbgain),
|
||||
rf5112_ini_bbgain, change_channel);
|
||||
rf5112_ini_bbgain, skip_pcu);
|
||||
break;
|
||||
case AR5K_RF2317:
|
||||
|
||||
ath5k_hw_ini_mode_registers(ah,
|
||||
ARRAY_SIZE(rf2413_ini_mode_end),
|
||||
rf2413_ini_mode_end, mode);
|
||||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf2425_ini_common_end),
|
||||
rf2425_ini_common_end, skip_pcu);
|
||||
|
||||
/* Override settings from rf2413_ini_mode_end */
|
||||
ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN);
|
||||
|
||||
/* Override settings from rf2413_ini_common_end */
|
||||
ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC);
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5,
|
||||
AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa);
|
||||
ath5k_hw_reg_write(ah, 0x800000a8, 0x8140);
|
||||
ath5k_hw_reg_write(ah, 0x000000ff, 0x9958);
|
||||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_bbgain),
|
||||
rf5112_ini_bbgain, skip_pcu);
|
||||
break;
|
||||
case AR5K_RF2425:
|
||||
|
||||
ath5k_hw_ini_mode_registers(ah,
|
||||
|
@ -1509,11 +1526,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf2425_ini_common_end),
|
||||
rf2425_ini_common_end, change_channel);
|
||||
rf2425_ini_common_end, skip_pcu);
|
||||
|
||||
ath5k_hw_ini_registers(ah,
|
||||
ARRAY_SIZE(rf5112_ini_bbgain),
|
||||
rf5112_ini_bbgain, change_channel);
|
||||
rf5112_ini_bbgain, skip_pcu);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -1538,17 +1555,17 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
|
|||
* Write initial settings common for all modes
|
||||
*/
|
||||
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
|
||||
ar5211_ini, change_channel);
|
||||
ar5211_ini, skip_pcu);
|
||||
|
||||
/* AR5211 only comes with 5111 */
|
||||
|
||||
/* Baseband gain table */
|
||||
ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
|
||||
rf5111_ini_bbgain, change_channel);
|
||||
rf5111_ini_bbgain, skip_pcu);
|
||||
/* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
|
||||
} else if (ah->ah_version == AR5K_AR5210) {
|
||||
ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
|
||||
ar5210_ini, change_channel);
|
||||
ar5210_ini, skip_pcu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -133,7 +133,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
|
|||
led->led_dev.default_trigger = trigger;
|
||||
led->led_dev.brightness_set = ath5k_led_brightness_set;
|
||||
|
||||
err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
|
||||
err = led_classdev_register(sc->dev, &led->led_dev);
|
||||
if (err) {
|
||||
ATH5K_WARN(sc, "could not register LED %s\n", name);
|
||||
led->sc = NULL;
|
||||
|
@ -161,11 +161,20 @@ int ath5k_init_leds(struct ath5k_softc *sc)
|
|||
{
|
||||
int ret = 0;
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
#ifndef CONFIG_ATHEROS_AR231X
|
||||
struct pci_dev *pdev = sc->pdev;
|
||||
#endif
|
||||
char name[ATH5K_LED_MAX_NAME_LEN + 1];
|
||||
const struct pci_device_id *match;
|
||||
|
||||
if (!sc->pdev)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_ATHEROS_AR231X
|
||||
match = NULL;
|
||||
#else
|
||||
match = pci_match_id(&ath5k_led_devices[0], pdev);
|
||||
#endif
|
||||
if (match) {
|
||||
__set_bit(ATH_STAT_LEDSOFT, sc->status);
|
||||
sc->led_pin = ATH_PIN(match->driver_data);
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 Atheros Communications Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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/nl80211.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
#include "../ath.h"
|
||||
#include "ath5k.h"
|
||||
#include "debug.h"
|
||||
#include "base.h"
|
||||
#include "reg.h"
|
||||
|
||||
/* Known PCI ids */
|
||||
static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
|
||||
{ PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
|
||||
{ PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* return bus cachesize in 4B word units */
|
||||
static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
|
||||
{
|
||||
struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;
|
||||
u8 u8tmp;
|
||||
|
||||
pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
|
||||
*csz = (int)u8tmp;
|
||||
|
||||
/*
|
||||
* This check was put in to avoid "unplesant" consequences if
|
||||
* the bootrom has not fully initialized all PCI devices.
|
||||
* Sometimes the cache line size register is not set
|
||||
*/
|
||||
|
||||
if (*csz == 0)
|
||||
*csz = L1_CACHE_BYTES >> 2; /* Use the default size */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from eeprom
|
||||
*/
|
||||
bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
|
||||
{
|
||||
struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
|
||||
u32 status, timeout;
|
||||
|
||||
/*
|
||||
* Initialize EEPROM access
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
|
||||
(void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
|
||||
} else {
|
||||
ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
|
||||
AR5K_EEPROM_CMD_READ);
|
||||
}
|
||||
|
||||
for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
|
||||
status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
|
||||
if (status & AR5K_EEPROM_STAT_RDDONE) {
|
||||
if (status & AR5K_EEPROM_STAT_RDERR)
|
||||
return -EIO;
|
||||
*data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
|
||||
0xffff);
|
||||
return 0;
|
||||
}
|
||||
udelay(15);
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int ath5k_hw_read_srev(struct ath5k_hw *ah)
|
||||
{
|
||||
ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Common ath_bus_opts structure */
|
||||
static const struct ath_bus_ops ath_pci_bus_ops = {
|
||||
.ath_bus_type = ATH_PCI,
|
||||
.read_cachesize = ath5k_pci_read_cachesize,
|
||||
.eeprom_read = ath5k_pci_eeprom_read,
|
||||
};
|
||||
|
||||
/********************\
|
||||
* PCI Initialization *
|
||||
\********************/
|
||||
|
||||
static int __devinit
|
||||
ath5k_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
void __iomem *mem;
|
||||
struct ath5k_softc *sc;
|
||||
struct ieee80211_hw *hw;
|
||||
int ret;
|
||||
u8 csz;
|
||||
|
||||
/*
|
||||
* L0s needs to be disabled on all ath5k cards.
|
||||
*
|
||||
* For distributions shipping with CONFIG_PCIEASPM (this will be enabled
|
||||
* by default in the future in 2.6.36) this will also mean both L1 and
|
||||
* L0s will be disabled when a pre 1.1 PCIe device is detected. We do
|
||||
* know L1 works correctly even for all ath5k pre 1.1 PCIe devices
|
||||
* though but cannot currently undue the effect of a blacklist, for
|
||||
* details you can read pcie_aspm_sanity_check() and see how it adjusts
|
||||
* the device link capability.
|
||||
*
|
||||
* It may be possible in the future to implement some PCI API to allow
|
||||
* drivers to override blacklists for pre 1.1 PCIe but for now it is
|
||||
* best to accept that both L0s and L1 will be disabled completely for
|
||||
* distributions shipping with CONFIG_PCIEASPM rather than having this
|
||||
* issue present. Motivation for adding this new API will be to help
|
||||
* with power consumption for some of these devices.
|
||||
*/
|
||||
pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't enable device\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* XXX 32-bit addressing only */
|
||||
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "32-bit DMA not available\n");
|
||||
goto err_dis;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache line size is used to size and align various
|
||||
* structures used to communicate with the hardware.
|
||||
*/
|
||||
pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
|
||||
if (csz == 0) {
|
||||
/*
|
||||
* Linux 2.4.18 (at least) writes the cache line size
|
||||
* register as a 16-bit wide register which is wrong.
|
||||
* We must have this setup properly for rx buffer
|
||||
* DMA to work so force a reasonable value here if it
|
||||
* comes up zero.
|
||||
*/
|
||||
csz = L1_CACHE_BYTES >> 2;
|
||||
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
|
||||
}
|
||||
/*
|
||||
* The default setting of latency timer yields poor results,
|
||||
* set it to the value used by other systems. It may be worth
|
||||
* tweaking this setting more.
|
||||
*/
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
|
||||
|
||||
/* Enable bus mastering */
|
||||
pci_set_master(pdev);
|
||||
|
||||
/*
|
||||
* Disable the RETRY_TIMEOUT register (0x41) to keep
|
||||
* PCI Tx retries from interfering with C3 CPU state.
|
||||
*/
|
||||
pci_write_config_byte(pdev, 0x41, 0);
|
||||
|
||||
ret = pci_request_region(pdev, 0, "ath5k");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
|
||||
goto err_dis;
|
||||
}
|
||||
|
||||
mem = pci_iomap(pdev, 0, 0);
|
||||
if (!mem) {
|
||||
dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
|
||||
ret = -EIO;
|
||||
goto err_reg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate hw (mac80211 main struct)
|
||||
* and hw->priv (driver private data)
|
||||
*/
|
||||
hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
|
||||
if (hw == NULL) {
|
||||
dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_map;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
|
||||
|
||||
sc = hw->priv;
|
||||
sc->hw = hw;
|
||||
sc->pdev = pdev;
|
||||
sc->dev = &pdev->dev;
|
||||
sc->irq = pdev->irq;
|
||||
sc->devid = id->device;
|
||||
sc->iobase = mem; /* So we can unmap it on detach */
|
||||
|
||||
/* Initialize */
|
||||
ret = ath5k_init_softc(sc, &ath_pci_bus_ops);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
/* Set private data */
|
||||
pci_set_drvdata(pdev, hw);
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
ieee80211_free_hw(hw);
|
||||
err_map:
|
||||
pci_iounmap(pdev, mem);
|
||||
err_reg:
|
||||
pci_release_region(pdev, 0);
|
||||
err_dis:
|
||||
pci_disable_device(pdev);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __devexit
|
||||
ath5k_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
|
||||
ath5k_deinit_softc(sc);
|
||||
pci_iounmap(pdev, sc->iobase);
|
||||
pci_release_region(pdev, 0);
|
||||
pci_disable_device(pdev);
|
||||
ieee80211_free_hw(hw);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ath5k_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
|
||||
|
||||
ath5k_led_off(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath5k_pci_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct ath5k_softc *sc = pci_get_drvdata(pdev);
|
||||
|
||||
/*
|
||||
* Suspend/Resume resets the PCI configuration space, so we have to
|
||||
* re-disable the RETRY_TIMEOUT register (0x41) to keep
|
||||
* PCI Tx retries from interfering with C3 CPU state
|
||||
*/
|
||||
pci_write_config_byte(pdev, 0x41, 0);
|
||||
|
||||
ath5k_led_enable(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
|
||||
#define ATH5K_PM_OPS (&ath5k_pm_ops)
|
||||
#else
|
||||
#define ATH5K_PM_OPS NULL
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static struct pci_driver ath5k_pci_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = ath5k_pci_id_table,
|
||||
.probe = ath5k_pci_probe,
|
||||
.remove = __devexit_p(ath5k_pci_remove),
|
||||
.driver.pm = ATH5K_PM_OPS,
|
||||
};
|
||||
|
||||
/*
|
||||
* Module init/exit functions
|
||||
*/
|
||||
static int __init
|
||||
init_ath5k_pci(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pci_register_driver(&ath5k_pci_driver);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
exit_ath5k_pci(void)
|
||||
{
|
||||
pci_unregister_driver(&ath5k_pci_driver);
|
||||
}
|
||||
|
||||
module_init(init_ath5k_pci);
|
||||
module_exit(exit_ath5k_pci);
|
|
@ -31,87 +31,163 @@
|
|||
#include "debug.h"
|
||||
#include "base.h"
|
||||
|
||||
/*
|
||||
* AR5212+ can use higher rates for ack transmition
|
||||
* based on current tx rate instead of the base rate.
|
||||
* It does this to better utilize channel usage.
|
||||
* This is a mapping between G rates (that cover both
|
||||
* CCK and OFDM) and ack rates that we use when setting
|
||||
* rate -> duration table. This mapping is hw-based so
|
||||
* don't change anything.
|
||||
*
|
||||
* To enable this functionality we must set
|
||||
* ah->ah_ack_bitrate_high to true else base rate is
|
||||
* used (1Mb for CCK, 6Mb for OFDM).
|
||||
*/
|
||||
static const unsigned int ack_rates_high[] =
|
||||
/* Tx -> ACK */
|
||||
/* 1Mb -> 1Mb */ { 0,
|
||||
/* 2MB -> 2Mb */ 1,
|
||||
/* 5.5Mb -> 2Mb */ 1,
|
||||
/* 11Mb -> 2Mb */ 1,
|
||||
/* 6Mb -> 6Mb */ 4,
|
||||
/* 9Mb -> 6Mb */ 4,
|
||||
/* 12Mb -> 12Mb */ 6,
|
||||
/* 18Mb -> 12Mb */ 6,
|
||||
/* 24Mb -> 24Mb */ 8,
|
||||
/* 36Mb -> 24Mb */ 8,
|
||||
/* 48Mb -> 24Mb */ 8,
|
||||
/* 54Mb -> 24Mb */ 8 };
|
||||
|
||||
/*******************\
|
||||
* Generic functions *
|
||||
* Helper functions *
|
||||
\*******************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_opmode - Set PCU operating mode
|
||||
* ath5k_hw_get_frame_duration - Get tx time of a frame
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
* @op_mode: &enum nl80211_iftype operating mode
|
||||
* @len: Frame's length in bytes
|
||||
* @rate: The @struct ieee80211_rate
|
||||
*
|
||||
* Initialize PCU for the various operating modes (AP/STA etc)
|
||||
* Calculate tx duration of a frame given it's rate and length
|
||||
* It extends ieee80211_generic_frame_duration for non standard
|
||||
* bwmodes.
|
||||
*/
|
||||
int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
|
||||
int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
|
||||
int len, struct ieee80211_rate *rate)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
u32 pcu_reg, beacon_reg, low_id, high_id;
|
||||
struct ath5k_softc *sc = ah->ah_sc;
|
||||
int sifs, preamble, plcp_bits, sym_time;
|
||||
int bitrate, bits, symbols, symbol_bits;
|
||||
int dur;
|
||||
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
|
||||
|
||||
/* Preserve rest settings */
|
||||
pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
|
||||
pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
|
||||
| AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
(AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
|
||||
|
||||
beacon_reg = 0;
|
||||
|
||||
switch (op_mode) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
|
||||
beacon_reg |= AR5K_BCR_ADHOC;
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
|
||||
else
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
|
||||
beacon_reg |= AR5K_BCR_AP;
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
|
||||
else
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_STATION:
|
||||
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
AR5K_STA_ID1_PWR_SV : 0);
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
AR5K_STA_ID1_NO_PSPOLL : 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
/* Fallback */
|
||||
if (!ah->ah_bwmode) {
|
||||
dur = ieee80211_generic_frame_duration(sc->hw,
|
||||
NULL, len, rate);
|
||||
return dur;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set PCU registers
|
||||
*/
|
||||
low_id = get_unaligned_le32(common->macaddr);
|
||||
high_id = get_unaligned_le16(common->macaddr + 4);
|
||||
ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
|
||||
ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
|
||||
bitrate = rate->bitrate;
|
||||
preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
|
||||
plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
|
||||
sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
|
||||
|
||||
/*
|
||||
* Set Beacon Control Register on 5210
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_40MHZ:
|
||||
sifs = AR5K_INIT_SIFS_TURBO;
|
||||
preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
sifs = AR5K_INIT_SIFS_HALF_RATE;
|
||||
preamble *= 2;
|
||||
sym_time *= 2;
|
||||
break;
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
sifs = AR5K_INIT_SIFS_QUARTER_RATE;
|
||||
preamble *= 4;
|
||||
sym_time *= 4;
|
||||
break;
|
||||
default:
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
bits = plcp_bits + (len << 3);
|
||||
/* Bit rate is in 100Kbits */
|
||||
symbol_bits = bitrate * sym_time;
|
||||
symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
|
||||
|
||||
dur = sifs + preamble + (sym_time * symbols);
|
||||
|
||||
return dur;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_update - Update MIB counters (mac layer statistics)
|
||||
* ath5k_hw_get_default_slottime - Get the default slot time for current mode
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
unsigned int slot_time;
|
||||
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_40MHZ:
|
||||
slot_time = AR5K_INIT_SLOT_TIME_TURBO;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
|
||||
break;
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
|
||||
break;
|
||||
case AR5K_BWMODE_DEFAULT:
|
||||
slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
|
||||
default:
|
||||
if (channel->hw_value & CHANNEL_CCK)
|
||||
slot_time = AR5K_INIT_SLOT_TIME_B;
|
||||
break;
|
||||
}
|
||||
|
||||
return slot_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_get_default_sifs - Get the default SIFS for current mode
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
unsigned int sifs;
|
||||
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_40MHZ:
|
||||
sifs = AR5K_INIT_SIFS_TURBO;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
sifs = AR5K_INIT_SIFS_HALF_RATE;
|
||||
break;
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
sifs = AR5K_INIT_SIFS_QUARTER_RATE;
|
||||
break;
|
||||
case AR5K_BWMODE_DEFAULT:
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
|
||||
default:
|
||||
if (channel->hw_value & CHANNEL_5GHZ)
|
||||
sifs = AR5K_INIT_SIFS_DEFAULT_A;
|
||||
break;
|
||||
}
|
||||
|
||||
return sifs;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
|
@ -133,36 +209,88 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
|
|||
stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_ack_bitrate - set bitrate for ACKs
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
* @high: Flag to determine if we want to use high transmission rate
|
||||
* for ACKs or not
|
||||
*
|
||||
* If high flag is set, we tell hw to use a set of control rates based on
|
||||
* the current transmission rate (check out control_rates array inside reset.c).
|
||||
* If not hw just uses the lowest rate available for the current modulation
|
||||
* scheme being used (1Mbit for CCK and 6Mbits for OFDM).
|
||||
*/
|
||||
void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
|
||||
{
|
||||
if (ah->ah_version != AR5K_AR5212)
|
||||
return;
|
||||
else {
|
||||
u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
|
||||
if (high)
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
|
||||
else
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************\
|
||||
* ACK/CTS Timeouts *
|
||||
\******************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_write_rate_duration - fill rate code to duration table
|
||||
*
|
||||
* @ah: the &struct ath5k_hw
|
||||
* @mode: one of enum ath5k_driver_mode
|
||||
*
|
||||
* Write the rate code to duration table upon hw reset. This is a helper for
|
||||
* ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on
|
||||
* the hardware, based on current mode, for each rate. The rates which are
|
||||
* capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
|
||||
* different rate code so we write their value twice (one for long preamble
|
||||
* and one for short).
|
||||
*
|
||||
* Note: Band doesn't matter here, if we set the values for OFDM it works
|
||||
* on both a and g modes. So all we have to do is set values for all g rates
|
||||
* that include all OFDM and CCK rates.
|
||||
*
|
||||
*/
|
||||
static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ath5k_softc *sc = ah->ah_sc;
|
||||
struct ieee80211_rate *rate;
|
||||
unsigned int i;
|
||||
/* 802.11g covers both OFDM and CCK */
|
||||
u8 band = IEEE80211_BAND_2GHZ;
|
||||
|
||||
/* Write rate duration table */
|
||||
for (i = 0; i < sc->sbands[band].n_bitrates; i++) {
|
||||
u32 reg;
|
||||
u16 tx_time;
|
||||
|
||||
if (ah->ah_ack_bitrate_high)
|
||||
rate = &sc->sbands[band].bitrates[ack_rates_high[i]];
|
||||
/* CCK -> 1Mb */
|
||||
else if (i < 4)
|
||||
rate = &sc->sbands[band].bitrates[0];
|
||||
/* OFDM -> 6Mb */
|
||||
else
|
||||
rate = &sc->sbands[band].bitrates[4];
|
||||
|
||||
/* Set ACK timeout */
|
||||
reg = AR5K_RATE_DUR(rate->hw_value);
|
||||
|
||||
/* An ACK frame consists of 10 bytes. If you add the FCS,
|
||||
* which ieee80211_generic_frame_duration() adds,
|
||||
* its 14 bytes. Note we use the control rate and not the
|
||||
* actual rate for this rate. See mac80211 tx.c
|
||||
* ieee80211_duration() for a brief description of
|
||||
* what rate we should choose to TX ACKs. */
|
||||
tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
|
||||
|
||||
tx_time = le16_to_cpu(tx_time);
|
||||
|
||||
ath5k_hw_reg_write(ah, tx_time, reg);
|
||||
|
||||
if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We're not distinguishing short preamble here,
|
||||
* This is true, all we'll get is a longer value here
|
||||
* which is not necessarilly bad. We could use
|
||||
* export ieee80211_frame_duration() but that needs to be
|
||||
* fixed first to be properly used by mac802111 drivers:
|
||||
*
|
||||
* - remove erp stuff and let the routine figure ofdm
|
||||
* erp rates
|
||||
* - remove passing argument ieee80211_local as
|
||||
* drivers don't have access to it
|
||||
* - move drivers using ieee80211_generic_frame_duration()
|
||||
* to this
|
||||
*/
|
||||
ath5k_hw_reg_write(ah, tx_time,
|
||||
reg + (AR5K_SET_SHORT_PREAMBLE << 2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
|
||||
*
|
||||
|
@ -199,88 +327,10 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_htoclock - Translate usec to hw clock units
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
* @usec: value in microseconds
|
||||
*/
|
||||
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
return usec * common->clockrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_clocktoh - Translate hw clock units to usec
|
||||
* @clock: value in hw clock units
|
||||
*/
|
||||
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
return clock / common->clockrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_clockrate - Set common->clockrate for the current channel
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
int clock;
|
||||
|
||||
if (channel->hw_value & CHANNEL_5GHZ)
|
||||
clock = 40; /* 802.11a */
|
||||
else if (channel->hw_value & CHANNEL_CCK)
|
||||
clock = 22; /* 802.11b */
|
||||
else
|
||||
clock = 44; /* 802.11g */
|
||||
|
||||
/* Clock rate in turbo modes is twice the normal rate */
|
||||
if (channel->hw_value & CHANNEL_TURBO)
|
||||
clock *= 2;
|
||||
|
||||
common->clockrate = clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_get_default_slottime - Get the default slot time for current mode
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
|
||||
if (channel->hw_value & CHANNEL_TURBO)
|
||||
return 6; /* both turbo modes */
|
||||
|
||||
if (channel->hw_value & CHANNEL_CCK)
|
||||
return 20; /* 802.11b */
|
||||
|
||||
return 9; /* 802.11 a/g */
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_get_default_sifs - Get the default SIFS for current mode
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*/
|
||||
static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
|
||||
if (channel->hw_value & CHANNEL_TURBO)
|
||||
return 8; /* both turbo modes */
|
||||
|
||||
if (channel->hw_value & CHANNEL_5GHZ)
|
||||
return 16; /* 802.11a */
|
||||
|
||||
return 10; /* 802.11 b/g */
|
||||
}
|
||||
/*******************\
|
||||
* RX filter Control *
|
||||
\*******************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_lladdr - Set station id
|
||||
|
@ -362,39 +412,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
|
|||
ath_hw_setbssidmask(common);
|
||||
}
|
||||
|
||||
/************\
|
||||
* RX Control *
|
||||
\************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_start_rx_pcu - Start RX engine
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Starts RX engine on PCU so that hw can process RXed frames
|
||||
* (ACK etc).
|
||||
*
|
||||
* NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
|
||||
*/
|
||||
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
|
||||
{
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
|
||||
}
|
||||
|
||||
/**
|
||||
* at5k_hw_stop_rx_pcu - Stop RX engine
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Stops RX engine on PCU
|
||||
*
|
||||
* TODO: Detach ANI here
|
||||
*/
|
||||
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
|
||||
{
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set multicast filter
|
||||
*/
|
||||
|
@ -746,7 +763,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
|
|||
* @ah: The &struct ath5k_hw
|
||||
* @coverage_class: IEEE 802.11 coverage class number
|
||||
*
|
||||
* Sets slot time, ACK timeout and CTS timeout for given coverage class.
|
||||
* Sets IFS intervals and ACK/CTS timeouts for given coverage class.
|
||||
*/
|
||||
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
|
||||
{
|
||||
|
@ -755,9 +772,175 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
|
|||
int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
|
||||
int cts_timeout = ack_timeout;
|
||||
|
||||
ath5k_hw_set_slot_time(ah, slot_time);
|
||||
ath5k_hw_set_ifs_intervals(ah, slot_time);
|
||||
ath5k_hw_set_ack_timeout(ah, ack_timeout);
|
||||
ath5k_hw_set_cts_timeout(ah, cts_timeout);
|
||||
|
||||
ah->ah_coverage_class = coverage_class;
|
||||
}
|
||||
|
||||
/***************************\
|
||||
* Init/Start/Stop functions *
|
||||
\***************************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_start_rx_pcu - Start RX engine
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Starts RX engine on PCU so that hw can process RXed frames
|
||||
* (ACK etc).
|
||||
*
|
||||
* NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
|
||||
*/
|
||||
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
|
||||
{
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
|
||||
}
|
||||
|
||||
/**
|
||||
* at5k_hw_stop_rx_pcu - Stop RX engine
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
*
|
||||
* Stops RX engine on PCU
|
||||
*/
|
||||
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
|
||||
{
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_opmode - Set PCU operating mode
|
||||
*
|
||||
* @ah: The &struct ath5k_hw
|
||||
* @op_mode: &enum nl80211_iftype operating mode
|
||||
*
|
||||
* Configure PCU for the various operating modes (AP/STA etc)
|
||||
*/
|
||||
int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
|
||||
{
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
u32 pcu_reg, beacon_reg, low_id, high_id;
|
||||
|
||||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
|
||||
|
||||
/* Preserve rest settings */
|
||||
pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
|
||||
pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
|
||||
| AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
(AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
|
||||
|
||||
beacon_reg = 0;
|
||||
|
||||
switch (op_mode) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
|
||||
beacon_reg |= AR5K_BCR_ADHOC;
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
|
||||
else
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
|
||||
beacon_reg |= AR5K_BCR_AP;
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
|
||||
else
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
|
||||
break;
|
||||
|
||||
case NL80211_IFTYPE_STATION:
|
||||
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
AR5K_STA_ID1_PWR_SV : 0);
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
|
||||
| (ah->ah_version == AR5K_AR5210 ?
|
||||
AR5K_STA_ID1_NO_PSPOLL : 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set PCU registers
|
||||
*/
|
||||
low_id = get_unaligned_le32(common->macaddr);
|
||||
high_id = get_unaligned_le16(common->macaddr + 4);
|
||||
ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
|
||||
ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
|
||||
|
||||
/*
|
||||
* Set Beacon Control Register on 5210
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||
u8 mode)
|
||||
{
|
||||
/* Set bssid and bssid mask */
|
||||
ath5k_hw_set_bssid(ah);
|
||||
|
||||
/* Set PCU config */
|
||||
ath5k_hw_set_opmode(ah, op_mode);
|
||||
|
||||
/* Write rate duration table only on AR5212 and if
|
||||
* virtual interface has already been brought up
|
||||
* XXX: rethink this after new mode changes to
|
||||
* mac80211 are integrated */
|
||||
if (ah->ah_version == AR5K_AR5212 &&
|
||||
ah->ah_sc->nvifs)
|
||||
ath5k_hw_write_rate_duration(ah);
|
||||
|
||||
/* Set RSSI/BRSSI thresholds
|
||||
*
|
||||
* Note: If we decide to set this value
|
||||
* dynamicaly, have in mind that when AR5K_RSSI_THR
|
||||
* register is read it might return 0x40 if we haven't
|
||||
* wrote anything to it plus BMISS RSSI threshold is zeroed.
|
||||
* So doing a save/restore procedure here isn't the right
|
||||
* choice. Instead store it on ath5k_hw */
|
||||
ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
|
||||
AR5K_TUNE_BMISS_THRES <<
|
||||
AR5K_RSSI_THR_BMISS_S),
|
||||
AR5K_RSSI_THR);
|
||||
|
||||
/* MIC QoS support */
|
||||
if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
|
||||
ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
|
||||
ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
|
||||
}
|
||||
|
||||
/* QoS NOACK Policy */
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
|
||||
AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
|
||||
AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
|
||||
AR5K_QOS_NOACK);
|
||||
}
|
||||
|
||||
/* Restore slot time and ACK timeouts */
|
||||
if (ah->ah_coverage_class > 0)
|
||||
ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
|
||||
|
||||
/* Set ACK bitrate mode (see ack_rates_high) */
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
|
||||
if (ah->ah_ack_bitrate_high)
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
|
||||
else
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,95 @@
|
|||
#include "rfbuffer.h"
|
||||
#include "rfgain.h"
|
||||
|
||||
|
||||
/******************\
|
||||
* Helper functions *
|
||||
\******************/
|
||||
|
||||
/*
|
||||
* Get the PHY Chip revision
|
||||
*/
|
||||
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 srev;
|
||||
u16 ret;
|
||||
|
||||
/*
|
||||
* Set the radio chip access register
|
||||
*/
|
||||
switch (chan) {
|
||||
case CHANNEL_2GHZ:
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
|
||||
break;
|
||||
case CHANNEL_5GHZ:
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
mdelay(2);
|
||||
|
||||
/* ...wait until PHY is ready and read the selected radio revision */
|
||||
ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
|
||||
ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
|
||||
} else {
|
||||
srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
|
||||
ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
|
||||
((srev & 0x0f) << 4), 8);
|
||||
}
|
||||
|
||||
/* Reset to the 5GHz mode */
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a channel is supported
|
||||
*/
|
||||
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
|
||||
{
|
||||
/* Check if the channel is in our supported range */
|
||||
if (flags & CHANNEL_2GHZ) {
|
||||
if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
|
||||
(freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
|
||||
return true;
|
||||
} else if (flags & CHANNEL_5GHZ)
|
||||
if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
|
||||
(freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u8 refclk_freq;
|
||||
|
||||
if ((ah->ah_radio == AR5K_RF5112) ||
|
||||
(ah->ah_radio == AR5K_RF5413) ||
|
||||
(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
|
||||
refclk_freq = 40;
|
||||
else
|
||||
refclk_freq = 32;
|
||||
|
||||
if ((channel->center_freq % refclk_freq != 0) &&
|
||||
((channel->center_freq % refclk_freq < 10) ||
|
||||
(channel->center_freq % refclk_freq > 22)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to modify RF Banks before writing them to AR5K_RF_BUFFER
|
||||
*/
|
||||
|
@ -110,6 +199,90 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
|
||||
*
|
||||
* @ah: the &struct ath5k_hw
|
||||
* @channel: the currently set channel upon reset
|
||||
*
|
||||
* Write the delta slope coefficient (used on pilot tracking ?) for OFDM
|
||||
* operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
|
||||
*
|
||||
* Since delta slope is floating point we split it on its exponent and
|
||||
* mantissa and provide these values on hw.
|
||||
*
|
||||
* For more infos i think this patent is related
|
||||
* http://www.freepatentsonline.com/7184495.html
|
||||
*/
|
||||
static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
/* Get exponent and mantissa and set it */
|
||||
u32 coef_scaled, coef_exp, coef_man,
|
||||
ds_coef_exp, ds_coef_man, clock;
|
||||
|
||||
BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
|
||||
!(channel->hw_value & CHANNEL_OFDM));
|
||||
|
||||
/* Get coefficient
|
||||
* ALGO: coef = (5 * clock / carrier_freq) / 2
|
||||
* we scale coef by shifting clock value by 24 for
|
||||
* better precision since we use integers */
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_40MHZ:
|
||||
clock = 40 * 2;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
clock = 40 / 2;
|
||||
break;
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
clock = 40 / 4;
|
||||
break;
|
||||
default:
|
||||
clock = 40;
|
||||
break;
|
||||
}
|
||||
coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
|
||||
|
||||
/* Get exponent
|
||||
* ALGO: coef_exp = 14 - highest set bit position */
|
||||
coef_exp = ilog2(coef_scaled);
|
||||
|
||||
/* Doesn't make sense if it's zero*/
|
||||
if (!coef_scaled || !coef_exp)
|
||||
return -EINVAL;
|
||||
|
||||
/* Note: we've shifted coef_scaled by 24 */
|
||||
coef_exp = 14 - (coef_exp - 24);
|
||||
|
||||
|
||||
/* Get mantissa (significant digits)
|
||||
* ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
|
||||
coef_man = coef_scaled +
|
||||
(1 << (24 - coef_exp - 1));
|
||||
|
||||
/* Calculate delta slope coefficient exponent
|
||||
* and mantissa (remove scaling) and set them on hw */
|
||||
ds_coef_man = coef_man >> (24 - coef_exp);
|
||||
ds_coef_exp = coef_exp - 16;
|
||||
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
|
||||
AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
|
||||
AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath5k_hw_phy_disable(struct ath5k_hw *ah)
|
||||
{
|
||||
/*Just a try M.F.*/
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**********************\
|
||||
* RF Gain optimization *
|
||||
\**********************/
|
||||
|
@ -436,7 +609,7 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
|
|||
/* Write initial RF gain table to set the RF sensitivity
|
||||
* this one works on all RF chips and has nothing to do
|
||||
* with gain_F calibration */
|
||||
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
|
||||
static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
|
||||
{
|
||||
const struct ath5k_ini_rfgain *ath5k_rfg;
|
||||
unsigned int i, size;
|
||||
|
@ -494,12 +667,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
|
|||
* RF Registers setup *
|
||||
\********************/
|
||||
|
||||
|
||||
/*
|
||||
* Setup RF registers by writing RF buffer on hw
|
||||
*/
|
||||
int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
unsigned int mode)
|
||||
static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel, unsigned int mode)
|
||||
{
|
||||
const struct ath5k_rf_reg *rf_regs;
|
||||
const struct ath5k_ini_rfbuffer *ini_rfb;
|
||||
|
@ -652,6 +824,11 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
|
||||
g_step = &go->go_step[ah->ah_gain.g_step_idx];
|
||||
|
||||
/* Set turbo mode (N/A on RF5413) */
|
||||
if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
|
||||
(ah->ah_radio != AR5K_RF5413))
|
||||
ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
|
||||
|
||||
/* Bank Modifications (chip-specific) */
|
||||
if (ah->ah_radio == AR5K_RF5111) {
|
||||
|
||||
|
@ -691,7 +868,23 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
|
||||
AR5K_RF_PLO_SEL, true);
|
||||
|
||||
/* TODO: Half/quarter channel support */
|
||||
/* Tweak power detectors for half/quarter rate support */
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
|
||||
ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
|
||||
u8 wait_i;
|
||||
|
||||
ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
|
||||
AR5K_RF_WAIT_S, true);
|
||||
|
||||
wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
|
||||
0x1f : 0x10;
|
||||
|
||||
ath5k_hw_rfb_op(ah, rf_regs, wait_i,
|
||||
AR5K_RF_WAIT_I, true);
|
||||
ath5k_hw_rfb_op(ah, rf_regs, 3,
|
||||
AR5K_RF_MAX_TIME, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ah->ah_radio == AR5K_RF5112) {
|
||||
|
@ -789,8 +982,20 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
|
||||
AR5K_RF_GAIN_I, true);
|
||||
|
||||
/* TODO: Half/quarter channel support */
|
||||
/* Tweak power detector for half/quarter rates */
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
|
||||
ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
|
||||
u8 pd_delay;
|
||||
|
||||
pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
|
||||
0xf : 0x8;
|
||||
|
||||
ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
|
||||
AR5K_RF_PD_PERIOD_A, true);
|
||||
ath5k_hw_rfb_op(ah, rf_regs, 0xf,
|
||||
AR5K_RF_PD_DELAY_A, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ah->ah_radio == AR5K_RF5413 &&
|
||||
|
@ -821,24 +1026,6 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
PHY/RF channel functions
|
||||
\**************************/
|
||||
|
||||
/*
|
||||
* Check if a channel is supported
|
||||
*/
|
||||
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
|
||||
{
|
||||
/* Check if the channel is in our supported range */
|
||||
if (flags & CHANNEL_2GHZ) {
|
||||
if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
|
||||
(freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
|
||||
return true;
|
||||
} else if (flags & CHANNEL_5GHZ)
|
||||
if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
|
||||
(freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convertion needed for RF5110
|
||||
*/
|
||||
|
@ -1045,7 +1232,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
|
|||
/*
|
||||
* Set a channel on the radio chip
|
||||
*/
|
||||
int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
static int ath5k_hw_channel(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
int ret;
|
||||
/*
|
||||
|
@ -1092,8 +1280,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
|||
}
|
||||
|
||||
ah->ah_current_channel = channel;
|
||||
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
|
||||
ath5k_hw_set_clockrate(ah);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1177,12 +1363,10 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
|
|||
|
||||
switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_T:
|
||||
case CHANNEL_XR:
|
||||
ee_mode = AR5K_EEPROM_MODE_11A;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_TG:
|
||||
ee_mode = AR5K_EEPROM_MODE_11G;
|
||||
break;
|
||||
default:
|
||||
|
@ -1419,31 +1603,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************\
|
||||
* Spur mitigation functions *
|
||||
\***************************/
|
||||
|
||||
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u8 refclk_freq;
|
||||
|
||||
if ((ah->ah_radio == AR5K_RF5112) ||
|
||||
(ah->ah_radio == AR5K_RF5413) ||
|
||||
(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
|
||||
refclk_freq = 40;
|
||||
else
|
||||
refclk_freq = 32;
|
||||
|
||||
if ((channel->center_freq % refclk_freq != 0) &&
|
||||
((channel->center_freq % refclk_freq < 10) ||
|
||||
(channel->center_freq % refclk_freq > 22)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
|
@ -1472,7 +1637,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
|
|||
spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
|
||||
spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
|
||||
/* XXX: Half/Quarter channels ?*/
|
||||
if (channel->hw_value & CHANNEL_TURBO)
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
|
||||
spur_detection_window *= 2;
|
||||
|
||||
for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
|
||||
|
@ -1501,32 +1666,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
|
|||
* Calculate deltas:
|
||||
* spur_freq_sigma_delta -> spur_offset / sample_freq << 21
|
||||
* spur_delta_phase -> spur_offset / chip_freq << 11
|
||||
* Note: Both values have 100KHz resolution
|
||||
* Note: Both values have 100Hz resolution
|
||||
*/
|
||||
/* XXX: Half/Quarter rate channels ? */
|
||||
switch (channel->hw_value) {
|
||||
case CHANNEL_A:
|
||||
/* Both sample_freq and chip_freq are 40MHz */
|
||||
spur_delta_phase = (spur_offset << 17) / 25;
|
||||
spur_freq_sigma_delta = (spur_delta_phase >> 10);
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
/* sample_freq -> 40MHz chip_freq -> 44MHz
|
||||
* (for b compatibility) */
|
||||
spur_freq_sigma_delta = (spur_offset << 8) / 55;
|
||||
spur_delta_phase = (spur_offset << 17) / 25;
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
|
||||
break;
|
||||
case CHANNEL_T:
|
||||
case CHANNEL_TG:
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_40MHZ:
|
||||
/* Both sample_freq and chip_freq are 80MHz */
|
||||
spur_delta_phase = (spur_offset << 16) / 25;
|
||||
spur_freq_sigma_delta = (spur_delta_phase >> 10);
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
/* Both sample_freq and chip_freq are 20MHz (?) */
|
||||
spur_delta_phase = (spur_offset << 18) / 25;
|
||||
spur_freq_sigma_delta = (spur_delta_phase >> 10);
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
/* Both sample_freq and chip_freq are 10MHz (?) */
|
||||
spur_delta_phase = (spur_offset << 19) / 25;
|
||||
spur_freq_sigma_delta = (spur_delta_phase >> 10);
|
||||
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
|
||||
default:
|
||||
return;
|
||||
if (channel->hw_value == CHANNEL_A) {
|
||||
/* Both sample_freq and chip_freq are 40MHz */
|
||||
spur_delta_phase = (spur_offset << 17) / 25;
|
||||
spur_freq_sigma_delta =
|
||||
(spur_delta_phase >> 10);
|
||||
symbol_width =
|
||||
AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
|
||||
} else {
|
||||
/* sample_freq -> 40MHz chip_freq -> 44MHz
|
||||
* (for b compatibility) */
|
||||
spur_delta_phase = (spur_offset << 17) / 25;
|
||||
spur_freq_sigma_delta =
|
||||
(spur_offset << 8) / 55;
|
||||
symbol_width =
|
||||
AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate pilot and magnitude masks */
|
||||
|
@ -1666,63 +1842,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
|
|||
}
|
||||
}
|
||||
|
||||
/********************\
|
||||
Misc PHY functions
|
||||
\********************/
|
||||
|
||||
int ath5k_hw_phy_disable(struct ath5k_hw *ah)
|
||||
{
|
||||
/*Just a try M.F.*/
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the PHY Chip revision
|
||||
*/
|
||||
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 srev;
|
||||
u16 ret;
|
||||
|
||||
/*
|
||||
* Set the radio chip access register
|
||||
*/
|
||||
switch (chan) {
|
||||
case CHANNEL_2GHZ:
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
|
||||
break;
|
||||
case CHANNEL_5GHZ:
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
mdelay(2);
|
||||
|
||||
/* ...wait until PHY is ready and read the selected radio revision */
|
||||
ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
|
||||
ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
|
||||
} else {
|
||||
srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
|
||||
ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
|
||||
((srev & 0x0f) << 4), 8);
|
||||
}
|
||||
|
||||
/* Reset to the 5GHz mode */
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************\
|
||||
* Antenna control *
|
||||
|
@ -1830,12 +1949,10 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
|
|||
|
||||
switch (channel->hw_value & CHANNEL_MODES) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_T:
|
||||
case CHANNEL_XR:
|
||||
ee_mode = AR5K_EEPROM_MODE_11A;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_TG:
|
||||
ee_mode = AR5K_EEPROM_MODE_11G;
|
||||
break;
|
||||
case CHANNEL_B:
|
||||
|
@ -2269,20 +2386,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
|
|||
|
||||
switch (channel->hw_value & CHANNEL_MODES) {
|
||||
case CHANNEL_A:
|
||||
ctl_mode |= AR5K_CTL_11A;
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
|
||||
ctl_mode |= AR5K_CTL_TURBO;
|
||||
else
|
||||
ctl_mode |= AR5K_CTL_11A;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
ctl_mode |= AR5K_CTL_11G;
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
|
||||
ctl_mode |= AR5K_CTL_TURBOG;
|
||||
else
|
||||
ctl_mode |= AR5K_CTL_11G;
|
||||
break;
|
||||
case CHANNEL_B:
|
||||
ctl_mode |= AR5K_CTL_11B;
|
||||
break;
|
||||
case CHANNEL_T:
|
||||
ctl_mode |= AR5K_CTL_TURBO;
|
||||
break;
|
||||
case CHANNEL_TG:
|
||||
ctl_mode |= AR5K_CTL_TURBOG;
|
||||
break;
|
||||
case CHANNEL_XR:
|
||||
/* Fall through */
|
||||
default:
|
||||
|
@ -2984,9 +3101,9 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
|
|||
/*
|
||||
* Set transmission power
|
||||
*/
|
||||
int
|
||||
static int
|
||||
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
u8 ee_mode, u8 txpower)
|
||||
u8 ee_mode, u8 txpower, bool fast)
|
||||
{
|
||||
struct ath5k_rate_pcal_info rate_info;
|
||||
u8 type;
|
||||
|
@ -3005,6 +3122,9 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
|
||||
/* Initialize TX power table */
|
||||
switch (ah->ah_radio) {
|
||||
case AR5K_RF5110:
|
||||
/* TODO */
|
||||
return 0;
|
||||
case AR5K_RF5111:
|
||||
type = AR5K_PWRTABLE_PWR_TO_PCDAC;
|
||||
break;
|
||||
|
@ -3022,10 +3142,15 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* FIXME: Only on channel/mode change */
|
||||
ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* If fast is set it means we are on the same channel/mode
|
||||
* so there is no need to recalculate the powertable, we 'll
|
||||
* just use the cached one */
|
||||
if (!fast) {
|
||||
ret = ath5k_setup_channel_powertable(ah, channel,
|
||||
ee_mode, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Limit max power if we have a CTL available */
|
||||
ath5k_get_max_ctl_power(ah, channel);
|
||||
|
@ -3086,12 +3211,10 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
|
|||
|
||||
switch (channel->hw_value & CHANNEL_MODES) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_T:
|
||||
case CHANNEL_XR:
|
||||
ee_mode = AR5K_EEPROM_MODE_11A;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_TG:
|
||||
ee_mode = AR5K_EEPROM_MODE_11G;
|
||||
break;
|
||||
case CHANNEL_B:
|
||||
|
@ -3106,5 +3229,229 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
|
|||
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
|
||||
"changing txpower to %d\n", txpower);
|
||||
|
||||
return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
|
||||
return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true);
|
||||
}
|
||||
|
||||
/*************\
|
||||
Init function
|
||||
\*************/
|
||||
|
||||
int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
u8 mode, u8 ee_mode, u8 freq, bool fast)
|
||||
{
|
||||
struct ieee80211_channel *curr_channel;
|
||||
int ret, i;
|
||||
u32 phy_tst1;
|
||||
bool fast_txp;
|
||||
ret = 0;
|
||||
|
||||
/*
|
||||
* Sanity check for fast flag
|
||||
* Don't try fast channel change when changing modulation
|
||||
* mode/band. We check for chip compatibility on
|
||||
* ath5k_hw_reset.
|
||||
*/
|
||||
curr_channel = ah->ah_current_channel;
|
||||
if (fast && (channel->hw_value != curr_channel->hw_value))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* On fast channel change we only set the synth parameters
|
||||
* while PHY is running, enable calibration and skip the rest.
|
||||
*/
|
||||
if (fast) {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
|
||||
AR5K_PHY_RFBUS_REQ_REQUEST);
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
|
||||
break;
|
||||
udelay(5);
|
||||
}
|
||||
/* Failed */
|
||||
if (i >= 100)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't change channel/mode skip
|
||||
* tx powertable calculation and use the
|
||||
* cached one.
|
||||
*/
|
||||
if ((channel->hw_value == curr_channel->hw_value) &&
|
||||
(channel->center_freq == curr_channel->center_freq))
|
||||
fast_txp = true;
|
||||
else
|
||||
fast_txp = false;
|
||||
|
||||
/*
|
||||
* Set TX power
|
||||
*
|
||||
* Note: We need to do that before we set
|
||||
* RF buffer settings on 5211/5212+ so that we
|
||||
* properly set curve indices.
|
||||
*/
|
||||
ret = ath5k_hw_txpower(ah, channel, ee_mode,
|
||||
ah->ah_txpower.txp_max_pwr / 2,
|
||||
fast_txp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* For 5210 we do all initialization using
|
||||
* initvals, so we don't have to modify
|
||||
* any settings (5210 also only supports
|
||||
* a/aturbo modes)
|
||||
*/
|
||||
if ((ah->ah_version != AR5K_AR5210) && !fast) {
|
||||
|
||||
/*
|
||||
* Write initial RF gain settings
|
||||
* This should work for both 5111/5112
|
||||
*/
|
||||
ret = ath5k_hw_rfgain_init(ah, freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mdelay(1);
|
||||
|
||||
/*
|
||||
* Write RF buffer
|
||||
*/
|
||||
ret = ath5k_hw_rfregs_init(ah, channel, mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write OFDM timings on 5212*/
|
||||
if (ah->ah_version == AR5K_AR5212 &&
|
||||
channel->hw_value & CHANNEL_OFDM) {
|
||||
|
||||
ret = ath5k_hw_write_ofdm_timings(ah, channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Spur info is available only from EEPROM versions
|
||||
* greater than 5.3, but the EEPROM routines will use
|
||||
* static values for older versions */
|
||||
if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
|
||||
ath5k_hw_set_spur_mitigation_filter(ah,
|
||||
channel);
|
||||
}
|
||||
|
||||
/*Enable/disable 802.11b mode on 5111
|
||||
(enable 2111 frequency converter + CCK)*/
|
||||
if (ah->ah_radio == AR5K_RF5111) {
|
||||
if (mode == AR5K_MODE_11B)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
|
||||
AR5K_TXCFG_B_MODE);
|
||||
else
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
|
||||
AR5K_TXCFG_B_MODE);
|
||||
}
|
||||
|
||||
} else if (ah->ah_version == AR5K_AR5210) {
|
||||
mdelay(1);
|
||||
/* Disable phy and wait */
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
/* Set channel on PHY */
|
||||
ret = ath5k_hw_channel(ah, channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Enable the PHY and wait until completion
|
||||
* This includes BaseBand and Synthesizer
|
||||
* activation.
|
||||
*/
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
|
||||
|
||||
/*
|
||||
* On 5211+ read activation -> rx delay
|
||||
* and use it.
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
u32 delay;
|
||||
delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
|
||||
AR5K_PHY_RX_DELAY_M;
|
||||
delay = (channel->hw_value & CHANNEL_CCK) ?
|
||||
((delay << 2) / 22) : (delay / 10);
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
|
||||
delay = delay << 1;
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
|
||||
delay = delay << 2;
|
||||
/* XXX: /2 on turbo ? Let's be safe
|
||||
* for now */
|
||||
udelay(100 + delay);
|
||||
} else {
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
if (fast)
|
||||
/*
|
||||
* Release RF Bus grant
|
||||
*/
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
|
||||
AR5K_PHY_RFBUS_REQ_REQUEST);
|
||||
else {
|
||||
/*
|
||||
* Perform ADC test to see if baseband is ready
|
||||
* Set tx hold and check adc test register
|
||||
*/
|
||||
phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
|
||||
for (i = 0; i <= 20; i++) {
|
||||
if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
|
||||
break;
|
||||
udelay(200);
|
||||
}
|
||||
ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start automatic gain control calibration
|
||||
*
|
||||
* During AGC calibration RX path is re-routed to
|
||||
* a power detector so we don't receive anything.
|
||||
*
|
||||
* This method is used to calibrate some static offsets
|
||||
* used together with on-the fly I/Q calibration (the
|
||||
* one performed via ath5k_hw_phy_calibrate), which doesn't
|
||||
* interrupt rx path.
|
||||
*
|
||||
* While rx path is re-routed to the power detector we also
|
||||
* start a noise floor calibration to measure the
|
||||
* card's noise floor (the noise we measure when we are not
|
||||
* transmitting or receiving anything).
|
||||
*
|
||||
* If we are in a noisy environment, AGC calibration may time
|
||||
* out and/or noise floor calibration might timeout.
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
|
||||
|
||||
/* At the same time start I/Q calibration for QAM constellation
|
||||
* -no need for CCK- */
|
||||
ah->ah_calibration = false;
|
||||
if (!(mode == AR5K_MODE_11B)) {
|
||||
ah->ah_calibration = true;
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_RUN);
|
||||
}
|
||||
|
||||
/* Wait for gain calibration to finish (we check for I/Q calibration
|
||||
* during ath5k_phy_calibrate) */
|
||||
if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL, 0, false)) {
|
||||
ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
|
||||
channel->center_freq);
|
||||
}
|
||||
|
||||
/* Restore antenna mode */
|
||||
ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,52 @@ Queue Control Unit, DFS Control Unit Functions
|
|||
#include "debug.h"
|
||||
#include "base.h"
|
||||
|
||||
|
||||
/******************\
|
||||
* Helper functions *
|
||||
\******************/
|
||||
|
||||
/*
|
||||
* Get properties for a transmit queue
|
||||
* Get number of pending frames
|
||||
* for a specific queue [5211+]
|
||||
*/
|
||||
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
|
||||
struct ath5k_txq_info *queue_info)
|
||||
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
|
||||
return 0;
|
||||
u32 pending;
|
||||
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
|
||||
|
||||
/* Return if queue is declared inactive */
|
||||
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
|
||||
return false;
|
||||
|
||||
/* XXX: How about AR5K_CFG_TXCNT ? */
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
return false;
|
||||
|
||||
pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
|
||||
pending &= AR5K_QCU_STS_FRMPENDCNT;
|
||||
|
||||
/* It's possible to have no frames pending even if TXE
|
||||
* is set. To indicate that q has not stopped return
|
||||
* true */
|
||||
if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
|
||||
return true;
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a transmit queue inactive
|
||||
*/
|
||||
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
|
||||
return;
|
||||
|
||||
/* This queue will be skipped in further operations */
|
||||
ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
|
||||
/*For SIMR setup*/
|
||||
AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -49,6 +87,16 @@ static u16 ath5k_cw_validate(u16 cw_req)
|
|||
return cw;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get properties for a transmit queue
|
||||
*/
|
||||
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
|
||||
struct ath5k_txq_info *queue_info)
|
||||
{
|
||||
memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set properties for a transmit queue
|
||||
*/
|
||||
|
@ -172,113 +220,18 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
|
|||
return queue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get number of pending frames
|
||||
* for a specific queue [5211+]
|
||||
*/
|
||||
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
u32 pending;
|
||||
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
|
||||
|
||||
/* Return if queue is declared inactive */
|
||||
if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
|
||||
return false;
|
||||
|
||||
/* XXX: How about AR5K_CFG_TXCNT ? */
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
return false;
|
||||
|
||||
pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
|
||||
pending &= AR5K_QCU_STS_FRMPENDCNT;
|
||||
|
||||
/* It's possible to have no frames pending even if TXE
|
||||
* is set. To indicate that q has not stopped return
|
||||
* true */
|
||||
if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
|
||||
return true;
|
||||
|
||||
return pending;
|
||||
}
|
||||
/*******************************\
|
||||
* Single QCU/DCU initialization *
|
||||
\*******************************/
|
||||
|
||||
/*
|
||||
* Set a transmit queue inactive
|
||||
* Set tx retry limits on DCU
|
||||
*/
|
||||
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
|
||||
return;
|
||||
|
||||
/* This queue will be skipped in further operations */
|
||||
ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
|
||||
/*For SIMR setup*/
|
||||
AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set DFS properties for a transmit queue on DCU
|
||||
*/
|
||||
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
|
||||
unsigned int queue)
|
||||
{
|
||||
u32 retry_lg, retry_sh;
|
||||
struct ath5k_txq_info *tq = &ah->ah_txq[queue];
|
||||
|
||||
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
|
||||
|
||||
tq = &ah->ah_txq[queue];
|
||||
|
||||
if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
|
||||
return 0;
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
/* Only handle data queues, others will be ignored */
|
||||
if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
|
||||
return 0;
|
||||
|
||||
/* Set Slot time */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
|
||||
AR5K_SLOT_TIME);
|
||||
/* Set ACK_CTS timeout */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
|
||||
AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
|
||||
/* Set Transmit Latency */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_TRANSMIT_LATENCY_TURBO :
|
||||
AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
|
||||
|
||||
/* Set IFS0 */
|
||||
if (ah->ah_turbo) {
|
||||
ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
|
||||
tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) <<
|
||||
AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
|
||||
AR5K_IFS0);
|
||||
} else {
|
||||
ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
|
||||
tq->tqi_aifs * AR5K_INIT_SLOT_TIME) <<
|
||||
AR5K_IFS0_DIFS_S) |
|
||||
AR5K_INIT_SIFS, AR5K_IFS0);
|
||||
}
|
||||
|
||||
/* Set IFS1 */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
|
||||
AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
|
||||
/* Set AR5K_PHY_SETTLING */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x38 :
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x1C,
|
||||
AR5K_PHY_SETTLING);
|
||||
/* Set Frame Control Register */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
|
||||
AR5K_PHY_TURBO_SHORT | 0x2020) :
|
||||
(AR5K_PHY_FRAME_CTL_INI | 0x1020),
|
||||
AR5K_PHY_FRAME_CTL_5210);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate and set retry limits
|
||||
|
@ -293,8 +246,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
|||
retry_sh = AR5K_INIT_SH_RETRY;
|
||||
}
|
||||
|
||||
/*No QCU/DCU [5210]*/
|
||||
/* Single data queue on AR5210 */
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
struct ath5k_txq_info *tq = &ah->ah_txq[queue];
|
||||
|
||||
if (queue > 0)
|
||||
return;
|
||||
|
||||
ath5k_hw_reg_write(ah,
|
||||
(tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
|
||||
| AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
|
||||
|
@ -304,8 +262,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
|||
| AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
|
||||
| AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
|
||||
AR5K_NODCU_RETRY_LMT);
|
||||
/* DCU on AR5211+ */
|
||||
} else {
|
||||
/*QCU/DCU [5211+]*/
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
|
||||
AR5K_DCU_RETRY_LMT_SLG_RETRY) |
|
||||
|
@ -314,219 +272,393 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
|||
AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
|
||||
AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
|
||||
AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*===Rest is also for QCU/DCU only [5211+]===*/
|
||||
/**
|
||||
* ath5k_hw_reset_tx_queue - Initialize a single hw queue
|
||||
*
|
||||
* @ah The &struct ath5k_hw
|
||||
* @queue The hw queue number
|
||||
*
|
||||
* Set DFS properties for the given transmit queue on DCU
|
||||
* and configures all queue-specific parameters.
|
||||
*/
|
||||
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
{
|
||||
struct ath5k_txq_info *tq = &ah->ah_txq[queue];
|
||||
|
||||
/*
|
||||
* Set contention window (cw_min/cw_max)
|
||||
* and arbitrated interframe space (aifs)...
|
||||
*/
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
|
||||
AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
|
||||
AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
|
||||
AR5K_QUEUE_DFS_LOCAL_IFS(queue));
|
||||
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
|
||||
|
||||
/*
|
||||
* Set misc registers
|
||||
*/
|
||||
/* Enable DCU early termination for this queue */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_DCU_EARLY);
|
||||
tq = &ah->ah_txq[queue];
|
||||
|
||||
/* Enable DCU to wait for next fragment from QCU */
|
||||
/* Skip if queue inactive or if we are on AR5210
|
||||
* that doesn't have QCU/DCU */
|
||||
if ((ah->ah_version == AR5K_AR5210) ||
|
||||
(tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Set contention window (cw_min/cw_max)
|
||||
* and arbitrated interframe space (aifs)...
|
||||
*/
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
|
||||
AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
|
||||
AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
|
||||
AR5K_QUEUE_DFS_LOCAL_IFS(queue));
|
||||
|
||||
/*
|
||||
* Set tx retry limits for this queue
|
||||
*/
|
||||
ath5k_hw_set_tx_retry_limits(ah, queue);
|
||||
|
||||
|
||||
/*
|
||||
* Set misc registers
|
||||
*/
|
||||
|
||||
/* Enable DCU to wait for next fragment from QCU */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
AR5K_DCU_MISC_FRAG_WAIT);
|
||||
|
||||
/* On Maui and Spirit use the global seqnum on DCU */
|
||||
if (ah->ah_mac_version < AR5K_SREV_AR5211)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
AR5K_DCU_MISC_FRAG_WAIT);
|
||||
AR5K_DCU_MISC_SEQNUM_CTL);
|
||||
|
||||
/* On Maui and Spirit use the global seqnum on DCU */
|
||||
if (ah->ah_mac_version < AR5K_SREV_AR5211)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
AR5K_DCU_MISC_SEQNUM_CTL);
|
||||
/* Constant bit rate period */
|
||||
if (tq->tqi_cbr_period) {
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
|
||||
AR5K_QCU_CBRCFG_INTVAL) |
|
||||
AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
|
||||
AR5K_QCU_CBRCFG_ORN_THRES),
|
||||
AR5K_QUEUE_CBRCFG(queue));
|
||||
|
||||
if (tq->tqi_cbr_period) {
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
|
||||
AR5K_QCU_CBRCFG_INTVAL) |
|
||||
AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
|
||||
AR5K_QCU_CBRCFG_ORN_THRES),
|
||||
AR5K_QUEUE_CBRCFG(queue));
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_CBR);
|
||||
|
||||
if (tq->tqi_cbr_overflow_limit)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_CBR);
|
||||
if (tq->tqi_cbr_overflow_limit)
|
||||
AR5K_REG_ENABLE_BITS(ah,
|
||||
AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_CBR_THRES_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (tq->tqi_ready_time &&
|
||||
(tq->tqi_type != AR5K_TX_QUEUE_CAB))
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
|
||||
AR5K_QCU_RDYTIMECFG_INTVAL) |
|
||||
AR5K_QCU_RDYTIMECFG_ENABLE,
|
||||
AR5K_QUEUE_RDYTIMECFG(queue));
|
||||
/* Ready time interval */
|
||||
if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
|
||||
AR5K_QCU_RDYTIMECFG_INTVAL) |
|
||||
AR5K_QCU_RDYTIMECFG_ENABLE,
|
||||
AR5K_QUEUE_RDYTIMECFG(queue));
|
||||
|
||||
if (tq->tqi_burst_time) {
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
|
||||
AR5K_DCU_CHAN_TIME_DUR) |
|
||||
AR5K_DCU_CHAN_TIME_ENABLE,
|
||||
AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
|
||||
if (tq->tqi_burst_time) {
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
|
||||
AR5K_DCU_CHAN_TIME_DUR) |
|
||||
AR5K_DCU_CHAN_TIME_ENABLE,
|
||||
AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
|
||||
|
||||
if (tq->tqi_flags
|
||||
& AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
|
||||
AR5K_REG_ENABLE_BITS(ah,
|
||||
AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_RDY_VEOL_POLICY);
|
||||
}
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
|
||||
ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
|
||||
AR5K_QUEUE_DFS_MISC(queue));
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
|
||||
ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
|
||||
AR5K_QUEUE_DFS_MISC(queue));
|
||||
|
||||
/*
|
||||
* Set registers by queue type
|
||||
*/
|
||||
switch (tq->tqi_type) {
|
||||
case AR5K_TX_QUEUE_BEACON:
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_RDY_VEOL_POLICY);
|
||||
}
|
||||
|
||||
/* Enable/disable Post frame backoff */
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
|
||||
ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
|
||||
AR5K_QUEUE_DFS_MISC(queue));
|
||||
|
||||
/* Enable/disable fragmentation burst backoff */
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
|
||||
ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
|
||||
AR5K_QUEUE_DFS_MISC(queue));
|
||||
|
||||
/*
|
||||
* Set registers by queue type
|
||||
*/
|
||||
switch (tq->tqi_type) {
|
||||
case AR5K_TX_QUEUE_BEACON:
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_DBA_GT |
|
||||
AR5K_QCU_MISC_CBREXP_BCN_DIS |
|
||||
AR5K_QCU_MISC_BCN_ENABLE);
|
||||
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
|
||||
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
|
||||
AR5K_DCU_MISC_ARBLOCK_IGNORE |
|
||||
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
|
||||
AR5K_DCU_MISC_BCN_ENABLE);
|
||||
break;
|
||||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_CAB:
|
||||
/* XXX: use BCN_SENT_GT, if we can figure out how */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_DBA_GT |
|
||||
AR5K_QCU_MISC_CBREXP_DIS |
|
||||
AR5K_QCU_MISC_CBREXP_BCN_DIS);
|
||||
case AR5K_TX_QUEUE_CAB:
|
||||
/* XXX: use BCN_SENT_GT, if we can figure out how */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_FRSHED_DBA_GT |
|
||||
AR5K_QCU_MISC_CBREXP_DIS |
|
||||
AR5K_QCU_MISC_CBREXP_BCN_DIS);
|
||||
|
||||
ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
|
||||
(AR5K_TUNE_SW_BEACON_RESP -
|
||||
AR5K_TUNE_DMA_BEACON_RESP) -
|
||||
ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
|
||||
(AR5K_TUNE_SW_BEACON_RESP -
|
||||
AR5K_TUNE_DMA_BEACON_RESP) -
|
||||
AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
|
||||
AR5K_QCU_RDYTIMECFG_ENABLE,
|
||||
AR5K_QUEUE_RDYTIMECFG(queue));
|
||||
AR5K_QCU_RDYTIMECFG_ENABLE,
|
||||
AR5K_QUEUE_RDYTIMECFG(queue));
|
||||
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
|
||||
AR5K_DCU_MISC_ARBLOCK_CTL_S));
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
|
||||
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
|
||||
AR5K_DCU_MISC_ARBLOCK_CTL_S));
|
||||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_UAPSD:
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_CBREXP_DIS);
|
||||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_DATA:
|
||||
default:
|
||||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_UAPSD:
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_CBREXP_DIS);
|
||||
break;
|
||||
|
||||
case AR5K_TX_QUEUE_DATA:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Handle frame compression */
|
||||
|
||||
/*
|
||||
* Enable interrupts for this tx queue
|
||||
* in the secondary interrupt mask registers
|
||||
*/
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
|
||||
|
||||
/* Update secondary interrupt mask registers */
|
||||
|
||||
/* Filter out inactive queues */
|
||||
ah->ah_txq_imr_txok &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txerr &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txurn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txeol &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
|
||||
AR5K_SIMR0_QCU_TXOK) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txdesc,
|
||||
AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
|
||||
AR5K_SIMR1_QCU_TXERR) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txeol,
|
||||
AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
|
||||
/* Update simr2 but don't overwrite rest simr2 settings */
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txurn,
|
||||
AR5K_SIMR2_QCU_TXURN));
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
|
||||
AR5K_SIMR3_QCBRORN) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
|
||||
AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
|
||||
AR5K_SIMR4_QTRIG), AR5K_SIMR4);
|
||||
/* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
|
||||
AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
|
||||
/* No queue has TXNOFRM enabled, disable the interrupt
|
||||
* by setting AR5K_TXNOFRM to zero */
|
||||
if (ah->ah_txq_imr_nofrm == 0)
|
||||
ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
|
||||
|
||||
/* Set QCU mask for this DCU to save power */
|
||||
AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
|
||||
}
|
||||
|
||||
/* TODO: Handle frame compression */
|
||||
|
||||
/*
|
||||
* Enable interrupts for this tx queue
|
||||
* in the secondary interrupt mask registers
|
||||
*/
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
|
||||
AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
|
||||
|
||||
/* Update secondary interrupt mask registers */
|
||||
|
||||
/* Filter out inactive queues */
|
||||
ah->ah_txq_imr_txok &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txerr &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txurn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_txeol &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
|
||||
ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
|
||||
AR5K_SIMR0_QCU_TXOK) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txdesc,
|
||||
AR5K_SIMR0_QCU_TXDESC),
|
||||
AR5K_SIMR0);
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
|
||||
AR5K_SIMR1_QCU_TXERR) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txeol,
|
||||
AR5K_SIMR1_QCU_TXEOL),
|
||||
AR5K_SIMR1);
|
||||
|
||||
/* Update SIMR2 but don't overwrite rest simr2 settings */
|
||||
AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
|
||||
AR5K_REG_SM(ah->ah_txq_imr_txurn,
|
||||
AR5K_SIMR2_QCU_TXURN));
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
|
||||
AR5K_SIMR3_QCBRORN) |
|
||||
AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
|
||||
AR5K_SIMR3_QCBRURN),
|
||||
AR5K_SIMR3);
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
|
||||
AR5K_SIMR4_QTRIG), AR5K_SIMR4);
|
||||
|
||||
/* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
|
||||
ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
|
||||
AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
|
||||
|
||||
/* No queue has TXNOFRM enabled, disable the interrupt
|
||||
* by setting AR5K_TXNOFRM to zero */
|
||||
if (ah->ah_txq_imr_nofrm == 0)
|
||||
ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
|
||||
|
||||
/* Set QCU mask for this DCU to save power */
|
||||
AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set slot time on DCU
|
||||
|
||||
/**************************\
|
||||
* Global QCU/DCU functions *
|
||||
\**************************/
|
||||
|
||||
/**
|
||||
* ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU
|
||||
*
|
||||
* @ah The &struct ath5k_hw
|
||||
* @slot_time Slot time in us
|
||||
*
|
||||
* Sets the global IFS intervals on DCU (also works on AR5210) for
|
||||
* the given slot time and the current bwmode.
|
||||
*/
|
||||
int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
|
||||
int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
|
||||
{
|
||||
struct ieee80211_channel *channel = ah->ah_current_channel;
|
||||
struct ath5k_softc *sc = ah->ah_sc;
|
||||
struct ieee80211_rate *rate;
|
||||
u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
|
||||
u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
|
||||
|
||||
if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
|
||||
sifs = ath5k_hw_get_default_sifs(ah);
|
||||
sifs_clock = ath5k_hw_htoclock(ah, sifs);
|
||||
|
||||
/* EIFS
|
||||
* Txtime of ack at lowest rate + SIFS + DIFS
|
||||
* (DIFS = SIFS + 2 * Slot time)
|
||||
*
|
||||
* Note: HAL has some predefined values for EIFS
|
||||
* Turbo: (37 + 2 * 6)
|
||||
* Default: (74 + 2 * 9)
|
||||
* Half: (149 + 2 * 13)
|
||||
* Quarter: (298 + 2 * 21)
|
||||
*
|
||||
* (74 + 2 * 6) for AR5210 default and turbo !
|
||||
*
|
||||
* According to the formula we have
|
||||
* ack_tx_time = 25 for turbo and
|
||||
* ack_tx_time = 42.5 * clock multiplier
|
||||
* for default/half/quarter.
|
||||
*
|
||||
* This can't be right, 42 is what we would get
|
||||
* from ath5k_hw_get_frame_dur_for_bwmode or
|
||||
* ieee80211_generic_frame_duration for zero frame
|
||||
* length and without SIFS !
|
||||
*
|
||||
* Also we have different lowest rate for 802.11a
|
||||
*/
|
||||
if (channel->hw_value & CHANNEL_5GHZ)
|
||||
rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
|
||||
else
|
||||
ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
|
||||
rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
|
||||
|
||||
ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
|
||||
|
||||
/* ack_tx_time includes an SIFS already */
|
||||
eifs = ack_tx_time + sifs + 2 * slot_time;
|
||||
eifs_clock = ath5k_hw_htoclock(ah, eifs);
|
||||
|
||||
/* Set IFS settings on AR5210 */
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
u32 pifs, pifs_clock, difs, difs_clock;
|
||||
|
||||
/* Set slot time */
|
||||
ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
|
||||
|
||||
/* Set EIFS */
|
||||
eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
|
||||
|
||||
/* PIFS = Slot time + SIFS */
|
||||
pifs = slot_time + sifs;
|
||||
pifs_clock = ath5k_hw_htoclock(ah, pifs);
|
||||
pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
|
||||
|
||||
/* DIFS = SIFS + 2 * Slot time */
|
||||
difs = sifs + 2 * slot_time;
|
||||
difs_clock = ath5k_hw_htoclock(ah, difs);
|
||||
|
||||
/* Set SIFS/DIFS */
|
||||
ath5k_hw_reg_write(ah, (difs_clock <<
|
||||
AR5K_IFS0_DIFS_S) | sifs_clock,
|
||||
AR5K_IFS0);
|
||||
|
||||
/* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
|
||||
ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
|
||||
(AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
|
||||
AR5K_IFS1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set IFS slot time */
|
||||
ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
|
||||
|
||||
/* Set EIFS interval */
|
||||
ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
|
||||
|
||||
/* Set SIFS interval in usecs */
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
|
||||
AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
|
||||
sifs);
|
||||
|
||||
/* Set SIFS interval in clock cycles */
|
||||
ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ath5k_hw_init_queues(struct ath5k_hw *ah)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
/* TODO: HW Compression support for data queues */
|
||||
/* TODO: Burst prefetch for data queues */
|
||||
|
||||
/*
|
||||
* Reset queues and start beacon timers at the end of the reset routine
|
||||
* This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
|
||||
* Note: If we want we can assign multiple qcus on one dcu.
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210)
|
||||
for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
|
||||
ret = ath5k_hw_reset_tx_queue(ah, i);
|
||||
if (ret) {
|
||||
ATH5K_ERR(ah->ah_sc,
|
||||
"failed to reset TX queue #%d\n", i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* No QCU/DCU on AR5210, just set tx
|
||||
* retry limits. We set IFS parameters
|
||||
* on ath5k_hw_set_ifs_intervals */
|
||||
ath5k_hw_set_tx_retry_limits(ah, 0);
|
||||
|
||||
/* Set the turbo flag when operating on 40MHz */
|
||||
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
|
||||
AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
|
||||
|
||||
/* If we didn't set IFS timings through
|
||||
* ath5k_hw_set_coverage_class make sure
|
||||
* we set them here */
|
||||
if (!ah->ah_coverage_class) {
|
||||
unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
|
||||
ath5k_hw_set_ifs_intervals(ah, slot_time);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -787,6 +787,7 @@
|
|||
#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
|
||||
#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
|
||||
#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
|
||||
#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4
|
||||
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
|
||||
#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
|
||||
#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
|
||||
|
@ -1311,7 +1312,7 @@
|
|||
#define AR5K_IFS1_EIFS 0x03fff000
|
||||
#define AR5K_IFS1_EIFS_S 12
|
||||
#define AR5K_IFS1_CS_EN 0x04000000
|
||||
|
||||
#define AR5K_IFS1_CS_EN_S 26
|
||||
|
||||
/*
|
||||
* CFP duration register
|
||||
|
@ -2058,6 +2059,7 @@
|
|||
|
||||
#define AR5K_PHY_SCAL 0x9878
|
||||
#define AR5K_PHY_SCAL_32MHZ 0x0000000e
|
||||
#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008
|
||||
#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
|
||||
#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
|
||||
|
||||
|
@ -2244,6 +2246,8 @@
|
|||
#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
|
||||
AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
|
||||
/*---[5111+]---*/
|
||||
#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */
|
||||
#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0
|
||||
#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */
|
||||
#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
|
||||
#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */
|
||||
|
@ -2558,3 +2562,28 @@
|
|||
*/
|
||||
#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
|
||||
#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
|
||||
|
||||
/*
|
||||
* Platform registers for WiSoC
|
||||
*/
|
||||
#define AR5K_AR5312_RESET 0xbc003020
|
||||
#define AR5K_AR5312_RESET_BB0_COLD 0x00000004
|
||||
#define AR5K_AR5312_RESET_BB1_COLD 0x00000200
|
||||
#define AR5K_AR5312_RESET_WMAC0 0x00002000
|
||||
#define AR5K_AR5312_RESET_BB0_WARM 0x00004000
|
||||
#define AR5K_AR5312_RESET_WMAC1 0x00020000
|
||||
#define AR5K_AR5312_RESET_BB1_WARM 0x00040000
|
||||
|
||||
#define AR5K_AR5312_ENABLE 0xbc003080
|
||||
#define AR5K_AR5312_ENABLE_WLAN0 0x00000001
|
||||
#define AR5K_AR5312_ENABLE_WLAN1 0x00000008
|
||||
|
||||
#define AR5K_AR2315_RESET 0xb1000004
|
||||
#define AR5K_AR2315_RESET_WMAC 0x00000001
|
||||
#define AR5K_AR2315_RESET_BB_WARM 0x00000002
|
||||
|
||||
#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008
|
||||
#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002
|
||||
|
||||
#define AR5K_AR2315_BYTESWAP 0xb100000c
|
||||
#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -95,7 +95,7 @@ static struct attribute_group ath5k_attribute_group_ani = {
|
|||
int
|
||||
ath5k_sysfs_register(struct ath5k_softc *sc)
|
||||
{
|
||||
struct device *dev = &sc->pdev->dev;
|
||||
struct device *dev = sc->dev;
|
||||
int err;
|
||||
|
||||
err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
|
||||
|
@ -110,7 +110,7 @@ ath5k_sysfs_register(struct ath5k_softc *sc)
|
|||
void
|
||||
ath5k_sysfs_unregister(struct ath5k_softc *sc)
|
||||
{
|
||||
struct device *dev = &sc->pdev->dev;
|
||||
struct device *dev = sc->dev;
|
||||
|
||||
sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
|
||||
}
|
||||
|
|
|
@ -57,10 +57,11 @@
|
|||
#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
|
||||
#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
|
||||
|
||||
#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
|
||||
|
||||
static int ar9003_hw_power_interpolate(int32_t x,
|
||||
int32_t *px, int32_t *py, u_int16_t np);
|
||||
|
||||
#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
|
||||
|
||||
static const struct ar9300_eeprom ar9300_default = {
|
||||
.eepromVersion = 2,
|
||||
|
@ -3032,6 +3033,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
|
|||
return le32_to_cpu(pBase->swreg);
|
||||
case EEP_PAPRD:
|
||||
return !!(pBase->featureEnable & BIT(5));
|
||||
case EEP_CHAIN_MASK_REDUCE:
|
||||
return (pBase->miscConfiguration >> 0x3) & 0x1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -487,7 +487,11 @@ void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
|
|||
break;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
|
||||
|
||||
if (tx == 0x5) {
|
||||
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
|
||||
AR_PHY_SWAP_ALT_CHAIN);
|
||||
|
|
|
@ -545,6 +545,7 @@ struct ath_ant_comb {
|
|||
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
|
||||
#define SC_OP_BT_SCAN BIT(13)
|
||||
#define SC_OP_ANI_RUN BIT(14)
|
||||
#define SC_OP_ENABLE_APM BIT(15)
|
||||
|
||||
/* Powersave flags */
|
||||
#define PS_WAIT_FOR_BEACON BIT(0)
|
||||
|
@ -697,6 +698,8 @@ static inline void ath_ahb_exit(void) {};
|
|||
void ath9k_ps_wakeup(struct ath_softc *sc);
|
||||
void ath9k_ps_restore(struct ath_softc *sc);
|
||||
|
||||
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
|
||||
|
||||
void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
int ath9k_wiphy_add(struct ath_softc *sc);
|
||||
int ath9k_wiphy_del(struct ath_wiphy *aphy);
|
||||
|
|
|
@ -103,7 +103,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
|||
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
|
||||
series[0].Tries = 1;
|
||||
series[0].Rate = rate;
|
||||
series[0].ChSel = common->tx_chainmask;
|
||||
series[0].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[0].Rate);
|
||||
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
|
||||
ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
|
||||
series, 4, 0);
|
||||
|
|
|
@ -35,29 +35,6 @@ struct ath_btcoex_config {
|
|||
bool bt_hold_rx_clear;
|
||||
};
|
||||
|
||||
static const u16 ath_subsysid_tbl[] = {
|
||||
AR9280_COEX2WIRE_SUBSYSID,
|
||||
AT9285_COEX3WIRE_SA_SUBSYSID,
|
||||
AT9285_COEX3WIRE_DA_SUBSYSID
|
||||
};
|
||||
|
||||
/*
|
||||
* Checks the subsystem id of the device to see if it
|
||||
* supports btcoex
|
||||
*/
|
||||
bool ath9k_hw_btcoex_supported(struct ath_hw *ah)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ah->hw_version.subsysid)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
|
||||
if (ah->hw_version.subsysid == ath_subsysid_tbl[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
|
||||
{
|
||||
|
|
|
@ -49,7 +49,6 @@ struct ath_btcoex_hw {
|
|||
u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
|
||||
};
|
||||
|
||||
bool ath9k_hw_btcoex_supported(struct ath_hw *ah);
|
||||
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
|
||||
void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
|
||||
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#define REG_READ_D(_ah, _reg) \
|
||||
ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
|
||||
|
||||
static struct dentry *ath9k_debugfs_root;
|
||||
|
||||
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
|
@ -878,11 +876,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
|||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
|
||||
if (!ath9k_debugfs_root)
|
||||
return -ENOENT;
|
||||
|
||||
sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
|
||||
ath9k_debugfs_root);
|
||||
sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
|
||||
sc->hw->wiphy->debugfsdir);
|
||||
if (!sc->debug.debugfs_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -935,29 +930,7 @@ int ath9k_init_debug(struct ath_hw *ah)
|
|||
sc->debug.regidx = 0;
|
||||
return 0;
|
||||
err:
|
||||
ath9k_exit_debug(ah);
|
||||
debugfs_remove_recursive(sc->debug.debugfs_phy);
|
||||
sc->debug.debugfs_phy = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void ath9k_exit_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
|
||||
debugfs_remove_recursive(sc->debug.debugfs_phy);
|
||||
}
|
||||
|
||||
int ath9k_debug_create_root(void)
|
||||
{
|
||||
ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
if (!ath9k_debugfs_root)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath9k_debug_remove_root(void)
|
||||
{
|
||||
debugfs_remove(ath9k_debugfs_root);
|
||||
ath9k_debugfs_root = NULL;
|
||||
}
|
||||
|
|
|
@ -164,10 +164,7 @@ struct ath9k_debug {
|
|||
};
|
||||
|
||||
int ath9k_init_debug(struct ath_hw *ah);
|
||||
void ath9k_exit_debug(struct ath_hw *ah);
|
||||
|
||||
int ath9k_debug_create_root(void);
|
||||
void ath9k_debug_remove_root(void);
|
||||
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
|
||||
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts);
|
||||
|
@ -180,19 +177,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath9k_exit_debug(struct ath_hw *ah)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath9k_debug_create_root(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath9k_debug_remove_root(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
|
||||
enum ath9k_int status)
|
||||
{
|
||||
|
|
|
@ -280,6 +280,7 @@ enum eeprom_param {
|
|||
EEP_PAPRD,
|
||||
EEP_MODAL_VER,
|
||||
EEP_ANT_DIV_CTL1,
|
||||
EEP_CHAIN_MASK_REDUCE
|
||||
};
|
||||
|
||||
enum ar5416_rates {
|
||||
|
|
|
@ -363,9 +363,9 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
|||
struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
|
||||
int index = 0, i = 0, chk_idx, len = skb->len;
|
||||
int rx_remain_len = 0, rx_pkt_len = 0;
|
||||
u16 pkt_len, pkt_tag, pool_index = 0;
|
||||
int index = 0, i = 0, len = skb->len;
|
||||
int rx_remain_len, rx_pkt_len;
|
||||
u16 pool_index = 0;
|
||||
u8 *ptr;
|
||||
|
||||
spin_lock(&hif_dev->rx_lock);
|
||||
|
@ -399,65 +399,65 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
|||
spin_unlock(&hif_dev->rx_lock);
|
||||
|
||||
while (index < len) {
|
||||
u16 pkt_len;
|
||||
u16 pkt_tag;
|
||||
u16 pad_len;
|
||||
int chk_idx;
|
||||
|
||||
ptr = (u8 *) skb->data;
|
||||
|
||||
pkt_len = ptr[index] + (ptr[index+1] << 8);
|
||||
pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
|
||||
|
||||
if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
|
||||
u16 pad_len;
|
||||
|
||||
pad_len = 4 - (pkt_len & 0x3);
|
||||
if (pad_len == 4)
|
||||
pad_len = 0;
|
||||
|
||||
chk_idx = index;
|
||||
index = index + 4 + pkt_len + pad_len;
|
||||
|
||||
if (index > MAX_RX_BUF_SIZE) {
|
||||
spin_lock(&hif_dev->rx_lock);
|
||||
hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
|
||||
hif_dev->rx_transfer_len =
|
||||
MAX_RX_BUF_SIZE - chk_idx - 4;
|
||||
hif_dev->rx_pad_len = pad_len;
|
||||
|
||||
nskb = __dev_alloc_skb(pkt_len + 32,
|
||||
GFP_ATOMIC);
|
||||
if (!nskb) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
"ath9k_htc: RX memory allocation"
|
||||
" error\n");
|
||||
spin_unlock(&hif_dev->rx_lock);
|
||||
goto err;
|
||||
}
|
||||
skb_reserve(nskb, 32);
|
||||
RX_STAT_INC(skb_allocated);
|
||||
|
||||
memcpy(nskb->data, &(skb->data[chk_idx+4]),
|
||||
hif_dev->rx_transfer_len);
|
||||
|
||||
/* Record the buffer pointer */
|
||||
hif_dev->remain_skb = nskb;
|
||||
spin_unlock(&hif_dev->rx_lock);
|
||||
} else {
|
||||
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
||||
if (!nskb) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
"ath9k_htc: RX memory allocation"
|
||||
" error\n");
|
||||
goto err;
|
||||
}
|
||||
skb_reserve(nskb, 32);
|
||||
RX_STAT_INC(skb_allocated);
|
||||
|
||||
memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
|
||||
skb_put(nskb, pkt_len);
|
||||
skb_pool[pool_index++] = nskb;
|
||||
}
|
||||
} else {
|
||||
if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
|
||||
RX_STAT_INC(skb_dropped);
|
||||
return;
|
||||
}
|
||||
|
||||
pad_len = 4 - (pkt_len & 0x3);
|
||||
if (pad_len == 4)
|
||||
pad_len = 0;
|
||||
|
||||
chk_idx = index;
|
||||
index = index + 4 + pkt_len + pad_len;
|
||||
|
||||
if (index > MAX_RX_BUF_SIZE) {
|
||||
spin_lock(&hif_dev->rx_lock);
|
||||
hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
|
||||
hif_dev->rx_transfer_len =
|
||||
MAX_RX_BUF_SIZE - chk_idx - 4;
|
||||
hif_dev->rx_pad_len = pad_len;
|
||||
|
||||
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
||||
if (!nskb) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
"ath9k_htc: RX memory allocation error\n");
|
||||
spin_unlock(&hif_dev->rx_lock);
|
||||
goto err;
|
||||
}
|
||||
skb_reserve(nskb, 32);
|
||||
RX_STAT_INC(skb_allocated);
|
||||
|
||||
memcpy(nskb->data, &(skb->data[chk_idx+4]),
|
||||
hif_dev->rx_transfer_len);
|
||||
|
||||
/* Record the buffer pointer */
|
||||
hif_dev->remain_skb = nskb;
|
||||
spin_unlock(&hif_dev->rx_lock);
|
||||
} else {
|
||||
nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
|
||||
if (!nskb) {
|
||||
dev_err(&hif_dev->udev->dev,
|
||||
"ath9k_htc: RX memory allocation error\n");
|
||||
goto err;
|
||||
}
|
||||
skb_reserve(nskb, 32);
|
||||
RX_STAT_INC(skb_allocated);
|
||||
|
||||
memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
|
||||
skb_put(nskb, pkt_len);
|
||||
skb_pool[pool_index++] = nskb;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
|
@ -471,7 +471,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
|
|||
static void ath9k_hif_usb_rx_cb(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
||||
struct hif_device_usb *hif_dev = (struct hif_device_usb *)
|
||||
struct hif_device_usb *hif_dev =
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
int ret;
|
||||
|
||||
|
@ -518,7 +518,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
|
|||
{
|
||||
struct sk_buff *skb = (struct sk_buff *) urb->context;
|
||||
struct sk_buff *nskb;
|
||||
struct hif_device_usb *hif_dev = (struct hif_device_usb *)
|
||||
struct hif_device_usb *hif_dev =
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
int ret;
|
||||
|
||||
|
@ -993,8 +993,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
|
|||
static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
struct hif_device_usb *hif_dev =
|
||||
(struct hif_device_usb *) usb_get_intfdata(interface);
|
||||
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
|
||||
|
||||
if (hif_dev) {
|
||||
ath9k_htc_hw_deinit(hif_dev->htc_handle,
|
||||
|
@ -1016,8 +1015,7 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
|
|||
static int ath9k_hif_usb_suspend(struct usb_interface *interface,
|
||||
pm_message_t message)
|
||||
{
|
||||
struct hif_device_usb *hif_dev =
|
||||
(struct hif_device_usb *) usb_get_intfdata(interface);
|
||||
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
|
||||
|
||||
ath9k_hif_usb_dealloc_urbs(hif_dev);
|
||||
|
||||
|
@ -1026,8 +1024,7 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
|
|||
|
||||
static int ath9k_hif_usb_resume(struct usb_interface *interface)
|
||||
{
|
||||
struct hif_device_usb *hif_dev =
|
||||
(struct hif_device_usb *) usb_get_intfdata(interface);
|
||||
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
|
||||
struct htc_target *htc_handle = hif_dev->htc_handle;
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -184,6 +184,47 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
struct ath9k_htc_target_vif hvif;
|
||||
int ret = 0;
|
||||
u8 cmd_rsp;
|
||||
|
||||
if (priv->nvifs > 0)
|
||||
return -ENOBUFS;
|
||||
|
||||
memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
|
||||
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
|
||||
|
||||
hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
|
||||
priv->ah->opmode = NL80211_IFTYPE_MONITOR;
|
||||
hvif.index = priv->nvifs;
|
||||
|
||||
WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->nvifs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
struct ath9k_htc_target_vif hvif;
|
||||
int ret = 0;
|
||||
u8 cmd_rsp;
|
||||
|
||||
memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
|
||||
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
|
||||
hvif.index = 0; /* Should do for now */
|
||||
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
|
||||
priv->nvifs--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
|
@ -1199,6 +1240,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
|||
WMI_CMD(WMI_STOP_RECV_CMDID);
|
||||
skb_queue_purge(&priv->tx_queue);
|
||||
|
||||
/* Remove monitor interface here */
|
||||
if (ah->opmode == NL80211_IFTYPE_MONITOR) {
|
||||
if (ath9k_htc_remove_monitor_interface(priv))
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to remove monitor interface\n");
|
||||
else
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"Monitor interface removed\n");
|
||||
}
|
||||
|
||||
if (ah->btcoex_hw.enabled) {
|
||||
ath9k_hw_btcoex_disable(ah);
|
||||
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
|
||||
|
@ -1372,13 +1423,16 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
|||
}
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
|
||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
|
||||
if (conf->flags & IEEE80211_CONF_MONITOR) {
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"HW opmode set to Monitor mode\n");
|
||||
priv->ah->opmode = NL80211_IFTYPE_MONITOR;
|
||||
if (ath9k_htc_add_monitor_interface(priv))
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Failed to set monitor mode\n");
|
||||
else
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
"HW opmode set to Monitor mode\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
|
||||
mutex_lock(&priv->htc_pm_lock);
|
||||
|
|
|
@ -77,20 +77,6 @@ struct htc_config_pipe_msg {
|
|||
u8 credits;
|
||||
} __packed;
|
||||
|
||||
struct htc_packet {
|
||||
void *pktcontext;
|
||||
u8 *buf;
|
||||
u8 *buf_payload;
|
||||
u32 buflen;
|
||||
u32 payload_len;
|
||||
|
||||
int endpoint;
|
||||
int status;
|
||||
|
||||
void *context;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct htc_ep_callbacks {
|
||||
void *priv;
|
||||
void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
|
||||
|
@ -123,11 +109,6 @@ struct htc_endpoint {
|
|||
#define HTC_CONTROL_BUFFER_SIZE \
|
||||
(HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
|
||||
|
||||
struct htc_control_buf {
|
||||
struct htc_packet htc_pkt;
|
||||
u8 buf[HTC_CONTROL_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
#define HTC_OP_START_WAIT BIT(0)
|
||||
#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
|
||||
|
||||
|
|
|
@ -1925,8 +1925,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
|||
pCap->num_antcfg_2ghz =
|
||||
ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah) &&
|
||||
ath9k_hw_btcoex_supported(ah)) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
|
||||
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
|
||||
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
|
||||
|
||||
|
@ -1975,6 +1974,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
|||
if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
|
||||
}
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_APM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ enum ath9k_hw_caps {
|
|||
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
|
||||
ATH9K_HW_CAP_2GHZ = BIT(13),
|
||||
ATH9K_HW_CAP_5GHZ = BIT(14),
|
||||
ATH9K_HW_CAP_APM = BIT(15),
|
||||
};
|
||||
|
||||
struct ath9k_hw_capabilities {
|
||||
|
|
|
@ -37,6 +37,10 @@ int led_blink;
|
|||
module_param_named(blink, led_blink, int, 0444);
|
||||
MODULE_PARM_DESC(blink, "Enable LED blink on activity");
|
||||
|
||||
static int ath9k_btcoex_enable;
|
||||
module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
|
||||
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
|
||||
|
||||
/* We use the hw_value as an index into our private channel structure */
|
||||
|
||||
#define CHAN2G(_freq, _idx) { \
|
||||
|
@ -540,6 +544,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
|||
common->hw = sc->hw;
|
||||
common->priv = sc;
|
||||
common->debug_mask = ath9k_debug;
|
||||
common->btcoex_enabled = ath9k_btcoex_enable == 1;
|
||||
spin_lock_init(&common->cc_lock);
|
||||
|
||||
spin_lock_init(&sc->wiphy_lock);
|
||||
|
@ -562,13 +567,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
|||
if (ret)
|
||||
goto err_hw;
|
||||
|
||||
ret = ath9k_init_debug(ah);
|
||||
if (ret) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to create debugfs files\n");
|
||||
goto err_debug;
|
||||
}
|
||||
|
||||
ret = ath9k_init_queues(sc);
|
||||
if (ret)
|
||||
goto err_queues;
|
||||
|
@ -591,8 +589,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
|||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
|
||||
err_queues:
|
||||
ath9k_exit_debug(ah);
|
||||
err_debug:
|
||||
ath9k_hw_deinit(ah);
|
||||
err_hw:
|
||||
tasklet_kill(&sc->intr_tq);
|
||||
|
@ -738,6 +734,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
|
|||
if (error)
|
||||
goto error_register;
|
||||
|
||||
error = ath9k_init_debug(ah);
|
||||
if (error) {
|
||||
ath_print(common, ATH_DBG_FATAL,
|
||||
"Unable to create debugfs files\n");
|
||||
goto error_world;
|
||||
}
|
||||
|
||||
/* Handle world regulatory */
|
||||
if (!ath_is_world_regd(reg)) {
|
||||
error = regulatory_hint(hw->wiphy, reg->alpha2);
|
||||
|
@ -796,7 +799,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
|
|||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
|
||||
|
||||
ath9k_exit_debug(sc->sc_ah);
|
||||
ath9k_hw_deinit(sc->sc_ah);
|
||||
|
||||
tasklet_kill(&sc->intr_tq);
|
||||
|
@ -863,20 +865,12 @@ static int __init ath9k_init(void)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
error = ath9k_debug_create_root();
|
||||
if (error) {
|
||||
printk(KERN_ERR
|
||||
"ath9k: Unable to create debugfs root: %d\n",
|
||||
error);
|
||||
goto err_rate_unregister;
|
||||
}
|
||||
|
||||
error = ath_pci_init();
|
||||
if (error < 0) {
|
||||
printk(KERN_ERR
|
||||
"ath9k: No PCI devices found, driver not installed.\n");
|
||||
error = -ENODEV;
|
||||
goto err_remove_root;
|
||||
goto err_rate_unregister;
|
||||
}
|
||||
|
||||
error = ath_ahb_init();
|
||||
|
@ -890,8 +884,6 @@ static int __init ath9k_init(void)
|
|||
err_pci_exit:
|
||||
ath_pci_exit();
|
||||
|
||||
err_remove_root:
|
||||
ath9k_debug_remove_root();
|
||||
err_rate_unregister:
|
||||
ath_rate_control_unregister();
|
||||
err_out:
|
||||
|
@ -903,7 +895,6 @@ static void __exit ath9k_exit(void)
|
|||
{
|
||||
ath_ahb_exit();
|
||||
ath_pci_exit();
|
||||
ath9k_debug_remove_root();
|
||||
ath_rate_control_unregister();
|
||||
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
|
||||
}
|
||||
|
|
|
@ -553,9 +553,12 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
|
|||
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct ath_node *an;
|
||||
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
|
||||
if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
|
||||
sc->sc_flags |= SC_OP_ENABLE_APM;
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR) {
|
||||
ath_tx_node_init(sc, an);
|
||||
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
|
|
|
@ -250,11 +250,11 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
|
|||
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
TX_STAT_INC(txq->axq_qnum, a_retries);
|
||||
if (tx_info->control.rates[4].count++ > 0)
|
||||
if (fi->retries++ > 0)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
@ -1506,6 +1506,18 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
|
|||
return duration;
|
||||
}
|
||||
|
||||
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath9k_channel *curchan = ah->curchan;
|
||||
if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
|
||||
(curchan->channelFlags & CHANNEL_5GHZ) &&
|
||||
(chainmask == 0x7) && (rate < 0x90))
|
||||
return 0x3;
|
||||
else
|
||||
return chainmask;
|
||||
}
|
||||
|
||||
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
@ -1546,7 +1558,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
|||
|
||||
rix = rates[i].idx;
|
||||
series[i].Tries = rates[i].count;
|
||||
series[i].ChSel = common->tx_chainmask;
|
||||
|
||||
if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
|
||||
(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
|
||||
|
@ -1569,6 +1580,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
|||
if (rates[i].flags & IEEE80211_TX_RC_MCS) {
|
||||
/* MCS rates */
|
||||
series[i].Rate = rix | 0x80;
|
||||
series[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[i].Rate);
|
||||
series[i].PktDuration = ath_pkt_duration(sc, rix, len,
|
||||
is_40, is_sgi, is_sp);
|
||||
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
|
||||
|
@ -1576,7 +1589,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* legcay rates */
|
||||
/* legacy rates */
|
||||
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
|
||||
!(rate->flags & IEEE80211_RATE_ERP_G))
|
||||
phy = WLAN_RC_PHY_CCK;
|
||||
|
@ -1592,6 +1605,12 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
|||
is_sp = false;
|
||||
}
|
||||
|
||||
if (bf->bf_state.bfs_paprd)
|
||||
series[i].ChSel = common->tx_chainmask;
|
||||
else
|
||||
series[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[i].Rate);
|
||||
|
||||
series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
|
||||
phy, rate->bitrate * 100, len, rix, is_sp);
|
||||
}
|
||||
|
|
|
@ -160,8 +160,7 @@ static void carl9170_usb_submit_data_urb(struct ar9170 *ar)
|
|||
|
||||
static void carl9170_usb_tx_data_complete(struct urb *urb)
|
||||
{
|
||||
struct ar9170 *ar = (struct ar9170 *)
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
|
||||
if (WARN_ON_ONCE(!ar)) {
|
||||
dev_kfree_skb_irq(urb->context);
|
||||
|
|
|
@ -67,6 +67,18 @@ enum b43_nphy_rf_sequence {
|
|||
B43_RFSEQ_UPDATE_GAINU,
|
||||
};
|
||||
|
||||
enum b43_nphy_rssi_type {
|
||||
B43_NPHY_RSSI_X = 0,
|
||||
B43_NPHY_RSSI_Y,
|
||||
B43_NPHY_RSSI_Z,
|
||||
B43_NPHY_RSSI_PWRDET,
|
||||
B43_NPHY_RSSI_TSSI_I,
|
||||
B43_NPHY_RSSI_TSSI_Q,
|
||||
B43_NPHY_RSSI_TBD,
|
||||
};
|
||||
|
||||
static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev,
|
||||
bool enable);
|
||||
static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
|
||||
u8 *events, u8 *delays, u8 length);
|
||||
static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
|
||||
|
@ -145,9 +157,153 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev,
|
|||
b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
|
||||
static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
u8 i;
|
||||
u16 tmp;
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 1);
|
||||
|
||||
nphy->txpwrctrl = enable;
|
||||
if (!enable) {
|
||||
if (dev->phy.rev >= 3)
|
||||
; /* TODO */
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
|
||||
for (i = 0; i < 84; i++)
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40);
|
||||
for (i = 0; i < 84; i++)
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
|
||||
|
||||
tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
|
||||
if (dev->phy.rev >= 3)
|
||||
tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN;
|
||||
b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp);
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
|
||||
} else {
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
|
||||
}
|
||||
|
||||
if (dev->phy.rev == 2)
|
||||
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
|
||||
~B43_NPHY_BPHY_CTL3_SCALE, 0x53);
|
||||
else if (dev->phy.rev < 2)
|
||||
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
|
||||
~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
|
||||
|
||||
if (dev->phy.rev < 2 && 0)
|
||||
; /* TODO */
|
||||
} else {
|
||||
b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n");
|
||||
}
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 0);
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
|
||||
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
{
|
||||
//TODO
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
|
||||
|
||||
u8 txpi[2], bbmult, i;
|
||||
u16 tmp, radio_gain, dac_gain;
|
||||
u16 freq = dev->phy.channel_freq;
|
||||
u32 txgain;
|
||||
/* u32 gaintbl; rev3+ */
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 1);
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
txpi[0] = 40;
|
||||
txpi[1] = 40;
|
||||
} else if (sprom->revision < 4) {
|
||||
txpi[0] = 72;
|
||||
txpi[1] = 72;
|
||||
} else {
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
txpi[0] = sprom->txpid2g[0];
|
||||
txpi[1] = sprom->txpid2g[1];
|
||||
} else if (freq >= 4900 && freq < 5100) {
|
||||
txpi[0] = sprom->txpid5gl[0];
|
||||
txpi[1] = sprom->txpid5gl[1];
|
||||
} else if (freq >= 5100 && freq < 5500) {
|
||||
txpi[0] = sprom->txpid5g[0];
|
||||
txpi[1] = sprom->txpid5g[1];
|
||||
} else if (freq >= 5500) {
|
||||
txpi[0] = sprom->txpid5gh[0];
|
||||
txpi[1] = sprom->txpid5gh[1];
|
||||
} else {
|
||||
txpi[0] = 91;
|
||||
txpi[1] = 91;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (i = 0; i < 2; i++) {
|
||||
nphy->txpwrindex[i].index_internal = txpi[i];
|
||||
nphy->txpwrindex[i].index_internal_save = txpi[i];
|
||||
}
|
||||
*/
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (dev->phy.rev >= 3) {
|
||||
/* TODO */
|
||||
radio_gain = (txgain >> 16) & 0x1FFFF;
|
||||
} else {
|
||||
txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
|
||||
radio_gain = (txgain >> 16) & 0x1FFF;
|
||||
}
|
||||
|
||||
dac_gain = (txgain >> 8) & 0x3F;
|
||||
bbmult = txgain & 0xFF;
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (i == 0)
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
|
||||
else
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
|
||||
} else {
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain);
|
||||
else
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
|
||||
tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
|
||||
if (i == 0)
|
||||
tmp = (tmp & 0x00FF) | (bbmult << 8);
|
||||
else
|
||||
tmp = (tmp & 0xFF00) | bbmult;
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp);
|
||||
|
||||
if (0)
|
||||
; /* TODO */
|
||||
}
|
||||
|
||||
b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1593,7 +1749,8 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
|
|||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
|
||||
static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
|
||||
s8 offset, u8 core, u8 rail, u8 type)
|
||||
s8 offset, u8 core, u8 rail,
|
||||
enum b43_nphy_rssi_type type)
|
||||
{
|
||||
u16 tmp;
|
||||
bool core1or5 = (core == 1) || (core == 5);
|
||||
|
@ -1602,53 +1759,59 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
|
|||
offset = clamp_val(offset, -32, 31);
|
||||
tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
|
||||
|
||||
if (core1or5 && (rail == 0) && (type == 2))
|
||||
if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
|
||||
if (core1or5 && (rail == 1) && (type == 2))
|
||||
if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
|
||||
if (core2or5 && (rail == 0) && (type == 2))
|
||||
if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
|
||||
if (core2or5 && (rail == 1) && (type == 2))
|
||||
if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
|
||||
if (core1or5 && (rail == 0) && (type == 0))
|
||||
|
||||
if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
|
||||
if (core1or5 && (rail == 1) && (type == 0))
|
||||
if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
|
||||
if (core2or5 && (rail == 0) && (type == 0))
|
||||
if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
|
||||
if (core2or5 && (rail == 1) && (type == 0))
|
||||
if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
|
||||
if (core1or5 && (rail == 0) && (type == 1))
|
||||
|
||||
if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
|
||||
if (core1or5 && (rail == 1) && (type == 1))
|
||||
if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
|
||||
if (core2or5 && (rail == 0) && (type == 1))
|
||||
if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
|
||||
if (core2or5 && (rail == 1) && (type == 1))
|
||||
if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
|
||||
if (core1or5 && (rail == 0) && (type == 6))
|
||||
|
||||
if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
|
||||
if (core1or5 && (rail == 1) && (type == 6))
|
||||
if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
|
||||
if (core2or5 && (rail == 0) && (type == 6))
|
||||
if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
|
||||
if (core2or5 && (rail == 1) && (type == 6))
|
||||
if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
|
||||
if (core1or5 && (rail == 0) && (type == 3))
|
||||
|
||||
if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
|
||||
if (core1or5 && (rail == 1) && (type == 3))
|
||||
if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
|
||||
if (core2or5 && (rail == 0) && (type == 3))
|
||||
if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
|
||||
if (core2or5 && (rail == 1) && (type == 3))
|
||||
if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
|
||||
if (core1or5 && (type == 4))
|
||||
|
||||
if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
|
||||
if (core2or5 && (type == 4))
|
||||
if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
|
||||
if (core1or5 && (type == 5))
|
||||
|
||||
if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
|
||||
if (core2or5 && (type == 5))
|
||||
if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q))
|
||||
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
|
||||
}
|
||||
|
||||
|
@ -1676,27 +1839,39 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
|
|||
(type + 1) << 4);
|
||||
}
|
||||
|
||||
/* TODO use some definitions */
|
||||
if (code == 0) {
|
||||
b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
|
||||
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000);
|
||||
if (type < 3) {
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
|
||||
b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
|
||||
~(B43_NPHY_RFCTL_CMD_RXEN |
|
||||
B43_NPHY_RFCTL_CMD_CORESEL));
|
||||
b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
|
||||
~(0x1 << 12 |
|
||||
0x1 << 5 |
|
||||
0x1 << 1 |
|
||||
0x1));
|
||||
b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
|
||||
~B43_NPHY_RFCTL_CMD_START);
|
||||
udelay(20);
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
|
||||
b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
|
||||
}
|
||||
} else {
|
||||
b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
|
||||
0x3000);
|
||||
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000);
|
||||
if (type < 3) {
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
|
||||
0xFEC7, 0x0180);
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
|
||||
0xEFDC, (code << 1 | 0x1021));
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
|
||||
~(B43_NPHY_RFCTL_CMD_RXEN |
|
||||
B43_NPHY_RFCTL_CMD_CORESEL),
|
||||
(B43_NPHY_RFCTL_CMD_RXEN |
|
||||
code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT));
|
||||
b43_phy_set(dev, B43_NPHY_RFCTL_OVER,
|
||||
(0x1 << 12 |
|
||||
0x1 << 5 |
|
||||
0x1 << 1 |
|
||||
0x1));
|
||||
b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
|
||||
B43_NPHY_RFCTL_CMD_START);
|
||||
udelay(20);
|
||||
b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
|
||||
b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1918,7 +2093,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
|
|||
u16 class, override;
|
||||
u8 regs_save_radio[2];
|
||||
u16 regs_save_phy[2];
|
||||
|
||||
s8 offset[4];
|
||||
u8 core;
|
||||
u8 rail;
|
||||
|
||||
u16 clip_state[2];
|
||||
u16 clip_off[2] = { 0xFFFF, 0xFFFF };
|
||||
|
@ -2019,12 +2197,11 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
|
|||
if (results_min[i] == 248)
|
||||
offset[i] = code - 32;
|
||||
|
||||
if (i % 2 == 0)
|
||||
b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
|
||||
type);
|
||||
else
|
||||
b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
|
||||
type);
|
||||
core = (i / 2) ? 2 : 1;
|
||||
rail = (i % 2) ? 1 : 0;
|
||||
|
||||
b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
|
||||
type);
|
||||
}
|
||||
|
||||
b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
|
||||
|
@ -2066,6 +2243,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
|
|||
|
||||
b43_nphy_classifier(dev, 7, class);
|
||||
b43_nphy_write_clip_detection(dev, clip_state);
|
||||
/* Specs don't say about reset here, but it makes wl and b43 dumps
|
||||
identical, it really seems wl performs this */
|
||||
b43_nphy_reset_cca(dev);
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
|
||||
|
@ -2083,9 +2263,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev)
|
|||
if (dev->phy.rev >= 3) {
|
||||
b43_nphy_rev3_rssi_cal(dev);
|
||||
} else {
|
||||
b43_nphy_rev2_rssi_cal(dev, 2);
|
||||
b43_nphy_rev2_rssi_cal(dev, 0);
|
||||
b43_nphy_rev2_rssi_cal(dev, 1);
|
||||
b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
|
||||
b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
|
||||
b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2351,7 +2531,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
|
|||
struct nphy_txgains target;
|
||||
const u32 *table = NULL;
|
||||
|
||||
if (nphy->txpwrctrl == 0) {
|
||||
if (!nphy->txpwrctrl) {
|
||||
int i;
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
|
@ -3260,9 +3440,8 @@ int b43_phy_initn(struct b43_wldev *dev)
|
|||
b43_nphy_bphy_init(dev);
|
||||
|
||||
tx_pwr_state = nphy->txpwrctrl;
|
||||
/* TODO N PHY TX power control with argument 0
|
||||
(turning off power control) */
|
||||
/* TODO Fix the TX Power Settings */
|
||||
b43_nphy_tx_power_ctrl(dev, false);
|
||||
b43_nphy_tx_power_fix(dev);
|
||||
/* TODO N PHY TX Power Control Idle TSSI */
|
||||
/* TODO N PHY TX Power Control Setup */
|
||||
|
||||
|
@ -3319,21 +3498,18 @@ int b43_phy_initn(struct b43_wldev *dev)
|
|||
/* TODO N PHY Pre Calibrate TX Gain */
|
||||
target = b43_nphy_get_tx_gains(dev);
|
||||
}
|
||||
}
|
||||
if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false))
|
||||
if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
|
||||
b43_nphy_save_cal(dev);
|
||||
} else if (nphy->mphase_cal_phase_id == 0)
|
||||
;/* N PHY Periodic Calibration with arg 3 */
|
||||
} else {
|
||||
b43_nphy_restore_cal(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
|
||||
if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
|
||||
b43_nphy_save_cal(dev);
|
||||
else if (nphy->mphase_cal_phase_id == 0)
|
||||
;/* N PHY Periodic Calibration with argument 3 */
|
||||
} else {
|
||||
b43_nphy_restore_cal(dev);
|
||||
}
|
||||
|
||||
b43_nphy_tx_pwr_ctrl_coef_setup(dev);
|
||||
/* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
|
||||
b43_nphy_tx_power_ctrl(dev, tx_pwr_state);
|
||||
b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
|
||||
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
|
||||
if (phy->rev >= 3 && phy->rev <= 6)
|
||||
|
@ -3384,7 +3560,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
|
|||
b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
|
||||
}
|
||||
|
||||
if (nphy->txpwrctrl)
|
||||
if (!nphy->txpwrctrl)
|
||||
b43_nphy_tx_power_fix(dev);
|
||||
|
||||
if (dev->phy.rev < 3)
|
||||
|
@ -3480,6 +3656,7 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
|
|||
nphy->gain_boost = true; /* this way we follow wl, assume it is true */
|
||||
nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
|
||||
nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
|
||||
nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
|
||||
}
|
||||
|
||||
static void b43_nphy_op_free(struct b43_wldev *dev)
|
||||
|
|
|
@ -782,7 +782,7 @@ struct b43_phy_n {
|
|||
u16 mphase_txcal_numcmds;
|
||||
u16 mphase_txcal_bestcoeffs[11];
|
||||
|
||||
u8 txpwrctrl;
|
||||
bool txpwrctrl;
|
||||
u16 txcal_bbmult;
|
||||
u16 txiqlocal_bestc[11];
|
||||
bool txiqlocal_coeffsvalid;
|
||||
|
|
|
@ -304,7 +304,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 184,
|
||||
.freq = 4920, /* MHz */
|
||||
.unk2 = 3280,
|
||||
RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xEC, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07B4, 0x07B0, 0x07AC, 0x0214, 0x0215, 0x0216),
|
||||
|
@ -312,7 +312,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 186,
|
||||
.freq = 4930, /* MHz */
|
||||
.unk2 = 3287,
|
||||
RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xED, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07B8, 0x07B4, 0x07B0, 0x0213, 0x0214, 0x0215),
|
||||
|
@ -320,7 +320,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 188,
|
||||
.freq = 4940, /* MHz */
|
||||
.unk2 = 3293,
|
||||
RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xEE, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07BC, 0x07B8, 0x07B4, 0x0212, 0x0213, 0x0214),
|
||||
|
@ -328,7 +328,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 190,
|
||||
.freq = 4950, /* MHz */
|
||||
.unk2 = 3300,
|
||||
RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xEF, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07C0, 0x07BC, 0x07B8, 0x0211, 0x0212, 0x0213),
|
||||
|
@ -336,7 +336,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 192,
|
||||
.freq = 4960, /* MHz */
|
||||
.unk2 = 3307,
|
||||
RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF0, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07C4, 0x07C0, 0x07BC, 0x020F, 0x0211, 0x0212),
|
||||
|
@ -344,7 +344,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 194,
|
||||
.freq = 4970, /* MHz */
|
||||
.unk2 = 3313,
|
||||
RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF1, 0x01, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07C8, 0x07C4, 0x07C0, 0x020E, 0x020F, 0x0211),
|
||||
|
@ -352,7 +352,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 196,
|
||||
.freq = 4980, /* MHz */
|
||||
.unk2 = 3320,
|
||||
RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF2, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07CC, 0x07C8, 0x07C4, 0x020D, 0x020E, 0x020F),
|
||||
|
@ -360,7 +360,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 198,
|
||||
.freq = 4990, /* MHz */
|
||||
.unk2 = 3327,
|
||||
RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF3, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07D0, 0x07CC, 0x07C8, 0x020C, 0x020D, 0x020E),
|
||||
|
@ -368,7 +368,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 200,
|
||||
.freq = 5000, /* MHz */
|
||||
.unk2 = 3333,
|
||||
RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF4, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07D4, 0x07D0, 0x07CC, 0x020B, 0x020C, 0x020D),
|
||||
|
@ -376,7 +376,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 202,
|
||||
.freq = 5010, /* MHz */
|
||||
.unk2 = 3340,
|
||||
RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF5, 0x01, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07D8, 0x07D4, 0x07D0, 0x020A, 0x020B, 0x020C),
|
||||
|
@ -384,7 +384,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 204,
|
||||
.freq = 5020, /* MHz */
|
||||
.unk2 = 3347,
|
||||
RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF6, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07DC, 0x07D8, 0x07D4, 0x0209, 0x020A, 0x020B),
|
||||
|
@ -392,7 +392,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 206,
|
||||
.freq = 5030, /* MHz */
|
||||
.unk2 = 3353,
|
||||
RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF7, 0x01, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07E0, 0x07DC, 0x07D8, 0x0208, 0x0209, 0x020A),
|
||||
|
@ -400,7 +400,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 208,
|
||||
.freq = 5040, /* MHz */
|
||||
.unk2 = 3360,
|
||||
RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF8, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07E4, 0x07E0, 0x07DC, 0x0207, 0x0208, 0x0209),
|
||||
|
@ -408,7 +408,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 210,
|
||||
.freq = 5050, /* MHz */
|
||||
.unk2 = 3367,
|
||||
RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xF9, 0x01, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
|
||||
0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
|
||||
PHYREGS(0x07E8, 0x07E4, 0x07E0, 0x0206, 0x0207, 0x0208),
|
||||
|
@ -416,7 +416,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 212,
|
||||
.freq = 5060, /* MHz */
|
||||
.unk2 = 3373,
|
||||
RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFA, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
|
||||
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
|
||||
PHYREGS(0x07EC, 0x07E8, 0x07E4, 0x0205, 0x0206, 0x0207),
|
||||
|
@ -424,7 +424,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 214,
|
||||
.freq = 5070, /* MHz */
|
||||
.unk2 = 3380,
|
||||
RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFB, 0x01, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
|
||||
0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
|
||||
PHYREGS(0x07F0, 0x07EC, 0x07E8, 0x0204, 0x0205, 0x0206),
|
||||
|
@ -432,7 +432,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 216,
|
||||
.freq = 5080, /* MHz */
|
||||
.unk2 = 3387,
|
||||
RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFC, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
|
||||
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
|
||||
PHYREGS(0x07F4, 0x07F0, 0x07EC, 0x0203, 0x0204, 0x0205),
|
||||
|
@ -440,7 +440,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 218,
|
||||
.freq = 5090, /* MHz */
|
||||
.unk2 = 3393,
|
||||
RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFD, 0x01, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
|
||||
0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
|
||||
PHYREGS(0x07F8, 0x07F4, 0x07F0, 0x0202, 0x0203, 0x0204),
|
||||
|
@ -448,7 +448,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 220,
|
||||
.freq = 5100, /* MHz */
|
||||
.unk2 = 3400,
|
||||
RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFE, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
|
||||
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
|
||||
PHYREGS(0x07FC, 0x07F8, 0x07F4, 0x0201, 0x0202, 0x0203),
|
||||
|
@ -456,7 +456,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 222,
|
||||
.freq = 5110, /* MHz */
|
||||
.unk2 = 3407,
|
||||
RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0xFF, 0x01, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
|
||||
0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
|
||||
PHYREGS(0x0800, 0x07FC, 0x07F8, 0x0200, 0x0201, 0x0202),
|
||||
|
@ -464,7 +464,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 224,
|
||||
.freq = 5120, /* MHz */
|
||||
.unk2 = 3413,
|
||||
RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x00, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
|
||||
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
|
||||
PHYREGS(0x0804, 0x0800, 0x07FC, 0x01FF, 0x0200, 0x0201),
|
||||
|
@ -472,7 +472,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 226,
|
||||
.freq = 5130, /* MHz */
|
||||
.unk2 = 3420,
|
||||
RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x01, 0x02, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
|
||||
0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
|
||||
PHYREGS(0x0808, 0x0804, 0x0800, 0x01FE, 0x01FF, 0x0200),
|
||||
|
@ -488,7 +488,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 32,
|
||||
.freq = 5160, /* MHz */
|
||||
.unk2 = 3440,
|
||||
RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x04, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
|
||||
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
|
||||
PHYREGS(0x0814, 0x0810, 0x080C, 0x01FB, 0x01FC, 0x01FD),
|
||||
|
@ -496,7 +496,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 34,
|
||||
.freq = 5170, /* MHz */
|
||||
.unk2 = 3447,
|
||||
RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x05, 0x02, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
|
||||
0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
|
||||
PHYREGS(0x0818, 0x0814, 0x0810, 0x01FA, 0x01FB, 0x01FC),
|
||||
|
@ -504,7 +504,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 36,
|
||||
.freq = 5180, /* MHz */
|
||||
.unk2 = 3453,
|
||||
RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x06, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
|
||||
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
|
||||
PHYREGS(0x081C, 0x0818, 0x0814, 0x01F9, 0x01FA, 0x01FB),
|
||||
|
@ -512,7 +512,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 38,
|
||||
.freq = 5190, /* MHz */
|
||||
.unk2 = 3460,
|
||||
RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x07, 0x02, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
|
||||
0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
|
||||
PHYREGS(0x0820, 0x081C, 0x0818, 0x01F8, 0x01F9, 0x01FA),
|
||||
|
@ -520,7 +520,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 40,
|
||||
.freq = 5200, /* MHz */
|
||||
.unk2 = 3467,
|
||||
RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x08, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
|
||||
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
|
||||
PHYREGS(0x0824, 0x0820, 0x081C, 0x01F7, 0x01F8, 0x01F9),
|
||||
|
@ -528,7 +528,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 42,
|
||||
.freq = 5210, /* MHz */
|
||||
.unk2 = 3473,
|
||||
RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x09, 0x02, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
|
||||
0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
|
||||
PHYREGS(0x0828, 0x0824, 0x0820, 0x01F6, 0x01F7, 0x01F8),
|
||||
|
@ -536,7 +536,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 44,
|
||||
.freq = 5220, /* MHz */
|
||||
.unk2 = 3480,
|
||||
RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0A, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
|
||||
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
|
||||
PHYREGS(0x082C, 0x0828, 0x0824, 0x01F5, 0x01F6, 0x01F7),
|
||||
|
@ -544,7 +544,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 46,
|
||||
.freq = 5230, /* MHz */
|
||||
.unk2 = 3487,
|
||||
RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0B, 0x02, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
|
||||
0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
|
||||
PHYREGS(0x0830, 0x082C, 0x0828, 0x01F4, 0x01F5, 0x01F6),
|
||||
|
@ -552,7 +552,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 48,
|
||||
.freq = 5240, /* MHz */
|
||||
.unk2 = 3493,
|
||||
RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0C, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
|
||||
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
|
||||
PHYREGS(0x0834, 0x0830, 0x082C, 0x01F3, 0x01F4, 0x01F5),
|
||||
|
@ -560,7 +560,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 50,
|
||||
.freq = 5250, /* MHz */
|
||||
.unk2 = 3500,
|
||||
RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0D, 0x02, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
|
||||
0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
|
||||
PHYREGS(0x0838, 0x0834, 0x0830, 0x01F2, 0x01F3, 0x01F4),
|
||||
|
@ -568,7 +568,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 52,
|
||||
.freq = 5260, /* MHz */
|
||||
.unk2 = 3507,
|
||||
RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0E, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
|
||||
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
|
||||
PHYREGS(0x083C, 0x0838, 0x0834, 0x01F1, 0x01F2, 0x01F3),
|
||||
|
@ -576,7 +576,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 54,
|
||||
.freq = 5270, /* MHz */
|
||||
.unk2 = 3513,
|
||||
RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x0F, 0x02, 0x0A, 0x98, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
|
||||
0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
|
||||
PHYREGS(0x0840, 0x083C, 0x0838, 0x01F0, 0x01F1, 0x01F2),
|
||||
|
@ -584,7 +584,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 56,
|
||||
.freq = 5280, /* MHz */
|
||||
.unk2 = 3520,
|
||||
RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x10, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
|
||||
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
|
||||
PHYREGS(0x0844, 0x0840, 0x083C, 0x01F0, 0x01F0, 0x01F1),
|
||||
|
@ -592,7 +592,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 58,
|
||||
.freq = 5290, /* MHz */
|
||||
.unk2 = 3527,
|
||||
RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x11, 0x02, 0x09, 0x91, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
|
||||
0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
|
||||
PHYREGS(0x0848, 0x0844, 0x0840, 0x01EF, 0x01F0, 0x01F0),
|
||||
|
@ -600,7 +600,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 60,
|
||||
.freq = 5300, /* MHz */
|
||||
.unk2 = 3533,
|
||||
RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x12, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
|
||||
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
|
||||
PHYREGS(0x084C, 0x0848, 0x0844, 0x01EE, 0x01EF, 0x01F0),
|
||||
|
@ -608,7 +608,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 62,
|
||||
.freq = 5310, /* MHz */
|
||||
.unk2 = 3540,
|
||||
RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x13, 0x02, 0x09, 0x8A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
|
||||
0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
|
||||
PHYREGS(0x0850, 0x084C, 0x0848, 0x01ED, 0x01EE, 0x01EF),
|
||||
|
@ -616,7 +616,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 64,
|
||||
.freq = 5320, /* MHz */
|
||||
.unk2 = 3547,
|
||||
RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x14, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
|
||||
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
|
||||
PHYREGS(0x0854, 0x0850, 0x084C, 0x01EC, 0x01ED, 0x01EE),
|
||||
|
@ -624,7 +624,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 66,
|
||||
.freq = 5330, /* MHz */
|
||||
.unk2 = 3553,
|
||||
RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x15, 0x02, 0x09, 0x83, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
|
||||
0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
|
||||
PHYREGS(0x0858, 0x0854, 0x0850, 0x01EB, 0x01EC, 0x01ED),
|
||||
|
@ -632,7 +632,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 68,
|
||||
.freq = 5340, /* MHz */
|
||||
.unk2 = 3560,
|
||||
RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x16, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
|
||||
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
|
||||
PHYREGS(0x085C, 0x0858, 0x0854, 0x01EA, 0x01EB, 0x01EC),
|
||||
|
@ -640,7 +640,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 70,
|
||||
.freq = 5350, /* MHz */
|
||||
.unk2 = 3567,
|
||||
RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x17, 0x02, 0x08, 0x7C, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
|
||||
0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
|
||||
PHYREGS(0x0860, 0x085C, 0x0858, 0x01E9, 0x01EA, 0x01EB),
|
||||
|
@ -648,7 +648,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 72,
|
||||
.freq = 5360, /* MHz */
|
||||
.unk2 = 3573,
|
||||
RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x18, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
|
||||
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
|
||||
PHYREGS(0x0864, 0x0860, 0x085C, 0x01E8, 0x01E9, 0x01EA),
|
||||
|
@ -656,7 +656,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 74,
|
||||
.freq = 5370, /* MHz */
|
||||
.unk2 = 3580,
|
||||
RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x19, 0x02, 0x08, 0x75, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
|
||||
0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
|
||||
PHYREGS(0x0868, 0x0864, 0x0860, 0x01E7, 0x01E8, 0x01E9),
|
||||
|
@ -664,7 +664,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 76,
|
||||
.freq = 5380, /* MHz */
|
||||
.unk2 = 3587,
|
||||
RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1A, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
|
||||
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
|
||||
PHYREGS(0x086C, 0x0868, 0x0864, 0x01E6, 0x01E7, 0x01E8),
|
||||
|
@ -672,7 +672,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 78,
|
||||
.freq = 5390, /* MHz */
|
||||
.unk2 = 3593,
|
||||
RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1B, 0x02, 0x08, 0x6E, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
|
||||
0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
|
||||
PHYREGS(0x0870, 0x086C, 0x0868, 0x01E5, 0x01E6, 0x01E7),
|
||||
|
@ -680,7 +680,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 80,
|
||||
.freq = 5400, /* MHz */
|
||||
.unk2 = 3600,
|
||||
RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1C, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
|
||||
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
|
||||
PHYREGS(0x0874, 0x0870, 0x086C, 0x01E5, 0x01E5, 0x01E6),
|
||||
|
@ -688,7 +688,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 82,
|
||||
.freq = 5410, /* MHz */
|
||||
.unk2 = 3607,
|
||||
RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1D, 0x02, 0x07, 0x67, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
|
||||
0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
|
||||
PHYREGS(0x0878, 0x0874, 0x0870, 0x01E4, 0x01E5, 0x01E5),
|
||||
|
@ -696,7 +696,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 84,
|
||||
.freq = 5420, /* MHz */
|
||||
.unk2 = 3613,
|
||||
RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1E, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
|
||||
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
|
||||
PHYREGS(0x087C, 0x0878, 0x0874, 0x01E3, 0x01E4, 0x01E5),
|
||||
|
@ -704,7 +704,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 86,
|
||||
.freq = 5430, /* MHz */
|
||||
.unk2 = 3620,
|
||||
RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x1F, 0x02, 0x07, 0x61, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
|
||||
0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
|
||||
PHYREGS(0x0880, 0x087C, 0x0878, 0x01E2, 0x01E3, 0x01E4),
|
||||
|
@ -712,7 +712,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 88,
|
||||
.freq = 5440, /* MHz */
|
||||
.unk2 = 3627,
|
||||
RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x20, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
|
||||
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
|
||||
PHYREGS(0x0884, 0x0880, 0x087C, 0x01E1, 0x01E2, 0x01E3),
|
||||
|
@ -720,7 +720,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 90,
|
||||
.freq = 5450, /* MHz */
|
||||
.unk2 = 3633,
|
||||
RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x21, 0x02, 0x07, 0x5A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
|
||||
0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
|
||||
PHYREGS(0x0888, 0x0884, 0x0880, 0x01E0, 0x01E1, 0x01E2),
|
||||
|
@ -728,7 +728,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 92,
|
||||
.freq = 5460, /* MHz */
|
||||
.unk2 = 3640,
|
||||
RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x22, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
|
||||
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
|
||||
PHYREGS(0x088C, 0x0888, 0x0884, 0x01DF, 0x01E0, 0x01E1),
|
||||
|
@ -736,7 +736,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 94,
|
||||
.freq = 5470, /* MHz */
|
||||
.unk2 = 3647,
|
||||
RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x23, 0x02, 0x06, 0x53, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
|
||||
0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
|
||||
PHYREGS(0x0890, 0x088C, 0x0888, 0x01DE, 0x01DF, 0x01E0),
|
||||
|
@ -744,7 +744,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 96,
|
||||
.freq = 5480, /* MHz */
|
||||
.unk2 = 3653,
|
||||
RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x24, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
|
||||
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
|
||||
PHYREGS(0x0894, 0x0890, 0x088C, 0x01DD, 0x01DE, 0x01DF),
|
||||
|
@ -752,7 +752,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 98,
|
||||
.freq = 5490, /* MHz */
|
||||
.unk2 = 3660,
|
||||
RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x25, 0x02, 0x06, 0x4D, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
|
||||
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
|
||||
PHYREGS(0x0898, 0x0894, 0x0890, 0x01DD, 0x01DD, 0x01DE),
|
||||
|
@ -760,7 +760,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 100,
|
||||
.freq = 5500, /* MHz */
|
||||
.unk2 = 3667,
|
||||
RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x26, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
|
||||
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
|
||||
PHYREGS(0x089C, 0x0898, 0x0894, 0x01DC, 0x01DD, 0x01DD),
|
||||
|
@ -768,7 +768,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 102,
|
||||
.freq = 5510, /* MHz */
|
||||
.unk2 = 3673,
|
||||
RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x27, 0x02, 0x06, 0x47, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
|
||||
0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
|
||||
PHYREGS(0x08A0, 0x089C, 0x0898, 0x01DB, 0x01DC, 0x01DD),
|
||||
|
@ -776,7 +776,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 104,
|
||||
.freq = 5520, /* MHz */
|
||||
.unk2 = 3680,
|
||||
RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x28, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
|
||||
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
|
||||
PHYREGS(0x08A4, 0x08A0, 0x089C, 0x01DA, 0x01DB, 0x01DC),
|
||||
|
@ -784,7 +784,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 106,
|
||||
.freq = 5530, /* MHz */
|
||||
.unk2 = 3687,
|
||||
RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x29, 0x02, 0x05, 0x40, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
|
||||
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
|
||||
PHYREGS(0x08A8, 0x08A4, 0x08A0, 0x01D9, 0x01DA, 0x01DB),
|
||||
|
@ -792,7 +792,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 108,
|
||||
.freq = 5540, /* MHz */
|
||||
.unk2 = 3693,
|
||||
RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2A, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
|
||||
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
|
||||
PHYREGS(0x08AC, 0x08A8, 0x08A4, 0x01D8, 0x01D9, 0x01DA),
|
||||
|
@ -800,7 +800,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 110,
|
||||
.freq = 5550, /* MHz */
|
||||
.unk2 = 3700,
|
||||
RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2B, 0x02, 0x05, 0x3A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
|
||||
0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
|
||||
PHYREGS(0x08B0, 0x08AC, 0x08A8, 0x01D7, 0x01D8, 0x01D9),
|
||||
|
@ -808,7 +808,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 112,
|
||||
.freq = 5560, /* MHz */
|
||||
.unk2 = 3707,
|
||||
RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2C, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
|
||||
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08B4, 0x08B0, 0x08AC, 0x01D7, 0x01D7, 0x01D8),
|
||||
|
@ -816,7 +816,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 114,
|
||||
.freq = 5570, /* MHz */
|
||||
.unk2 = 3713,
|
||||
RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2D, 0x02, 0x05, 0x34, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
|
||||
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08B8, 0x08B4, 0x08B0, 0x01D6, 0x01D7, 0x01D7),
|
||||
|
@ -824,7 +824,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 116,
|
||||
.freq = 5580, /* MHz */
|
||||
.unk2 = 3720,
|
||||
RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2E, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
|
||||
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08BC, 0x08B8, 0x08B4, 0x01D5, 0x01D6, 0x01D7),
|
||||
|
@ -832,7 +832,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 118,
|
||||
.freq = 5590, /* MHz */
|
||||
.unk2 = 3727,
|
||||
RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x2F, 0x02, 0x04, 0x2E, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
|
||||
0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08C0, 0x08BC, 0x08B8, 0x01D4, 0x01D5, 0x01D6),
|
||||
|
@ -840,7 +840,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 120,
|
||||
.freq = 5600, /* MHz */
|
||||
.unk2 = 3733,
|
||||
RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x30, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
|
||||
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08C4, 0x08C0, 0x08BC, 0x01D3, 0x01D4, 0x01D5),
|
||||
|
@ -848,7 +848,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 122,
|
||||
.freq = 5610, /* MHz */
|
||||
.unk2 = 3740,
|
||||
RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x31, 0x02, 0x04, 0x28, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
|
||||
0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
|
||||
PHYREGS(0x08C8, 0x08C4, 0x08C0, 0x01D2, 0x01D3, 0x01D4),
|
||||
|
@ -856,7 +856,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 124,
|
||||
.freq = 5620, /* MHz */
|
||||
.unk2 = 3747,
|
||||
RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x32, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08CC, 0x08C8, 0x08C4, 0x01D2, 0x01D2, 0x01D3),
|
||||
|
@ -864,7 +864,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 126,
|
||||
.freq = 5630, /* MHz */
|
||||
.unk2 = 3753,
|
||||
RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x33, 0x02, 0x04, 0x21, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08D0, 0x08CC, 0x08C8, 0x01D1, 0x01D2, 0x01D2),
|
||||
|
@ -872,7 +872,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 128,
|
||||
.freq = 5640, /* MHz */
|
||||
.unk2 = 3760,
|
||||
RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x34, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08D4, 0x08D0, 0x08CC, 0x01D0, 0x01D1, 0x01D2),
|
||||
|
@ -880,7 +880,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 130,
|
||||
.freq = 5650, /* MHz */
|
||||
.unk2 = 3767,
|
||||
RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x35, 0x02, 0x03, 0x1C, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08D8, 0x08D4, 0x08D0, 0x01CF, 0x01D0, 0x01D1),
|
||||
|
@ -888,7 +888,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 132,
|
||||
.freq = 5660, /* MHz */
|
||||
.unk2 = 3773,
|
||||
RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x36, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08DC, 0x08D8, 0x08D4, 0x01CE, 0x01CF, 0x01D0),
|
||||
|
@ -896,7 +896,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 134,
|
||||
.freq = 5670, /* MHz */
|
||||
.unk2 = 3780,
|
||||
RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x37, 0x02, 0x03, 0x16, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08E0, 0x08DC, 0x08D8, 0x01CE, 0x01CE, 0x01CF),
|
||||
|
@ -904,7 +904,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 136,
|
||||
.freq = 5680, /* MHz */
|
||||
.unk2 = 3787,
|
||||
RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x38, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08E4, 0x08E0, 0x08DC, 0x01CD, 0x01CE, 0x01CE),
|
||||
|
@ -912,7 +912,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 138,
|
||||
.freq = 5690, /* MHz */
|
||||
.unk2 = 3793,
|
||||
RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x39, 0x02, 0x03, 0x10, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08E8, 0x08E4, 0x08E0, 0x01CC, 0x01CD, 0x01CE),
|
||||
|
@ -920,7 +920,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 140,
|
||||
.freq = 5700, /* MHz */
|
||||
.unk2 = 3800,
|
||||
RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3A, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08EC, 0x08E8, 0x08E4, 0x01CB, 0x01CC, 0x01CD),
|
||||
|
@ -928,7 +928,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 142,
|
||||
.freq = 5710, /* MHz */
|
||||
.unk2 = 3807,
|
||||
RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3B, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08F0, 0x08EC, 0x08E8, 0x01CA, 0x01CB, 0x01CC),
|
||||
|
@ -936,7 +936,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 144,
|
||||
.freq = 5720, /* MHz */
|
||||
.unk2 = 3813,
|
||||
RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3C, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08F4, 0x08F0, 0x08EC, 0x01C9, 0x01CA, 0x01CB),
|
||||
|
@ -944,7 +944,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 145,
|
||||
.freq = 5725, /* MHz */
|
||||
.unk2 = 3817,
|
||||
RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x79, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08F6, 0x08F2, 0x08EE, 0x01C9, 0x01CA, 0x01CB),
|
||||
|
@ -952,7 +952,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 146,
|
||||
.freq = 5730, /* MHz */
|
||||
.unk2 = 3820,
|
||||
RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3D, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08F8, 0x08F4, 0x08F0, 0x01C9, 0x01C9, 0x01CA),
|
||||
|
@ -960,7 +960,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 147,
|
||||
.freq = 5735, /* MHz */
|
||||
.unk2 = 3823,
|
||||
RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x7B, 0x04, 0x02, 0x03, 0x01, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08FA, 0x08F6, 0x08F2, 0x01C8, 0x01C9, 0x01CA),
|
||||
|
@ -968,7 +968,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 148,
|
||||
.freq = 5740, /* MHz */
|
||||
.unk2 = 3827,
|
||||
RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3E, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08FC, 0x08F8, 0x08F4, 0x01C8, 0x01C9, 0x01C9),
|
||||
|
@ -976,7 +976,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 149,
|
||||
.freq = 5745, /* MHz */
|
||||
.unk2 = 3830,
|
||||
RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x7D, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x08FE, 0x08FA, 0x08F6, 0x01C8, 0x01C8, 0x01C9),
|
||||
|
@ -984,7 +984,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 150,
|
||||
.freq = 5750, /* MHz */
|
||||
.unk2 = 3833,
|
||||
RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x3F, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0900, 0x08FC, 0x08F8, 0x01C7, 0x01C8, 0x01C9),
|
||||
|
@ -992,7 +992,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 151,
|
||||
.freq = 5755, /* MHz */
|
||||
.unk2 = 3837,
|
||||
RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x7F, 0x04, 0x02, 0xFE, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0902, 0x08FE, 0x08FA, 0x01C7, 0x01C8, 0x01C8),
|
||||
|
@ -1000,7 +1000,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 152,
|
||||
.freq = 5760, /* MHz */
|
||||
.unk2 = 3840,
|
||||
RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x40, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0904, 0x0900, 0x08FC, 0x01C6, 0x01C7, 0x01C8),
|
||||
|
@ -1008,7 +1008,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 153,
|
||||
.freq = 5765, /* MHz */
|
||||
.unk2 = 3843,
|
||||
RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x81, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0906, 0x0902, 0x08FE, 0x01C6, 0x01C7, 0x01C8),
|
||||
|
@ -1016,7 +1016,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 154,
|
||||
.freq = 5770, /* MHz */
|
||||
.unk2 = 3847,
|
||||
RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x41, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0908, 0x0904, 0x0900, 0x01C6, 0x01C6, 0x01C7),
|
||||
|
@ -1024,7 +1024,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 155,
|
||||
.freq = 5775, /* MHz */
|
||||
.unk2 = 3850,
|
||||
RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x83, 0x04, 0x02, 0xF8, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x090A, 0x0906, 0x0902, 0x01C5, 0x01C6, 0x01C7),
|
||||
|
@ -1032,7 +1032,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 156,
|
||||
.freq = 5780, /* MHz */
|
||||
.unk2 = 3853,
|
||||
RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x42, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x090C, 0x0908, 0x0904, 0x01C5, 0x01C6, 0x01C6),
|
||||
|
@ -1040,7 +1040,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 157,
|
||||
.freq = 5785, /* MHz */
|
||||
.unk2 = 3857,
|
||||
RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x85, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x090E, 0x090A, 0x0906, 0x01C4, 0x01C5, 0x01C6),
|
||||
|
@ -1048,7 +1048,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 158,
|
||||
.freq = 5790, /* MHz */
|
||||
.unk2 = 3860,
|
||||
RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x43, 0x02, 0x02, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0910, 0x090C, 0x0908, 0x01C4, 0x01C5, 0x01C6),
|
||||
|
@ -1056,7 +1056,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 159,
|
||||
.freq = 5795, /* MHz */
|
||||
.unk2 = 3863,
|
||||
RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x87, 0x04, 0x02, 0xF2, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0912, 0x090E, 0x090A, 0x01C4, 0x01C4, 0x01C5),
|
||||
|
@ -1064,7 +1064,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 160,
|
||||
.freq = 5800, /* MHz */
|
||||
.unk2 = 3867,
|
||||
RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x44, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0914, 0x0910, 0x090C, 0x01C3, 0x01C4, 0x01C5),
|
||||
|
@ -1072,7 +1072,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 161,
|
||||
.freq = 5805, /* MHz */
|
||||
.unk2 = 3870,
|
||||
RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x89, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0916, 0x0912, 0x090E, 0x01C3, 0x01C4, 0x01C4),
|
||||
|
@ -1080,7 +1080,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 162,
|
||||
.freq = 5810, /* MHz */
|
||||
.unk2 = 3873,
|
||||
RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x45, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0918, 0x0914, 0x0910, 0x01C2, 0x01C3, 0x01C4),
|
||||
|
@ -1088,7 +1088,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 163,
|
||||
.freq = 5815, /* MHz */
|
||||
.unk2 = 3877,
|
||||
RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x8B, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x091A, 0x0916, 0x0912, 0x01C2, 0x01C3, 0x01C4),
|
||||
|
@ -1096,7 +1096,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 164,
|
||||
.freq = 5820, /* MHz */
|
||||
.unk2 = 3880,
|
||||
RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x46, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x091C, 0x0918, 0x0914, 0x01C2, 0x01C2, 0x01C3),
|
||||
|
@ -1104,7 +1104,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 165,
|
||||
.freq = 5825, /* MHz */
|
||||
.unk2 = 3883,
|
||||
RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
RADIOREGS(0x72, 0x8D, 0x04, 0x01, 0xED, 0x00, 0x03, 0x14,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x091E, 0x091A, 0x0916, 0x01C1, 0x01C2, 0x01C3),
|
||||
|
@ -1112,7 +1112,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 166,
|
||||
.freq = 5830, /* MHz */
|
||||
.unk2 = 3887,
|
||||
RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x47, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0920, 0x091C, 0x0918, 0x01C1, 0x01C2, 0x01C2),
|
||||
|
@ -1120,7 +1120,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 168,
|
||||
.freq = 5840, /* MHz */
|
||||
.unk2 = 3893,
|
||||
RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x48, 0x02, 0x01, 0x0A, 0x01, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0924, 0x0920, 0x091C, 0x01C0, 0x01C1, 0x01C2),
|
||||
|
@ -1128,7 +1128,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 170,
|
||||
.freq = 5850, /* MHz */
|
||||
.unk2 = 3900,
|
||||
RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x49, 0x02, 0x01, 0xE0, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0928, 0x0924, 0x0920, 0x01BF, 0x01C0, 0x01C1),
|
||||
|
@ -1136,7 +1136,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 172,
|
||||
.freq = 5860, /* MHz */
|
||||
.unk2 = 3907,
|
||||
RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4A, 0x02, 0x01, 0xDE, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x092C, 0x0928, 0x0924, 0x01BF, 0x01BF, 0x01C0),
|
||||
|
@ -1144,7 +1144,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 174,
|
||||
.freq = 5870, /* MHz */
|
||||
.unk2 = 3913,
|
||||
RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4B, 0x02, 0x00, 0xDB, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0930, 0x092C, 0x0928, 0x01BE, 0x01BF, 0x01BF),
|
||||
|
@ -1152,7 +1152,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 176,
|
||||
.freq = 5880, /* MHz */
|
||||
.unk2 = 3920,
|
||||
RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4C, 0x02, 0x00, 0xD8, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0934, 0x0930, 0x092C, 0x01BD, 0x01BE, 0x01BF),
|
||||
|
@ -1160,7 +1160,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 178,
|
||||
.freq = 5890, /* MHz */
|
||||
.unk2 = 3927,
|
||||
RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4D, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0938, 0x0934, 0x0930, 0x01BC, 0x01BD, 0x01BE),
|
||||
|
@ -1168,7 +1168,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 180,
|
||||
.freq = 5900, /* MHz */
|
||||
.unk2 = 3933,
|
||||
RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4E, 0x02, 0x00, 0xD3, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x093C, 0x0938, 0x0934, 0x01BC, 0x01BC, 0x01BD),
|
||||
|
@ -1176,7 +1176,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 182,
|
||||
.freq = 5910, /* MHz */
|
||||
.unk2 = 3940,
|
||||
RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
|
||||
RADIOREGS(0x71, 0x4F, 0x02, 0x00, 0xD6, 0x00, 0x04, 0x0A,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
|
||||
PHYREGS(0x0940, 0x093C, 0x0938, 0x01BB, 0x01BC, 0x01BC),
|
||||
|
@ -1184,7 +1184,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 1,
|
||||
.freq = 2412, /* MHz */
|
||||
.unk2 = 3216,
|
||||
RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x6C, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
|
||||
0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
|
||||
PHYREGS(0x03C9, 0x03C5, 0x03C1, 0x043A, 0x043F, 0x0443),
|
||||
|
@ -1192,7 +1192,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 2,
|
||||
.freq = 2417, /* MHz */
|
||||
.unk2 = 3223,
|
||||
RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x71, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
|
||||
0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
|
||||
PHYREGS(0x03CB, 0x03C7, 0x03C3, 0x0438, 0x043D, 0x0441),
|
||||
|
@ -1200,7 +1200,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 3,
|
||||
.freq = 2422, /* MHz */
|
||||
.unk2 = 3229,
|
||||
RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x76, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
|
||||
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
|
||||
PHYREGS(0x03CD, 0x03C9, 0x03C5, 0x0436, 0x043A, 0x043F),
|
||||
|
@ -1208,7 +1208,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 4,
|
||||
.freq = 2427, /* MHz */
|
||||
.unk2 = 3236,
|
||||
RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x7B, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
|
||||
0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
|
||||
PHYREGS(0x03CF, 0x03CB, 0x03C7, 0x0434, 0x0438, 0x043D),
|
||||
|
@ -1216,7 +1216,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 5,
|
||||
.freq = 2432, /* MHz */
|
||||
.unk2 = 3243,
|
||||
RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x80, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
|
||||
0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
|
||||
PHYREGS(0x03D1, 0x03CD, 0x03C9, 0x0431, 0x0436, 0x043A),
|
||||
|
@ -1224,7 +1224,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 6,
|
||||
.freq = 2437, /* MHz */
|
||||
.unk2 = 3249,
|
||||
RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x85, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
|
||||
0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
|
||||
PHYREGS(0x03D3, 0x03CF, 0x03CB, 0x042F, 0x0434, 0x0438),
|
||||
|
@ -1232,7 +1232,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 7,
|
||||
.freq = 2442, /* MHz */
|
||||
.unk2 = 3256,
|
||||
RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x8A, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
|
||||
0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
|
||||
PHYREGS(0x03D5, 0x03D1, 0x03CD, 0x042D, 0x0431, 0x0436),
|
||||
|
@ -1240,7 +1240,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 8,
|
||||
.freq = 2447, /* MHz */
|
||||
.unk2 = 3263,
|
||||
RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x8F, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
|
||||
0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
|
||||
PHYREGS(0x03D7, 0x03D3, 0x03CF, 0x042B, 0x042F, 0x0434),
|
||||
|
@ -1248,7 +1248,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 9,
|
||||
.freq = 2452, /* MHz */
|
||||
.unk2 = 3269,
|
||||
RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x94, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
|
||||
0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
|
||||
PHYREGS(0x03D9, 0x03D5, 0x03D1, 0x0429, 0x042D, 0x0431),
|
||||
|
@ -1256,7 +1256,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 10,
|
||||
.freq = 2457, /* MHz */
|
||||
.unk2 = 3276,
|
||||
RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x99, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
|
||||
0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
|
||||
PHYREGS(0x03DB, 0x03D7, 0x03D3, 0x0427, 0x042B, 0x042F),
|
||||
|
@ -1264,7 +1264,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 11,
|
||||
.freq = 2462, /* MHz */
|
||||
.unk2 = 3283,
|
||||
RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0x9E, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
|
||||
0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
|
||||
PHYREGS(0x03DD, 0x03D9, 0x03D5, 0x0424, 0x0429, 0x042D),
|
||||
|
@ -1272,7 +1272,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 12,
|
||||
.freq = 2467, /* MHz */
|
||||
.unk2 = 3289,
|
||||
RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0xA3, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
|
||||
0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
|
||||
PHYREGS(0x03DF, 0x03DB, 0x03D7, 0x0422, 0x0427, 0x042B),
|
||||
|
@ -1280,7 +1280,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 13,
|
||||
.freq = 2472, /* MHz */
|
||||
.unk2 = 3296,
|
||||
RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0xA8, 0x09, 0x0F, 0x00, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
|
||||
0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
|
||||
PHYREGS(0x03E1, 0x03DD, 0x03D9, 0x0420, 0x0424, 0x0429),
|
||||
|
@ -1288,7 +1288,7 @@ static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] =
|
|||
{ .channel = 14,
|
||||
.freq = 2484, /* MHz */
|
||||
.unk2 = 3312,
|
||||
RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
|
||||
RADIOREGS(0x73, 0xB4, 0x09, 0x0F, 0xFF, 0x01, 0x07, 0x15,
|
||||
0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
|
||||
0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
|
||||
PHYREGS(0x03E6, 0x03E2, 0x03DE, 0x041B, 0x041F, 0x0424),
|
||||
|
|
|
@ -278,8 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
|
|||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
|
@ -294,8 +292,6 @@ struct iwl_cfg iwl1000_bg_cfg = {
|
|||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
|
@ -305,12 +301,10 @@ struct iwl_cfg iwl1000_bg_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.name = "Intel(R) 100 Series 1x1 BGN",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
|
||||
.fw_name_pre = IWL100_FW_PRE,
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
|
@ -321,12 +315,10 @@ struct iwl_cfg iwl100_bgn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl100_bg_cfg = {
|
||||
.name = "Intel(R) 100 Series 1x1 BG",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BG",
|
||||
.fw_name_pre = IWL100_FW_PRE,
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
|
|
|
@ -527,8 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
|
|||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
|
@ -543,8 +541,8 @@ struct iwl_cfg iwl5100_bgn_cfg = {
|
|||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
|
@ -559,8 +557,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
|
|||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
|
@ -574,8 +572,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
|
|||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_B,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
|
@ -590,8 +588,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
|||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
|
@ -606,8 +602,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
|
|||
.fw_name_pre = IWL5150_FW_PRE,
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
|
@ -623,8 +617,6 @@ struct iwl_cfg iwl5150_abg_cfg = {
|
|||
.fw_name_pre = IWL5150_FW_PRE,
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
|
|
|
@ -553,12 +553,10 @@ static struct iwl_bt_params iwl6000_bt_params = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2a_2agn_cfg = {
|
||||
.name = "6000 Series 2x2 AGN Gen2a",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -571,12 +569,10 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2a_2abg_cfg = {
|
||||
.name = "6000 Series 2x2 ABG Gen2a",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -588,12 +584,10 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2a_2bg_cfg = {
|
||||
.name = "6000 Series 2x2 BG Gen2a",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -605,12 +599,10 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2agn_cfg = {
|
||||
.name = "6000 Series 2x2 AGN Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -627,12 +619,10 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
||||
.name = "6000 Series 2x2 ABG Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -648,12 +638,10 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
||||
.name = "6000 Series 2x2 BGN Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -670,12 +658,10 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
||||
.name = "6000 Series 2x2 BG Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -691,12 +677,10 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
||||
.name = "6000 Series 1x2 BGN Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -713,12 +697,10 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bg_cfg = {
|
||||
.name = "6000 Series 1x2 BG Gen2b",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -741,8 +723,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
|
|||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.valid_tx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -758,8 +740,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
|
|||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.valid_tx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -774,8 +756,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
|
|||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_BC,
|
||||
.valid_rx_ant = ANT_BC,
|
||||
.valid_tx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_BC, /* .cfg overwrite */
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -790,8 +772,6 @@ struct iwl_cfg iwl6050_2agn_cfg = {
|
|||
.fw_name_pre = IWL6050_FW_PRE,
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.ops = &iwl6050_ops,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
|
@ -803,12 +783,10 @@ struct iwl_cfg iwl6050_2agn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl6050g2_bgn_cfg = {
|
||||
.name = "6050 Series 1x2 BGN Gen2",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
|
||||
.fw_name_pre = IWL6050_FW_PRE,
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6050g2_ops,
|
||||
|
@ -824,8 +802,6 @@ struct iwl_cfg iwl6050_2abg_cfg = {
|
|||
.fw_name_pre = IWL6050_FW_PRE,
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_AB,
|
||||
.valid_rx_ant = ANT_AB,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.ops = &iwl6050_ops,
|
||||
|
@ -840,8 +816,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
|||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_ABC,
|
||||
.valid_rx_ant = ANT_ABC,
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
|
@ -853,12 +827,10 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl130_bgn_cfg = {
|
||||
.name = "Intel(R) 130 Series 1x1 BGN",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
@ -874,12 +846,10 @@ struct iwl_cfg iwl130_bgn_cfg = {
|
|||
};
|
||||
|
||||
struct iwl_cfg iwl130_bg_cfg = {
|
||||
.name = "Intel(R) 130 Series 1x2 BG",
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BG",
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE,
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
|
||||
.valid_tx_ant = ANT_A,
|
||||
.valid_rx_ant = ANT_A,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
|
|
|
@ -251,6 +251,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
|
|||
int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||
{
|
||||
u16 eeprom_sku;
|
||||
u16 radio_cfg;
|
||||
|
||||
eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
|
||||
|
||||
|
@ -266,6 +267,25 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
|||
|
||||
IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku);
|
||||
|
||||
if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) {
|
||||
/* not using .cfg overwrite */
|
||||
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
|
||||
priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
||||
priv->cfg->valid_rx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
||||
if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
|
||||
IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n",
|
||||
priv->cfg->valid_tx_ant,
|
||||
priv->cfg->valid_rx_ant);
|
||||
return -EINVAL;
|
||||
}
|
||||
IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n",
|
||||
priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant);
|
||||
}
|
||||
/*
|
||||
* for some special cases,
|
||||
* EEPROM did not reflect the correct antenna setting
|
||||
* so overwrite the valid tx/rx antenna from .cfg
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1778,7 +1778,7 @@ static const __le32 iwlagn_def_3w_lookup[12] = {
|
|||
cpu_to_le32(0xc0004000),
|
||||
cpu_to_le32(0x00004000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
cpu_to_le32(0xf0004000),
|
||||
cpu_to_le32(0xf0005000),
|
||||
};
|
||||
|
||||
static const __le32 iwlagn_concurrent_lookup[12] = {
|
||||
|
@ -1814,6 +1814,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
|
|||
bt_cmd.prio_boost = 0;
|
||||
bt_cmd.kill_ack_mask = priv->kill_ack_mask;
|
||||
bt_cmd.kill_cts_mask = priv->kill_cts_mask;
|
||||
|
||||
bt_cmd.valid = priv->bt_valid;
|
||||
bt_cmd.tx_prio_boost = 0;
|
||||
bt_cmd.rx_prio_boost = 0;
|
||||
|
@ -1996,24 +1997,29 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv,
|
|||
BT_UART_MSG_FRAME7CONNECTABLE_POS);
|
||||
}
|
||||
|
||||
static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
|
||||
struct iwl_bt_uart_msg *uart_msg)
|
||||
static void iwlagn_set_kill_msk(struct iwl_priv *priv,
|
||||
struct iwl_bt_uart_msg *uart_msg)
|
||||
{
|
||||
u8 kill_ack_msk;
|
||||
u8 kill_msk;
|
||||
static const __le32 bt_kill_ack_msg[2] = {
|
||||
cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
|
||||
IWLAGN_BT_KILL_ACK_MASK_DEFAULT,
|
||||
IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
|
||||
static const __le32 bt_kill_cts_msg[2] = {
|
||||
IWLAGN_BT_KILL_CTS_MASK_DEFAULT,
|
||||
IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
|
||||
|
||||
kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
|
||||
BT_UART_MSG_FRAME3SNIFF_MSK |
|
||||
BT_UART_MSG_FRAME3SCOESCO_MSK) &
|
||||
uart_msg->frame3) == 0) ? 1 : 0;
|
||||
if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
|
||||
kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3)
|
||||
? 1 : 0;
|
||||
if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] ||
|
||||
priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) {
|
||||
priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
|
||||
priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
|
||||
priv->kill_ack_mask = bt_kill_ack_msg[kill_msk];
|
||||
priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK;
|
||||
priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
|
||||
|
||||
/* schedule to send runtime bt_config */
|
||||
queue_work(priv->workqueue, &priv->bt_runtime_config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
|
||||
|
@ -2064,7 +2070,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
|
|||
}
|
||||
}
|
||||
|
||||
iwlagn_set_kill_ack_msk(priv, uart_msg);
|
||||
iwlagn_set_kill_msk(priv, uart_msg);
|
||||
|
||||
/* FIXME: based on notification, adjust the prio_boost */
|
||||
|
||||
|
|
|
@ -67,8 +67,14 @@
|
|||
*/
|
||||
|
||||
static const u8 tid_to_ac[] = {
|
||||
/* this matches the mac80211 numbers */
|
||||
2, 3, 3, 2, 1, 1, 0, 0
|
||||
IEEE80211_AC_BE,
|
||||
IEEE80211_AC_BK,
|
||||
IEEE80211_AC_BK,
|
||||
IEEE80211_AC_BE,
|
||||
IEEE80211_AC_VI,
|
||||
IEEE80211_AC_VI,
|
||||
IEEE80211_AC_VO,
|
||||
IEEE80211_AC_VO
|
||||
};
|
||||
|
||||
static inline int get_ac_from_tid(u16 tid)
|
||||
|
@ -531,6 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
|||
u8 tid = 0;
|
||||
u8 *qc = NULL;
|
||||
unsigned long flags;
|
||||
bool is_agg = false;
|
||||
|
||||
if (info->control.vif)
|
||||
ctx = iwl_rxon_ctx_from_vif(info->control.vif);
|
||||
|
@ -567,8 +574,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
|||
if (sta)
|
||||
sta_priv = (void *)sta->drv_priv;
|
||||
|
||||
if (sta_priv && sta_priv->asleep) {
|
||||
WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
|
||||
if (sta_priv && sta_priv->asleep &&
|
||||
(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
|
||||
/*
|
||||
* This sends an asynchronous command to the device,
|
||||
* but we can rely on it being processed before the
|
||||
|
@ -616,6 +623,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
|||
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
|
||||
priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
|
||||
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
|
||||
is_agg = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,8 +771,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
|||
* whether or not we should update the write pointer.
|
||||
*/
|
||||
|
||||
/* avoid atomic ops if it isn't an associated client */
|
||||
if (sta_priv && sta_priv->client)
|
||||
/*
|
||||
* Avoid atomic ops if it isn't an associated client.
|
||||
* Also, if this is a packet for aggregation, don't
|
||||
* increase the counter because the ucode will stop
|
||||
* aggregation queues when their respective station
|
||||
* goes to sleep.
|
||||
*/
|
||||
if (sta_priv && sta_priv->client && !is_agg)
|
||||
atomic_inc(&sta_priv->pending_frames);
|
||||
|
||||
if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
|
||||
|
@ -1143,14 +1157,15 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
|
||||
static void iwlagn_non_agg_tx_status(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx,
|
||||
const u8 *addr1)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
|
||||
struct ieee80211_sta *sta;
|
||||
struct iwl_station_priv *sta_priv;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
|
||||
sta = ieee80211_find_sta(ctx->vif, addr1);
|
||||
if (sta) {
|
||||
sta_priv = (void *)sta->drv_priv;
|
||||
/* avoid atomic ops if this isn't a client */
|
||||
|
@ -1159,6 +1174,15 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
|
|||
ieee80211_sta_block_awake(priv->hw, sta, false);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info,
|
||||
bool is_agg)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
|
||||
|
||||
if (!is_agg)
|
||||
iwlagn_non_agg_tx_status(priv, tx_info->ctx, hdr->addr1);
|
||||
|
||||
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
|
||||
}
|
||||
|
@ -1183,7 +1207,8 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
|
|||
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
|
||||
|
||||
tx_info = &txq->txb[txq->q.read_ptr];
|
||||
iwlagn_tx_status(priv, tx_info);
|
||||
iwlagn_tx_status(priv, tx_info,
|
||||
txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)tx_info->skb->data;
|
||||
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
|
||||
|
|
|
@ -47,10 +47,10 @@ struct queue_to_fifo_ac {
|
|||
};
|
||||
|
||||
static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
|
||||
{ IWL_TX_FIFO_VO, 0, },
|
||||
{ IWL_TX_FIFO_VI, 1, },
|
||||
{ IWL_TX_FIFO_BE, 2, },
|
||||
{ IWL_TX_FIFO_BK, 3, },
|
||||
{ IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
|
||||
{ IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
|
||||
{ IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
|
||||
{ IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
|
||||
{ IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
|
||||
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
|
||||
{ IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
|
||||
|
@ -60,14 +60,14 @@ static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
|
|||
};
|
||||
|
||||
static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
|
||||
{ IWL_TX_FIFO_VO, 0, },
|
||||
{ IWL_TX_FIFO_VI, 1, },
|
||||
{ IWL_TX_FIFO_BE, 2, },
|
||||
{ IWL_TX_FIFO_BK, 3, },
|
||||
{ IWL_TX_FIFO_BK_IPAN, 3, },
|
||||
{ IWL_TX_FIFO_BE_IPAN, 2, },
|
||||
{ IWL_TX_FIFO_VI_IPAN, 1, },
|
||||
{ IWL_TX_FIFO_VO_IPAN, 0, },
|
||||
{ IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
|
||||
{ IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
|
||||
{ IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
|
||||
{ IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
|
||||
{ IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
|
||||
{ IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
|
||||
{ IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
|
||||
{ IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
|
||||
{ IWL_TX_FIFO_BE_IPAN, 2, },
|
||||
{ IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
|
||||
};
|
||||
|
|
|
@ -3175,7 +3175,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
|
|||
hw->flags = IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_AMPDU_AGGREGATION |
|
||||
IEEE80211_HW_NEED_DTIM_PERIOD |
|
||||
IEEE80211_HW_SPECTRUM_MGMT;
|
||||
IEEE80211_HW_SPECTRUM_MGMT |
|
||||
IEEE80211_HW_REPORTS_TX_ACK_STATUS;
|
||||
|
||||
if (!priv->cfg->base_params->broken_powersave)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
|
||||
|
|
|
@ -2453,6 +2453,7 @@ struct iwl_bt_cmd {
|
|||
|
||||
#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000)
|
||||
#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000)
|
||||
#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff)
|
||||
|
||||
#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
|
||||
|
||||
|
|
|
@ -410,7 +410,6 @@ struct iwl_eeprom_calib_info {
|
|||
#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
|
||||
#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
|
||||
#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
|
||||
#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */
|
||||
#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */
|
||||
|
||||
/* The following masks are to be applied on EEPROM_RADIO_CONFIG */
|
||||
|
|
|
@ -183,7 +183,7 @@ static void p54u_rx_cb(struct urb *urb)
|
|||
static void p54u_tx_cb(struct urb *urb)
|
||||
{
|
||||
struct sk_buff *skb = urb->context;
|
||||
struct ieee80211_hw *dev = (struct ieee80211_hw *)
|
||||
struct ieee80211_hw *dev =
|
||||
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
|
||||
|
||||
p54_free_skb(dev, skb);
|
||||
|
|
|
@ -1776,11 +1776,8 @@ static void ray_update_multi_list(struct net_device *dev, int all)
|
|||
/* Copy the kernel's list of MC addresses to card */
|
||||
netdev_for_each_mc_addr(ha, dev) {
|
||||
memcpy_toio(p, ha->addr, ETH_ALEN);
|
||||
dev_dbg(&link->dev,
|
||||
"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
|
||||
ha->addr[0], ha->addr[1],
|
||||
ha->addr[2], ha->addr[3],
|
||||
ha->addr[4], ha->addr[5]);
|
||||
dev_dbg(&link->dev, "ray_update_multi add addr %pm\n",
|
||||
ha->addr);
|
||||
p += ETH_ALEN;
|
||||
i++;
|
||||
}
|
||||
|
@ -2015,11 +2012,8 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
|
|||
memcpy_fromio(&local->bss_id,
|
||||
prcs->var.rejoin_net_complete.
|
||||
bssid, ADDRLEN);
|
||||
dev_dbg(&link->dev,
|
||||
"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
|
||||
local->bss_id[0], local->bss_id[1],
|
||||
local->bss_id[2], local->bss_id[3],
|
||||
local->bss_id[4], local->bss_id[5]);
|
||||
dev_dbg(&link->dev, "ray_cs new BSSID = %pm\n",
|
||||
local->bss_id);
|
||||
if (!sniffer)
|
||||
authenticate(local);
|
||||
}
|
||||
|
|
|
@ -911,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
|||
__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
|
||||
if (!modparam_nohwcrypt)
|
||||
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
|
||||
|
|
|
@ -664,6 +664,7 @@ enum rt2x00_flags {
|
|||
DRIVER_REQUIRE_COPY_IV,
|
||||
DRIVER_REQUIRE_L2PAD,
|
||||
DRIVER_REQUIRE_TXSTATUS_FIFO,
|
||||
DRIVER_REQUIRE_TASKLET_CONTEXT,
|
||||
|
||||
/*
|
||||
* Driver features
|
||||
|
|
|
@ -379,9 +379,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
|
|||
* through a mac80211 library call (RTS/CTS) then we should not
|
||||
* send the status report back.
|
||||
*/
|
||||
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
|
||||
ieee80211_tx_status(rt2x00dev->hw, entry->skb);
|
||||
else
|
||||
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
|
||||
if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
|
||||
ieee80211_tx_status(rt2x00dev->hw, entry->skb);
|
||||
else
|
||||
ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
|
||||
} else
|
||||
dev_kfree_skb_any(entry->skb);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1830,7 +1830,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
|||
|
||||
static void zd1201_disconnect(struct usb_interface *interface)
|
||||
{
|
||||
struct zd1201 *zd=(struct zd1201 *)usb_get_intfdata(interface);
|
||||
struct zd1201 *zd = usb_get_intfdata(interface);
|
||||
struct hlist_node *node, *node2;
|
||||
struct zd1201_frag *frag;
|
||||
|
||||
|
|
|
@ -383,6 +383,35 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||
ssb_dev->id.revision);
|
||||
}
|
||||
|
||||
#define ssb_config_attr(attrib, field, format_string) \
|
||||
static ssize_t \
|
||||
attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
|
||||
}
|
||||
|
||||
ssb_config_attr(core_num, core_index, "%u\n")
|
||||
ssb_config_attr(coreid, id.coreid, "0x%04x\n")
|
||||
ssb_config_attr(vendor, id.vendor, "0x%04x\n")
|
||||
ssb_config_attr(revision, id.revision, "%u\n")
|
||||
ssb_config_attr(irq, irq, "%u\n")
|
||||
static ssize_t
|
||||
name_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n",
|
||||
ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
|
||||
}
|
||||
|
||||
static struct device_attribute ssb_device_attrs[] = {
|
||||
__ATTR_RO(name),
|
||||
__ATTR_RO(core_num),
|
||||
__ATTR_RO(coreid),
|
||||
__ATTR_RO(vendor),
|
||||
__ATTR_RO(revision),
|
||||
__ATTR_RO(irq),
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
static struct bus_type ssb_bustype = {
|
||||
.name = "ssb",
|
||||
.match = ssb_bus_match,
|
||||
|
@ -392,6 +421,7 @@ static struct bus_type ssb_bustype = {
|
|||
.suspend = ssb_device_suspend,
|
||||
.resume = ssb_device_resume,
|
||||
.uevent = ssb_device_uevent,
|
||||
.dev_attrs = ssb_device_attrs,
|
||||
};
|
||||
|
||||
static void ssb_buses_lock(void)
|
||||
|
|
|
@ -406,6 +406,46 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
|
|||
out->antenna_gain.ghz5.a3 = gain;
|
||||
}
|
||||
|
||||
/* Revs 4 5 and 8 have partially shared layout */
|
||||
static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
|
||||
{
|
||||
SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
|
||||
SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
|
||||
SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
|
||||
SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
|
||||
SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
|
||||
SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
|
||||
SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
|
||||
SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
|
||||
|
||||
SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
|
||||
SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
|
||||
SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
|
||||
SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
|
||||
SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
|
||||
SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
|
||||
SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
|
||||
SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
|
||||
|
||||
SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
|
||||
SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
|
||||
SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
|
||||
SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
|
||||
SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
|
||||
SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
|
||||
SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
|
||||
SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
|
||||
|
||||
SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
|
||||
SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
|
||||
SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
|
||||
SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
|
||||
SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
|
||||
SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
|
||||
SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
|
||||
SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
|
||||
}
|
||||
|
||||
static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
|
||||
{
|
||||
int i;
|
||||
|
@ -471,6 +511,8 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
|
|||
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
|
||||
sizeof(out->antenna_gain.ghz5));
|
||||
|
||||
sprom_extract_r458(out, in);
|
||||
|
||||
/* TODO - get remaining rev 4 stuff needed */
|
||||
}
|
||||
|
||||
|
@ -561,6 +603,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
|
|||
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
|
||||
sizeof(out->antenna_gain.ghz5));
|
||||
|
||||
sprom_extract_r458(out, in);
|
||||
|
||||
/* TODO - get remaining rev 8 stuff needed */
|
||||
}
|
||||
|
||||
|
|
|
@ -358,11 +358,16 @@
|
|||
* user space application). %NL80211_ATTR_FRAME is used to specify the
|
||||
* frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
|
||||
* optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on
|
||||
* which channel the frame is to be transmitted or was received. This
|
||||
* channel has to be the current channel (remain-on-channel or the
|
||||
* operational channel). When called, this operation returns a cookie
|
||||
* (%NL80211_ATTR_COOKIE) that will be included with the TX status event
|
||||
* pertaining to the TX request.
|
||||
* which channel the frame is to be transmitted or was received. If this
|
||||
* channel is not the current channel (remain-on-channel or the
|
||||
* operational channel) the device will switch to the given channel and
|
||||
* transmit the frame, optionally waiting for a response for the time
|
||||
* specified using %NL80211_ATTR_DURATION. When called, this operation
|
||||
* returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
|
||||
* TX status event pertaining to the TX request.
|
||||
* @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
|
||||
* command may be used with the corresponding cookie to cancel the wait
|
||||
* time if it is known that it is no longer necessary.
|
||||
* @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
|
||||
* @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
|
||||
* transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
|
||||
|
@ -493,6 +498,8 @@ enum nl80211_commands {
|
|||
NL80211_CMD_SET_CHANNEL,
|
||||
NL80211_CMD_SET_WDS_PEER,
|
||||
|
||||
NL80211_CMD_FRAME_WAIT_CANCEL,
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
|
@ -828,6 +835,12 @@ enum nl80211_commands {
|
|||
*
|
||||
* @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
|
||||
*
|
||||
* @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
|
||||
* transmitted on another channel when the channel given doesn't match
|
||||
* the current channel. If the current channel doesn't match and this
|
||||
* flag isn't set, the frame will be rejected. This is also used as an
|
||||
* nl80211 capability flag.
|
||||
*
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
|
@ -1002,6 +1015,8 @@ enum nl80211_attrs {
|
|||
|
||||
NL80211_ATTR_MCAST_RATE,
|
||||
|
||||
NL80211_ATTR_OFFCHANNEL_TX_OK,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
|
|
@ -55,6 +55,10 @@ struct ssb_sprom {
|
|||
u8 tri5gl; /* 5.2GHz TX isolation */
|
||||
u8 tri5g; /* 5.3GHz TX isolation */
|
||||
u8 tri5gh; /* 5.8GHz TX isolation */
|
||||
u8 txpid2g[4]; /* 2GHz TX power index */
|
||||
u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */
|
||||
u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */
|
||||
u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */
|
||||
u8 rxpo2g; /* 2GHz RX power offset */
|
||||
u8 rxpo5g; /* 5GHz RX power offset */
|
||||
u8 rssisav2g; /* 2GHz RSSI params */
|
||||
|
|
|
@ -299,6 +299,46 @@
|
|||
#define SSB_SPROM4_AGAIN2_SHIFT 0
|
||||
#define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */
|
||||
#define SSB_SPROM4_AGAIN3_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID2G01 0x0062 /* TX Power Index 2GHz */
|
||||
#define SSB_SPROM4_TXPID2G0 0x00FF
|
||||
#define SSB_SPROM4_TXPID2G0_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID2G1 0xFF00
|
||||
#define SSB_SPROM4_TXPID2G1_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID2G23 0x0064 /* TX Power Index 2GHz */
|
||||
#define SSB_SPROM4_TXPID2G2 0x00FF
|
||||
#define SSB_SPROM4_TXPID2G2_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID2G3 0xFF00
|
||||
#define SSB_SPROM4_TXPID2G3_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5G01 0x0066 /* TX Power Index 5GHz middle subband */
|
||||
#define SSB_SPROM4_TXPID5G0 0x00FF
|
||||
#define SSB_SPROM4_TXPID5G0_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5G1 0xFF00
|
||||
#define SSB_SPROM4_TXPID5G1_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5G23 0x0068 /* TX Power Index 5GHz middle subband */
|
||||
#define SSB_SPROM4_TXPID5G2 0x00FF
|
||||
#define SSB_SPROM4_TXPID5G2_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5G3 0xFF00
|
||||
#define SSB_SPROM4_TXPID5G3_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5GL01 0x006A /* TX Power Index 5GHz low subband */
|
||||
#define SSB_SPROM4_TXPID5GL0 0x00FF
|
||||
#define SSB_SPROM4_TXPID5GL0_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5GL1 0xFF00
|
||||
#define SSB_SPROM4_TXPID5GL1_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5GL23 0x006C /* TX Power Index 5GHz low subband */
|
||||
#define SSB_SPROM4_TXPID5GL2 0x00FF
|
||||
#define SSB_SPROM4_TXPID5GL2_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5GL3 0xFF00
|
||||
#define SSB_SPROM4_TXPID5GL3_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5GH01 0x006E /* TX Power Index 5GHz high subband */
|
||||
#define SSB_SPROM4_TXPID5GH0 0x00FF
|
||||
#define SSB_SPROM4_TXPID5GH0_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5GH1 0xFF00
|
||||
#define SSB_SPROM4_TXPID5GH1_SHIFT 8
|
||||
#define SSB_SPROM4_TXPID5GH23 0x0070 /* TX Power Index 5GHz high subband */
|
||||
#define SSB_SPROM4_TXPID5GH2 0x00FF
|
||||
#define SSB_SPROM4_TXPID5GH2_SHIFT 0
|
||||
#define SSB_SPROM4_TXPID5GH3 0xFF00
|
||||
#define SSB_SPROM4_TXPID5GH3_SHIFT 8
|
||||
#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */
|
||||
#define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
|
||||
#define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
|
@ -489,7 +489,7 @@ struct hci_rp_read_local_name {
|
|||
|
||||
#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18
|
||||
|
||||
#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
|
||||
#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
|
||||
#define SCAN_DISABLED 0x00
|
||||
#define SCAN_INQUIRY 0x01
|
||||
#define SCAN_PAGE 0x02
|
||||
|
@ -874,7 +874,7 @@ struct hci_ev_si_security {
|
|||
|
||||
struct hci_command_hdr {
|
||||
__le16 opcode; /* OCF & OGF */
|
||||
__u8 plen;
|
||||
__u8 plen;
|
||||
} __packed;
|
||||
|
||||
struct hci_event_hdr {
|
||||
|
|
|
@ -44,15 +44,15 @@ struct inquiry_data {
|
|||
};
|
||||
|
||||
struct inquiry_entry {
|
||||
struct inquiry_entry *next;
|
||||
struct inquiry_entry *next;
|
||||
__u32 timestamp;
|
||||
struct inquiry_data data;
|
||||
};
|
||||
|
||||
struct inquiry_cache {
|
||||
spinlock_t lock;
|
||||
spinlock_t lock;
|
||||
__u32 timestamp;
|
||||
struct inquiry_entry *list;
|
||||
struct inquiry_entry *list;
|
||||
};
|
||||
|
||||
struct hci_conn_hash {
|
||||
|
@ -141,7 +141,7 @@ struct hci_dev {
|
|||
void *driver_data;
|
||||
void *core_data;
|
||||
|
||||
atomic_t promisc;
|
||||
atomic_t promisc;
|
||||
|
||||
struct dentry *debugfs;
|
||||
|
||||
|
@ -150,7 +150,7 @@ struct hci_dev {
|
|||
|
||||
struct rfkill *rfkill;
|
||||
|
||||
struct module *owner;
|
||||
struct module *owner;
|
||||
|
||||
int (*open)(struct hci_dev *hdev);
|
||||
int (*close)(struct hci_dev *hdev);
|
||||
|
@ -215,8 +215,8 @@ extern rwlock_t hci_dev_list_lock;
|
|||
extern rwlock_t hci_cb_list_lock;
|
||||
|
||||
/* ----- Inquiry cache ----- */
|
||||
#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
|
||||
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
|
||||
#define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */
|
||||
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */
|
||||
|
||||
#define inquiry_cache_lock(c) spin_lock(&c->lock)
|
||||
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
|
||||
|
@ -14,13 +14,13 @@
|
|||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
|
@ -417,11 +417,11 @@ static inline int l2cap_tx_window_full(struct sock *sk)
|
|||
return sub == pi->remote_tx_win;
|
||||
}
|
||||
|
||||
#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
|
||||
#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
|
||||
#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)
|
||||
#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
|
||||
#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
|
||||
#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
|
||||
#define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)
|
||||
#define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE))
|
||||
#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
|
||||
#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
|
||||
|
||||
void l2cap_load(void);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
RFCOMM implementation for Linux Bluetooth stack (BlueZ).
|
||||
/*
|
||||
RFCOMM implementation for Linux Bluetooth stack (BlueZ)
|
||||
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
|
||||
|
||||
|
@ -11,13 +11,13 @@
|
|||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
|
@ -105,7 +105,7 @@
|
|||
struct rfcomm_hdr {
|
||||
u8 addr;
|
||||
u8 ctrl;
|
||||
u8 len; // Actual size can be 2 bytes
|
||||
u8 len; /* Actual size can be 2 bytes */
|
||||
} __packed;
|
||||
|
||||
struct rfcomm_cmd {
|
||||
|
@ -228,7 +228,7 @@ struct rfcomm_dlc {
|
|||
/* ---- RFCOMM SEND RPN ---- */
|
||||
int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
|
||||
u8 bit_rate, u8 data_bits, u8 stop_bits,
|
||||
u8 parity, u8 flow_ctrl_settings,
|
||||
u8 parity, u8 flow_ctrl_settings,
|
||||
u8 xon_char, u8 xoff_char, u16 param_mask);
|
||||
|
||||
/* ---- RFCOMM DLCs (channels) ---- */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
|
@ -55,11 +55,11 @@ struct sco_conninfo {
|
|||
struct sco_conn {
|
||||
struct hci_conn *hcon;
|
||||
|
||||
bdaddr_t *dst;
|
||||
bdaddr_t *src;
|
||||
|
||||
bdaddr_t *dst;
|
||||
bdaddr_t *src;
|
||||
|
||||
spinlock_t lock;
|
||||
struct sock *sk;
|
||||
struct sock *sk;
|
||||
|
||||
unsigned int mtu;
|
||||
};
|
||||
|
|
|
@ -1134,7 +1134,9 @@ struct cfg80211_pmksa {
|
|||
* @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.
|
||||
* This allows the operation to be terminated prior to timeout based on
|
||||
* the duration value.
|
||||
* @mgmt_tx: Transmit a management frame
|
||||
* @mgmt_tx: Transmit a management frame.
|
||||
* @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
|
||||
* frame on another channel
|
||||
*
|
||||
* @testmode_cmd: run a test mode command
|
||||
*
|
||||
|
@ -1152,6 +1154,13 @@ struct cfg80211_pmksa {
|
|||
* @mgmt_frame_register: Notify driver that a management frame type was
|
||||
* registered. Note that this callback may not sleep, and cannot run
|
||||
* concurrently with itself.
|
||||
*
|
||||
* @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.
|
||||
* Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may
|
||||
* reject TX/RX mask combinations they cannot support by returning -EINVAL
|
||||
* (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).
|
||||
*
|
||||
* @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
|
||||
*/
|
||||
struct cfg80211_ops {
|
||||
int (*suspend)(struct wiphy *wiphy);
|
||||
|
@ -1291,10 +1300,13 @@ struct cfg80211_ops {
|
|||
u64 cookie);
|
||||
|
||||
int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ieee80211_channel *chan,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, u64 *cookie);
|
||||
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
u64 cookie);
|
||||
|
||||
int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
|
||||
bool enabled, int timeout);
|
||||
|
|
|
@ -2055,8 +2055,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
|
|||
*
|
||||
* This function may not be called in IRQ context. Calls to this function
|
||||
* for a single hardware must be synchronized against each other. Calls
|
||||
* to this function and ieee80211_tx_status_irqsafe() may not be mixed
|
||||
* for a single hardware.
|
||||
* to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
|
||||
* may not be mixed for a single hardware.
|
||||
*
|
||||
* @hw: the hardware the frame was transmitted by
|
||||
* @skb: the frame that was transmitted, owned by mac80211 after this call
|
||||
|
@ -2064,14 +2064,34 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
|
|||
void ieee80211_tx_status(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb);
|
||||
|
||||
/**
|
||||
* ieee80211_tx_status_ni - transmit status callback (in process context)
|
||||
*
|
||||
* Like ieee80211_tx_status() but can be called in process context.
|
||||
*
|
||||
* Calls to this function, ieee80211_tx_status() and
|
||||
* ieee80211_tx_status_irqsafe() may not be mixed
|
||||
* for a single hardware.
|
||||
*
|
||||
* @hw: the hardware the frame was transmitted by
|
||||
* @skb: the frame that was transmitted, owned by mac80211 after this call
|
||||
*/
|
||||
static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
local_bh_disable();
|
||||
ieee80211_tx_status(hw, skb);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback
|
||||
*
|
||||
* Like ieee80211_tx_status() but can be called in IRQ context
|
||||
* (internally defers to a tasklet.)
|
||||
*
|
||||
* Calls to this function and ieee80211_tx_status() may not be mixed for a
|
||||
* single hardware.
|
||||
* Calls to this function, ieee80211_tx_status() and
|
||||
* ieee80211_tx_status_ni() may not be mixed for a single hardware.
|
||||
*
|
||||
* @hw: the hardware the frame was transmitted by
|
||||
* @skb: the frame that was transmitted, owned by mac80211 after this call
|
||||
|
|
|
@ -648,6 +648,7 @@ int bnep_del_connection(struct bnep_conndel_req *req)
|
|||
|
||||
static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
|
||||
{
|
||||
memset(ci, 0, sizeof(*ci));
|
||||
memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
|
||||
strcpy(ci->device, s->dev->name);
|
||||
ci->flags = s->flags;
|
||||
|
|
|
@ -78,6 +78,7 @@ static void __cmtp_unlink_session(struct cmtp_session *session)
|
|||
|
||||
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
|
||||
{
|
||||
memset(ci, 0, sizeof(*ci));
|
||||
bacpy(&ci->bdaddr, &session->bdaddr);
|
||||
|
||||
ci->flags = session->flags;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -66,7 +66,8 @@ void hci_acl_connect(struct hci_conn *conn)
|
|||
bacpy(&cp.bdaddr, &conn->dst);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
|
||||
ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
|
||||
if (ie) {
|
||||
if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
|
||||
cp.pscan_rep_mode = ie->data.pscan_rep_mode;
|
||||
cp.pscan_mode = ie->data.pscan_mode;
|
||||
|
@ -368,8 +369,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
|
|||
|
||||
BT_DBG("%s dst %s", hdev->name, batostr(dst));
|
||||
|
||||
if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
|
||||
if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
|
||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||
if (!acl) {
|
||||
acl = hci_conn_add(hdev, ACL_LINK, dst);
|
||||
if (!acl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -389,8 +392,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
|
|||
if (type == ACL_LINK)
|
||||
return acl;
|
||||
|
||||
if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
|
||||
if (!(sco = hci_conn_add(hdev, type, dst))) {
|
||||
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
|
||||
if (!sco) {
|
||||
sco = hci_conn_add(hdev, type, dst);
|
||||
if (!sco) {
|
||||
hci_conn_put(acl);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -647,10 +652,12 @@ int hci_get_conn_list(void __user *arg)
|
|||
|
||||
size = sizeof(req) + req.conn_num * sizeof(*ci);
|
||||
|
||||
if (!(cl = kmalloc(size, GFP_KERNEL)))
|
||||
cl = kmalloc(size, GFP_KERNEL);
|
||||
if (!cl)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!(hdev = hci_dev_get(req.dev_id))) {
|
||||
hdev = hci_dev_get(req.dev_id);
|
||||
if (!hdev) {
|
||||
kfree(cl);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -349,20 +349,23 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
|
|||
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
|
||||
{
|
||||
struct inquiry_cache *cache = &hdev->inq_cache;
|
||||
struct inquiry_entry *e;
|
||||
struct inquiry_entry *ie;
|
||||
|
||||
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
|
||||
|
||||
if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) {
|
||||
ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
|
||||
if (!ie) {
|
||||
/* Entry not in the cache. Add new one. */
|
||||
if (!(e = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
|
||||
ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
|
||||
if (!ie)
|
||||
return;
|
||||
e->next = cache->list;
|
||||
cache->list = e;
|
||||
|
||||
ie->next = cache->list;
|
||||
cache->list = ie;
|
||||
}
|
||||
|
||||
memcpy(&e->data, data, sizeof(*data));
|
||||
e->timestamp = jiffies;
|
||||
memcpy(&ie->data, data, sizeof(*data));
|
||||
ie->timestamp = jiffies;
|
||||
cache->timestamp = jiffies;
|
||||
}
|
||||
|
||||
|
@ -422,16 +425,20 @@ int hci_inquiry(void __user *arg)
|
|||
|
||||
hci_dev_lock_bh(hdev);
|
||||
if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
|
||||
inquiry_cache_empty(hdev) ||
|
||||
ir.flags & IREQ_CACHE_FLUSH) {
|
||||
inquiry_cache_empty(hdev) ||
|
||||
ir.flags & IREQ_CACHE_FLUSH) {
|
||||
inquiry_cache_flush(hdev);
|
||||
do_inquiry = 1;
|
||||
}
|
||||
hci_dev_unlock_bh(hdev);
|
||||
|
||||
timeo = ir.length * msecs_to_jiffies(2000);
|
||||
if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
|
||||
goto done;
|
||||
|
||||
if (do_inquiry) {
|
||||
err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
|
||||
if (err < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* for unlimited number of responses we will use buffer with 255 entries */
|
||||
max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
|
||||
|
@ -439,7 +446,8 @@ int hci_inquiry(void __user *arg)
|
|||
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
|
||||
* copy it to the user space.
|
||||
*/
|
||||
if (!(buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL))) {
|
||||
buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
@ -611,7 +619,8 @@ int hci_dev_close(__u16 dev)
|
|||
struct hci_dev *hdev;
|
||||
int err;
|
||||
|
||||
if (!(hdev = hci_dev_get(dev)))
|
||||
hdev = hci_dev_get(dev);
|
||||
if (!hdev)
|
||||
return -ENODEV;
|
||||
err = hci_dev_do_close(hdev);
|
||||
hci_dev_put(hdev);
|
||||
|
@ -623,7 +632,8 @@ int hci_dev_reset(__u16 dev)
|
|||
struct hci_dev *hdev;
|
||||
int ret = 0;
|
||||
|
||||
if (!(hdev = hci_dev_get(dev)))
|
||||
hdev = hci_dev_get(dev);
|
||||
if (!hdev)
|
||||
return -ENODEV;
|
||||
|
||||
hci_req_lock(hdev);
|
||||
|
@ -663,7 +673,8 @@ int hci_dev_reset_stat(__u16 dev)
|
|||
struct hci_dev *hdev;
|
||||
int ret = 0;
|
||||
|
||||
if (!(hdev = hci_dev_get(dev)))
|
||||
hdev = hci_dev_get(dev);
|
||||
if (!hdev)
|
||||
return -ENODEV;
|
||||
|
||||
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
|
||||
|
@ -682,7 +693,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
|
|||
if (copy_from_user(&dr, arg, sizeof(dr)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!(hdev = hci_dev_get(dr.dev_id)))
|
||||
hdev = hci_dev_get(dr.dev_id);
|
||||
if (!hdev)
|
||||
return -ENODEV;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -763,7 +775,8 @@ int hci_get_dev_list(void __user *arg)
|
|||
|
||||
size = sizeof(*dl) + dev_num * sizeof(*dr);
|
||||
|
||||
if (!(dl = kzalloc(size, GFP_KERNEL)))
|
||||
dl = kzalloc(size, GFP_KERNEL);
|
||||
if (!dl)
|
||||
return -ENOMEM;
|
||||
|
||||
dr = dl->dev_req;
|
||||
|
@ -797,7 +810,8 @@ int hci_get_dev_info(void __user *arg)
|
|||
if (copy_from_user(&di, arg, sizeof(di)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!(hdev = hci_dev_get(di.dev_id)))
|
||||
hdev = hci_dev_get(di.dev_id);
|
||||
if (!hdev)
|
||||
return -ENODEV;
|
||||
|
||||
strcpy(di.name, hdev->name);
|
||||
|
@ -905,7 +919,7 @@ int hci_register_dev(struct hci_dev *hdev)
|
|||
hdev->sniff_max_interval = 800;
|
||||
hdev->sniff_min_interval = 80;
|
||||
|
||||
tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
|
||||
tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
|
||||
tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
|
||||
tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
|
||||
|
||||
|
@ -1368,7 +1382,8 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
|
|||
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
|
||||
hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
|
||||
|
||||
if (!(list = skb_shinfo(skb)->frag_list)) {
|
||||
list = skb_shinfo(skb)->frag_list;
|
||||
if (!list) {
|
||||
/* Non fragmented */
|
||||
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
|
||||
|
||||
|
@ -1609,7 +1624,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
hci_conn_enter_active_mode(conn);
|
||||
|
||||
/* Send to upper protocol */
|
||||
if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
|
||||
hp = hci_proto[HCI_PROTO_L2CAP];
|
||||
if (hp && hp->recv_acldata) {
|
||||
hp->recv_acldata(conn, skb, flags);
|
||||
return;
|
||||
}
|
||||
|
@ -1644,7 +1660,8 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
register struct hci_proto *hp;
|
||||
|
||||
/* Send to upper protocol */
|
||||
if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
|
||||
hp = hci_proto[HCI_PROTO_SCO];
|
||||
if (hp && hp->recv_scodata) {
|
||||
hp->recv_scodata(conn, skb);
|
||||
return;
|
||||
}
|
||||
|
@ -1727,7 +1744,8 @@ static void hci_cmd_task(unsigned long arg)
|
|||
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
|
||||
kfree_skb(hdev->sent_cmd);
|
||||
|
||||
if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
|
||||
hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
|
||||
if (hdev->sent_cmd) {
|
||||
atomic_dec(&hdev->cmd_cnt);
|
||||
hci_send_frame(skb);
|
||||
hdev->cmd_last_tx = jiffies;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -677,9 +677,50 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
|
|||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static int hci_outgoing_auth_needed(struct hci_dev *hdev,
|
||||
struct hci_conn *conn)
|
||||
{
|
||||
if (conn->state != BT_CONFIG || !conn->out)
|
||||
return 0;
|
||||
|
||||
if (conn->sec_level == BT_SECURITY_SDP)
|
||||
return 0;
|
||||
|
||||
/* Only request authentication for SSP connections or non-SSP
|
||||
* devices with sec_level HIGH */
|
||||
if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
|
||||
conn->sec_level != BT_SECURITY_HIGH)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
|
||||
{
|
||||
struct hci_cp_remote_name_req *cp;
|
||||
struct hci_conn *conn;
|
||||
|
||||
BT_DBG("%s status 0x%x", hdev->name, status);
|
||||
|
||||
/* If successful wait for the name req complete event before
|
||||
* checking for the need to do authentication */
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
|
||||
if (!cp)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
|
||||
if (conn && hci_outgoing_auth_needed(hdev, conn)) {
|
||||
struct hci_cp_auth_requested cp;
|
||||
cp.handle = __cpu_to_le16(conn->handle);
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
|
||||
|
@ -955,12 +996,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
|
|||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
|
||||
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
|
||||
if (ie)
|
||||
memcpy(ie->data.dev_class, ev->dev_class, 3);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
|
||||
if (!conn) {
|
||||
if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
|
||||
conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
|
||||
if (!conn) {
|
||||
BT_ERR("No memory for new connection");
|
||||
hci_dev_unlock(hdev);
|
||||
return;
|
||||
|
@ -1090,9 +1133,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
|
|||
|
||||
static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_ev_remote_name *ev = (void *) skb->data;
|
||||
struct hci_conn *conn;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
|
||||
hci_conn_check_pending(hdev);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (conn && hci_outgoing_auth_needed(hdev, conn)) {
|
||||
struct hci_cp_auth_requested cp;
|
||||
cp.handle = __cpu_to_le16(conn->handle);
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
@ -1162,33 +1219,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
||||
if (conn) {
|
||||
if (!ev->status)
|
||||
memcpy(conn->features, ev->features, 8);
|
||||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
if (!ev->status && lmp_ssp_capable(hdev) &&
|
||||
lmp_ssp_capable(conn)) {
|
||||
struct hci_cp_read_remote_ext_features cp;
|
||||
cp.handle = ev->handle;
|
||||
cp.page = 0x01;
|
||||
hci_send_cmd(hdev,
|
||||
HCI_OP_READ_REMOTE_EXT_FEATURES,
|
||||
if (!ev->status)
|
||||
memcpy(conn->features, ev->features, 8);
|
||||
|
||||
if (conn->state != BT_CONFIG)
|
||||
goto unlock;
|
||||
|
||||
if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
|
||||
struct hci_cp_read_remote_ext_features cp;
|
||||
cp.handle = ev->handle;
|
||||
cp.page = 0x01;
|
||||
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
|
||||
sizeof(cp), &cp);
|
||||
} else if (!ev->status && conn->out &&
|
||||
conn->sec_level == BT_SECURITY_HIGH) {
|
||||
struct hci_cp_auth_requested cp;
|
||||
cp.handle = ev->handle;
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
|
||||
sizeof(cp), &cp);
|
||||
} else {
|
||||
conn->state = BT_CONNECTED;
|
||||
hci_proto_connect_cfm(conn, ev->status);
|
||||
hci_conn_put(conn);
|
||||
}
|
||||
}
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (!ev->status) {
|
||||
struct hci_cp_remote_name_req cp;
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, &conn->dst);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
if (!hci_outgoing_auth_needed(hdev, conn)) {
|
||||
conn->state = BT_CONNECTED;
|
||||
hci_proto_connect_cfm(conn, ev->status);
|
||||
hci_conn_put(conn);
|
||||
}
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
|
@ -1449,10 +1512,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
|
|||
conn->sent -= count;
|
||||
|
||||
if (conn->type == ACL_LINK) {
|
||||
if ((hdev->acl_cnt += count) > hdev->acl_pkts)
|
||||
hdev->acl_cnt += count;
|
||||
if (hdev->acl_cnt > hdev->acl_pkts)
|
||||
hdev->acl_cnt = hdev->acl_pkts;
|
||||
} else {
|
||||
if ((hdev->sco_cnt += count) > hdev->sco_pkts)
|
||||
hdev->sco_cnt += count;
|
||||
if (hdev->sco_cnt > hdev->sco_pkts)
|
||||
hdev->sco_cnt = hdev->sco_pkts;
|
||||
}
|
||||
}
|
||||
|
@ -1547,7 +1612,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
|
|||
if (conn && !ev->status) {
|
||||
struct inquiry_entry *ie;
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
|
||||
ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
|
||||
if (ie) {
|
||||
ie->data.clock_offset = ev->clock_offset;
|
||||
ie->timestamp = jiffies;
|
||||
}
|
||||
|
@ -1581,7 +1647,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
|
|||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
|
||||
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
|
||||
if (ie) {
|
||||
ie->data.pscan_rep_mode = ev->pscan_rep_mode;
|
||||
ie->timestamp = jiffies;
|
||||
}
|
||||
|
@ -1646,32 +1713,37 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
|
||||
if (conn) {
|
||||
if (!ev->status && ev->page == 0x01) {
|
||||
struct inquiry_entry *ie;
|
||||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
|
||||
ie->data.ssp_mode = (ev->features[0] & 0x01);
|
||||
if (!ev->status && ev->page == 0x01) {
|
||||
struct inquiry_entry *ie;
|
||||
|
||||
conn->ssp_mode = (ev->features[0] & 0x01);
|
||||
}
|
||||
ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
|
||||
if (ie)
|
||||
ie->data.ssp_mode = (ev->features[0] & 0x01);
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
if (!ev->status && hdev->ssp_mode > 0 &&
|
||||
conn->ssp_mode > 0 && conn->out &&
|
||||
conn->sec_level != BT_SECURITY_SDP) {
|
||||
struct hci_cp_auth_requested cp;
|
||||
cp.handle = ev->handle;
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
|
||||
sizeof(cp), &cp);
|
||||
} else {
|
||||
conn->state = BT_CONNECTED;
|
||||
hci_proto_connect_cfm(conn, ev->status);
|
||||
hci_conn_put(conn);
|
||||
}
|
||||
}
|
||||
conn->ssp_mode = (ev->features[0] & 0x01);
|
||||
}
|
||||
|
||||
if (conn->state != BT_CONFIG)
|
||||
goto unlock;
|
||||
|
||||
if (!ev->status) {
|
||||
struct hci_cp_remote_name_req cp;
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
bacpy(&cp.bdaddr, &conn->dst);
|
||||
cp.pscan_rep_mode = 0x02;
|
||||
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
if (!hci_outgoing_auth_needed(hdev, conn)) {
|
||||
conn->state = BT_CONNECTED;
|
||||
hci_proto_connect_cfm(conn, ev->status);
|
||||
hci_conn_put(conn);
|
||||
}
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
|
@ -1821,7 +1893,8 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
|
|||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
|
||||
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
|
||||
if (ie)
|
||||
ie->data.ssp_mode = (ev->features[0] & 0x01);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -125,7 +125,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
continue;
|
||||
|
||||
/* Put type byte before the data */
|
||||
|
@ -370,7 +371,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
|
|||
}
|
||||
|
||||
if (haddr->hci_dev != HCI_DEV_NONE) {
|
||||
if (!(hdev = hci_dev_get(haddr->hci_dev))) {
|
||||
hdev = hci_dev_get(haddr->hci_dev);
|
||||
if (!hdev) {
|
||||
err = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
|
@ -457,7 +459,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (sk->sk_state == BT_CLOSED)
|
||||
return 0;
|
||||
|
||||
if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
|
||||
skb = skb_recv_datagram(sk, flags, noblock, &err);
|
||||
if (!skb)
|
||||
return err;
|
||||
|
||||
msg->msg_namelen = 0;
|
||||
|
@ -499,7 +502,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||
|
||||
lock_sock(sk);
|
||||
|
||||
if (!(hdev = hci_pi(sk)->hdev)) {
|
||||
hdev = hci_pi(sk)->hdev;
|
||||
if (!hdev) {
|
||||
err = -EBADFD;
|
||||
goto done;
|
||||
}
|
||||
|
@ -509,7 +513,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
|
||||
skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
|
||||
if (!skb)
|
||||
goto done;
|
||||
|
||||
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
|
||||
|
|
|
@ -107,6 +107,7 @@ static void __hidp_unlink_session(struct hidp_session *session)
|
|||
|
||||
static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
|
||||
{
|
||||
memset(ci, 0, sizeof(*ci));
|
||||
bacpy(&ci->bdaddr, &session->bdaddr);
|
||||
|
||||
ci->flags = session->flags;
|
||||
|
@ -115,7 +116,6 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin
|
|||
ci->vendor = 0x0000;
|
||||
ci->product = 0x0000;
|
||||
ci->version = 0x0000;
|
||||
memset(ci->name, 0, 128);
|
||||
|
||||
if (session->input) {
|
||||
ci->vendor = session->input->id.vendor;
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
#define VERSION "2.15"
|
||||
|
||||
static int disable_ertm = 0;
|
||||
static int disable_ertm;
|
||||
|
||||
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
|
||||
static u8 l2cap_fixed_chan[8] = { 0x02, };
|
||||
|
@ -83,6 +83,18 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
|
|||
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
/* ---- L2CAP timers ---- */
|
||||
static void l2cap_sock_set_timer(struct sock *sk, long timeout)
|
||||
{
|
||||
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
|
||||
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
|
||||
}
|
||||
|
||||
static void l2cap_sock_clear_timer(struct sock *sk)
|
||||
{
|
||||
BT_DBG("sock %p state %d", sk, sk->sk_state);
|
||||
sk_stop_timer(sk, &sk->sk_timer);
|
||||
}
|
||||
|
||||
static void l2cap_sock_timeout(unsigned long arg)
|
||||
{
|
||||
struct sock *sk = (struct sock *) arg;
|
||||
|
@ -92,6 +104,14 @@ static void l2cap_sock_timeout(unsigned long arg)
|
|||
|
||||
bh_lock_sock(sk);
|
||||
|
||||
if (sock_owned_by_user(sk)) {
|
||||
/* sk is owned by user. Try again later */
|
||||
l2cap_sock_set_timer(sk, HZ / 5);
|
||||
bh_unlock_sock(sk);
|
||||
sock_put(sk);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
|
||||
reason = ECONNREFUSED;
|
||||
else if (sk->sk_state == BT_CONNECT &&
|
||||
|
@ -108,18 +128,6 @@ static void l2cap_sock_timeout(unsigned long arg)
|
|||
sock_put(sk);
|
||||
}
|
||||
|
||||
static void l2cap_sock_set_timer(struct sock *sk, long timeout)
|
||||
{
|
||||
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
|
||||
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
|
||||
}
|
||||
|
||||
static void l2cap_sock_clear_timer(struct sock *sk)
|
||||
{
|
||||
BT_DBG("sock %p state %d", sk, sk->sk_state);
|
||||
sk_stop_timer(sk, &sk->sk_timer);
|
||||
}
|
||||
|
||||
/* ---- L2CAP channels ---- */
|
||||
static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
|
||||
{
|
||||
|
@ -743,11 +751,13 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
|
|||
/* Find socket with psm and source bdaddr.
|
||||
* Returns closest match.
|
||||
*/
|
||||
static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
|
||||
static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
|
||||
{
|
||||
struct sock *sk = NULL, *sk1 = NULL;
|
||||
struct hlist_node *node;
|
||||
|
||||
read_lock(&l2cap_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &l2cap_sk_list.head) {
|
||||
if (state && sk->sk_state != state)
|
||||
continue;
|
||||
|
@ -762,20 +772,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
|
|||
sk1 = sk;
|
||||
}
|
||||
}
|
||||
return node ? sk : sk1;
|
||||
}
|
||||
|
||||
/* Find socket with given address (psm, src).
|
||||
* Returns locked socket */
|
||||
static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
|
||||
{
|
||||
struct sock *s;
|
||||
read_lock(&l2cap_sk_list.lock);
|
||||
s = __l2cap_get_sock_by_psm(state, psm, src);
|
||||
if (s)
|
||||
bh_lock_sock(s);
|
||||
read_unlock(&l2cap_sk_list.lock);
|
||||
return s;
|
||||
|
||||
return node ? sk : sk1;
|
||||
}
|
||||
|
||||
static void l2cap_sock_destruct(struct sock *sk)
|
||||
|
@ -2926,6 +2926,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
|||
goto sendresp;
|
||||
}
|
||||
|
||||
bh_lock_sock(parent);
|
||||
|
||||
/* Check if the ACL is secure enough (if not SDP) */
|
||||
if (psm != cpu_to_le16(0x0001) &&
|
||||
!hci_conn_check_link_mode(conn->hcon)) {
|
||||
|
@ -3078,6 +3080,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
|||
break;
|
||||
|
||||
default:
|
||||
/* don't delete l2cap channel if sk is owned by user */
|
||||
if (sock_owned_by_user(sk)) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
l2cap_sock_clear_timer(sk);
|
||||
l2cap_sock_set_timer(sk, HZ / 5);
|
||||
break;
|
||||
}
|
||||
|
||||
l2cap_chan_del(sk, ECONNREFUSED);
|
||||
break;
|
||||
}
|
||||
|
@ -3283,6 +3293,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
|
|||
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
|
||||
/* don't delete l2cap channel if sk is owned by user */
|
||||
if (sock_owned_by_user(sk)) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
l2cap_sock_clear_timer(sk);
|
||||
l2cap_sock_set_timer(sk, HZ / 5);
|
||||
bh_unlock_sock(sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
l2cap_chan_del(sk, ECONNRESET);
|
||||
bh_unlock_sock(sk);
|
||||
|
||||
|
@ -3305,6 +3324,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
|
|||
if (!sk)
|
||||
return 0;
|
||||
|
||||
/* don't delete l2cap channel if sk is owned by user */
|
||||
if (sock_owned_by_user(sk)) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
l2cap_sock_clear_timer(sk);
|
||||
l2cap_sock_set_timer(sk, HZ / 5);
|
||||
bh_unlock_sock(sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
l2cap_chan_del(sk, 0);
|
||||
bh_unlock_sock(sk);
|
||||
|
||||
|
@ -4134,11 +4162,10 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
|
|||
__mod_retrans_timer();
|
||||
|
||||
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
|
||||
if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
|
||||
if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
|
||||
l2cap_send_ack(pi);
|
||||
} else {
|
||||
else
|
||||
l2cap_ertm_send(sk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4430,6 +4457,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
|
|||
if (!sk)
|
||||
goto drop;
|
||||
|
||||
bh_lock_sock(sk);
|
||||
|
||||
BT_DBG("sk %p, len %d", sk, skb->len);
|
||||
|
||||
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
|
||||
|
@ -4841,8 +4870,10 @@ static int __init l2cap_init(void)
|
|||
return err;
|
||||
|
||||
_busy_wq = create_singlethread_workqueue("l2cap");
|
||||
if (!_busy_wq)
|
||||
goto error;
|
||||
if (!_busy_wq) {
|
||||
proto_unregister(&l2cap_proto);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
|
||||
if (err < 0) {
|
||||
|
@ -4870,6 +4901,7 @@ static int __init l2cap_init(void)
|
|||
return 0;
|
||||
|
||||
error:
|
||||
destroy_workqueue(_busy_wq);
|
||||
proto_unregister(&l2cap_proto);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
#include <net/sock.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -51,10 +51,10 @@
|
|||
|
||||
#define VERSION "1.11"
|
||||
|
||||
static int disable_cfc = 0;
|
||||
static int disable_cfc;
|
||||
static int l2cap_ertm;
|
||||
static int channel_mtu = -1;
|
||||
static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
|
||||
static int l2cap_ertm = 0;
|
||||
|
||||
static struct task_struct *rfcomm_thread;
|
||||
|
||||
|
@ -1901,7 +1901,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
|
|||
|
||||
BT_DBG("%p state %ld", s, s->state);
|
||||
|
||||
switch(sk->sk_state) {
|
||||
switch (sk->sk_state) {
|
||||
case BT_CONNECTED:
|
||||
s->state = BT_CONNECT;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
|
|||
/* Find socket with channel and source bdaddr.
|
||||
* Returns closest match.
|
||||
*/
|
||||
static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
|
||||
static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
|
||||
{
|
||||
struct sock *sk = NULL, *sk1 = NULL;
|
||||
struct hlist_node *node;
|
||||
|
||||
read_lock(&rfcomm_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &rfcomm_sk_list.head) {
|
||||
if (state && sk->sk_state != state)
|
||||
continue;
|
||||
|
@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
|
|||
sk1 = sk;
|
||||
}
|
||||
}
|
||||
return node ? sk : sk1;
|
||||
}
|
||||
|
||||
/* Find socket with given address (channel, src).
|
||||
* Returns locked socket */
|
||||
static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
|
||||
{
|
||||
struct sock *s;
|
||||
read_lock(&rfcomm_sk_list.lock);
|
||||
s = __rfcomm_get_sock_by_channel(state, channel, src);
|
||||
if (s) bh_lock_sock(s);
|
||||
read_unlock(&rfcomm_sk_list.lock);
|
||||
return s;
|
||||
|
||||
return node ? sk : sk1;
|
||||
}
|
||||
|
||||
static void rfcomm_sock_destruct(struct sock *sk)
|
||||
|
@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
|
|||
|
||||
BT_DBG("sock %p, sk %p", sock, sk);
|
||||
|
||||
if (!sk) return 0;
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
||||
lock_sock(sk);
|
||||
if (!sk->sk_shutdown) {
|
||||
|
@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
|
|||
if (!parent)
|
||||
return 0;
|
||||
|
||||
bh_lock_sock(parent);
|
||||
|
||||
/* Check for backlog size */
|
||||
if (sk_acceptq_is_full(parent)) {
|
||||
BT_DBG("backlog full %d", parent->sk_ack_backlog);
|
||||
|
|
|
@ -58,9 +58,9 @@ struct rfcomm_dev {
|
|||
|
||||
bdaddr_t src;
|
||||
bdaddr_t dst;
|
||||
u8 channel;
|
||||
u8 channel;
|
||||
|
||||
uint modem_status;
|
||||
uint modem_status;
|
||||
|
||||
struct rfcomm_dlc *dlc;
|
||||
struct tty_struct *tty;
|
||||
|
@ -69,7 +69,7 @@ struct rfcomm_dev {
|
|||
|
||||
struct device *tty_dev;
|
||||
|
||||
atomic_t wmem_alloc;
|
||||
atomic_t wmem_alloc;
|
||||
|
||||
struct sk_buff_head pending;
|
||||
};
|
||||
|
@ -431,7 +431,8 @@ static int rfcomm_release_dev(void __user *arg)
|
|||
|
||||
BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
|
||||
|
||||
if (!(dev = rfcomm_dev_get(req.dev_id)))
|
||||
dev = rfcomm_dev_get(req.dev_id);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
|
||||
|
@ -470,7 +471,8 @@ static int rfcomm_get_dev_list(void __user *arg)
|
|||
|
||||
size = sizeof(*dl) + dev_num * sizeof(*di);
|
||||
|
||||
if (!(dl = kmalloc(size, GFP_KERNEL)))
|
||||
dl = kmalloc(size, GFP_KERNEL);
|
||||
if (!dl)
|
||||
return -ENOMEM;
|
||||
|
||||
di = dl->dev_info;
|
||||
|
@ -513,7 +515,8 @@ static int rfcomm_get_dev_info(void __user *arg)
|
|||
if (copy_from_user(&di, arg, sizeof(di)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!(dev = rfcomm_dev_get(di.id)))
|
||||
dev = rfcomm_dev_get(di.id);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
di.flags = dev->flags;
|
||||
|
@ -561,7 +564,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) {
|
||||
tty = dev->tty;
|
||||
if (!tty || !skb_queue_empty(&dev->pending)) {
|
||||
skb_queue_tail(&dev->pending, skb);
|
||||
return;
|
||||
}
|
||||
|
@ -796,7 +800,8 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
|
|||
|
||||
memcpy(skb_put(skb, size), buf + sent, size);
|
||||
|
||||
if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
|
||||
err = rfcomm_dlc_send(dlc, skb);
|
||||
if (err < 0) {
|
||||
kfree_skb(skb);
|
||||
break;
|
||||
}
|
||||
|
@ -892,7 +897,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|||
|
||||
/* Parity on/off and when on, odd/even */
|
||||
if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
|
||||
((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
|
||||
((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
|
||||
changes |= RFCOMM_RPN_PM_PARITY;
|
||||
BT_DBG("Parity change detected.");
|
||||
}
|
||||
|
@ -937,11 +942,10 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|||
/* POSIX does not support 1.5 stop bits and RFCOMM does not
|
||||
* support 2 stop bits. So a request for 2 stop bits gets
|
||||
* translated to 1.5 stop bits */
|
||||
if (new->c_cflag & CSTOPB) {
|
||||
if (new->c_cflag & CSTOPB)
|
||||
stop_bits = RFCOMM_RPN_STOP_15;
|
||||
} else {
|
||||
else
|
||||
stop_bits = RFCOMM_RPN_STOP_1;
|
||||
}
|
||||
|
||||
/* Handle number of data bits [5-8] */
|
||||
if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
#define VERSION "0.6"
|
||||
|
||||
static int disable_esco = 0;
|
||||
static int disable_esco;
|
||||
|
||||
static const struct proto_ops sco_sock_ops;
|
||||
|
||||
|
@ -138,16 +138,17 @@ static inline struct sock *sco_chan_get(struct sco_conn *conn)
|
|||
|
||||
static int sco_conn_del(struct hci_conn *hcon, int err)
|
||||
{
|
||||
struct sco_conn *conn;
|
||||
struct sco_conn *conn = hcon->sco_data;
|
||||
struct sock *sk;
|
||||
|
||||
if (!(conn = hcon->sco_data))
|
||||
if (!conn)
|
||||
return 0;
|
||||
|
||||
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
|
||||
|
||||
/* Kill socket */
|
||||
if ((sk = sco_chan_get(conn))) {
|
||||
sk = sco_chan_get(conn);
|
||||
if (sk) {
|
||||
bh_lock_sock(sk);
|
||||
sco_sock_clear_timer(sk);
|
||||
sco_chan_del(sk, err);
|
||||
|
@ -185,7 +186,8 @@ static int sco_connect(struct sock *sk)
|
|||
|
||||
BT_DBG("%s -> %s", batostr(src), batostr(dst));
|
||||
|
||||
if (!(hdev = hci_get_route(dst, src)))
|
||||
hdev = hci_get_route(dst, src);
|
||||
if (!hdev)
|
||||
return -EHOSTUNREACH;
|
||||
|
||||
hci_dev_lock_bh(hdev);
|
||||
|
@ -510,7 +512,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
|
|||
/* Set destination address and psm */
|
||||
bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
|
||||
|
||||
if ((err = sco_connect(sk)))
|
||||
err = sco_connect(sk);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
err = bt_sock_wait_state(sk, BT_CONNECTED,
|
||||
|
@ -828,13 +831,14 @@ static void sco_chan_del(struct sock *sk, int err)
|
|||
|
||||
static void sco_conn_ready(struct sco_conn *conn)
|
||||
{
|
||||
struct sock *parent, *sk;
|
||||
struct sock *parent;
|
||||
struct sock *sk = conn->sk;
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
sco_conn_lock(conn);
|
||||
|
||||
if ((sk = conn->sk)) {
|
||||
if (sk) {
|
||||
sco_sock_clear_timer(sk);
|
||||
bh_lock_sock(sk);
|
||||
sk->sk_state = BT_CONNECTED;
|
||||
|
|
|
@ -129,9 +129,7 @@ static void sta_rx_agg_reorder_timer_expired(unsigned long data)
|
|||
timer_to_tid[0]);
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock(&sta->lock);
|
||||
ieee80211_release_reorder_timeout(sta, *ptid);
|
||||
spin_unlock(&sta->lock);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
@ -256,7 +254,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
|
|||
}
|
||||
|
||||
/* prepare A-MPDU MLME for Rx aggregation */
|
||||
tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
|
||||
tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
|
||||
if (!tid_agg_rx) {
|
||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||
if (net_ratelimit())
|
||||
|
@ -280,9 +278,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
|
|||
|
||||
/* prepare reordering buffer */
|
||||
tid_agg_rx->reorder_buf =
|
||||
kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
|
||||
kcalloc(buf_size, sizeof(struct sk_buff *), GFP_KERNEL);
|
||||
tid_agg_rx->reorder_time =
|
||||
kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC);
|
||||
kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL);
|
||||
if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
|
||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||
if (net_ratelimit())
|
||||
|
|
|
@ -1551,27 +1551,54 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
|
|||
return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
|
||||
}
|
||||
|
||||
static enum work_done_result
|
||||
ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
|
||||
{
|
||||
/*
|
||||
* Use the data embedded in the work struct for reporting
|
||||
* here so if the driver mangled the SKB before dropping
|
||||
* it (which is the only way we really should get here)
|
||||
* then we don't report mangled data.
|
||||
*
|
||||
* If there was no wait time, then by the time we get here
|
||||
* the driver will likely not have reported the status yet,
|
||||
* so in that case userspace will have to deal with it.
|
||||
*/
|
||||
|
||||
if (wk->offchan_tx.wait && wk->offchan_tx.frame)
|
||||
cfg80211_mgmt_tx_status(wk->sdata->dev,
|
||||
(unsigned long) wk->offchan_tx.frame,
|
||||
wk->ie, wk->ie_len, false, GFP_KERNEL);
|
||||
|
||||
return WORK_DONE_DESTROY;
|
||||
}
|
||||
|
||||
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ieee80211_channel *chan,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, u64 *cookie)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct sk_buff *skb;
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_work *wk;
|
||||
const struct ieee80211_mgmt *mgmt = (void *)buf;
|
||||
u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
bool is_offchan = false;
|
||||
|
||||
/* Check that we are on the requested channel for transmission */
|
||||
if (chan != local->tmp_channel &&
|
||||
chan != local->oper_channel)
|
||||
return -EBUSY;
|
||||
is_offchan = true;
|
||||
if (channel_type_valid &&
|
||||
(channel_type != local->tmp_channel_type &&
|
||||
channel_type != local->_oper_channel_type))
|
||||
is_offchan = true;
|
||||
|
||||
if (is_offchan && !offchan)
|
||||
return -EBUSY;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
|
@ -1605,12 +1632,70 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
|
|||
IEEE80211_SKB_CB(skb)->flags = flags;
|
||||
|
||||
skb->dev = sdata->dev;
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
|
||||
*cookie = (unsigned long) skb;
|
||||
|
||||
/*
|
||||
* Can transmit right away if the channel was the
|
||||
* right one and there's no wait involved... If a
|
||||
* wait is involved, we might otherwise not be on
|
||||
* the right channel for long enough!
|
||||
*/
|
||||
if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) {
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL);
|
||||
if (!wk) {
|
||||
kfree_skb(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
wk->type = IEEE80211_WORK_OFFCHANNEL_TX;
|
||||
wk->chan = chan;
|
||||
wk->sdata = sdata;
|
||||
wk->done = ieee80211_offchan_tx_done;
|
||||
wk->offchan_tx.frame = skb;
|
||||
wk->offchan_tx.wait = wait;
|
||||
wk->ie_len = len;
|
||||
memcpy(wk->ie, buf, len);
|
||||
|
||||
ieee80211_add_work(wk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
u64 cookie)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_work *wk;
|
||||
int ret = -ENOENT;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
list_for_each_entry(wk, &local->work_list, list) {
|
||||
if (wk->sdata != sdata)
|
||||
continue;
|
||||
|
||||
if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
|
||||
continue;
|
||||
|
||||
if (cookie != (unsigned long) wk->offchan_tx.frame)
|
||||
continue;
|
||||
|
||||
wk->timeout = jiffies;
|
||||
|
||||
ieee80211_queue_work(&local->hw, &local->work_work);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
u16 frame_type, bool reg)
|
||||
|
@ -1695,6 +1780,7 @@ struct cfg80211_ops mac80211_config_ops = {
|
|||
.remain_on_channel = ieee80211_remain_on_channel,
|
||||
.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
|
||||
.mgmt_tx = ieee80211_mgmt_tx,
|
||||
.mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,
|
||||
.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
|
||||
.mgmt_frame_register = ieee80211_mgmt_frame_register,
|
||||
.set_antenna = ieee80211_set_antenna,
|
||||
|
|
|
@ -112,34 +112,35 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
|||
char buf[71 + STA_TID_NUM * 40], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct tid_ampdu_rx *tid_rx;
|
||||
struct tid_ampdu_tx *tid_tx;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
spin_lock_bh(&sta->lock);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
|
||||
sta->ampdu_mlme.dialog_token_allocator + 1);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p,
|
||||
"TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
|
||||
for (i = 0; i < STA_TID_NUM; i++) {
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
!!sta->ampdu_mlme.tid_rx[i]);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
sta->ampdu_mlme.tid_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->ssn : 0);
|
||||
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
!!sta->ampdu_mlme.tid_tx[i]);
|
||||
for (i = 0; i < STA_TID_NUM; i++) {
|
||||
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
|
||||
tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]);
|
||||
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_rx);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_tx[i] ?
|
||||
sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
|
||||
tid_rx ? tid_rx->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
tid_rx ? tid_rx->ssn : 0);
|
||||
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", !!tid_tx);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
tid_tx ? tid_tx->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d",
|
||||
sta->ampdu_mlme.tid_tx[i] ?
|
||||
skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
|
||||
tid_tx ? skb_queue_len(&tid_tx->pending) : 0);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\n");
|
||||
}
|
||||
spin_unlock_bh(&sta->lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
}
|
||||
|
|
|
@ -260,6 +260,7 @@ enum ieee80211_work_type {
|
|||
IEEE80211_WORK_ASSOC_BEACON_WAIT,
|
||||
IEEE80211_WORK_ASSOC,
|
||||
IEEE80211_WORK_REMAIN_ON_CHANNEL,
|
||||
IEEE80211_WORK_OFFCHANNEL_TX,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -320,6 +321,10 @@ struct ieee80211_work {
|
|||
struct {
|
||||
u32 duration;
|
||||
} remain;
|
||||
struct {
|
||||
struct sk_buff *frame;
|
||||
u32 wait;
|
||||
} offchan_tx;
|
||||
};
|
||||
|
||||
int ie_len;
|
||||
|
|
|
@ -538,6 +538,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
|
|||
{
|
||||
struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
|
||||
|
||||
lockdep_assert_held(&tid_agg_rx->reorder_lock);
|
||||
|
||||
if (!skb)
|
||||
goto no_frame;
|
||||
|
||||
|
@ -557,6 +559,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
|
|||
{
|
||||
int index;
|
||||
|
||||
lockdep_assert_held(&tid_agg_rx->reorder_lock);
|
||||
|
||||
while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
|
||||
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
|
||||
tid_agg_rx->buf_size;
|
||||
|
@ -581,6 +585,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
|
|||
{
|
||||
int index, j;
|
||||
|
||||
lockdep_assert_held(&tid_agg_rx->reorder_lock);
|
||||
|
||||
/* release the buffer until next missing frame */
|
||||
index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
|
||||
tid_agg_rx->buf_size;
|
||||
|
@ -683,10 +689,11 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
|
|||
int index;
|
||||
bool ret = true;
|
||||
|
||||
spin_lock(&tid_agg_rx->reorder_lock);
|
||||
|
||||
buf_size = tid_agg_rx->buf_size;
|
||||
head_seq_num = tid_agg_rx->head_seq_num;
|
||||
|
||||
spin_lock(&tid_agg_rx->reorder_lock);
|
||||
/* frame with out of date sequence number */
|
||||
if (seq_less(mpdu_seq_num, head_seq_num)) {
|
||||
dev_kfree_skb(skb);
|
||||
|
@ -1870,9 +1877,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
|
|||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += rx->skb->len;
|
||||
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
||||
!is_multicast_ether_addr(hdr->addr1) &&
|
||||
local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) {
|
||||
if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&
|
||||
!is_multicast_ether_addr(((struct ethhdr *)rx->skb->data)->h_dest)) {
|
||||
mod_timer(&local->dynamic_ps_timer, jiffies +
|
||||
msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
|
||||
}
|
||||
|
@ -1921,9 +1927,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
|
|||
mod_timer(&tid_agg_rx->session_timer,
|
||||
TU_TO_EXP_TIME(tid_agg_rx->timeout));
|
||||
|
||||
spin_lock(&tid_agg_rx->reorder_lock);
|
||||
/* release stored frames up to start of BAR */
|
||||
ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
|
||||
frames);
|
||||
spin_unlock(&tid_agg_rx->reorder_lock);
|
||||
|
||||
kfree_skb(skb);
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
@ -2519,9 +2528,8 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
|||
}
|
||||
|
||||
/*
|
||||
* This function makes calls into the RX path. Therefore the
|
||||
* caller must hold the sta_info->lock and everything has to
|
||||
* be under rcu_read_lock protection as well.
|
||||
* This function makes calls into the RX path, therefore
|
||||
* it has to be invoked under RCU read lock.
|
||||
*/
|
||||
void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
||||
{
|
||||
|
|
|
@ -81,13 +81,14 @@ enum ieee80211_sta_info_flags {
|
|||
* @stop_initiator: initiator of a session stop
|
||||
* @tx_stop: TX DelBA frame when stopping
|
||||
*
|
||||
* This structure is protected by RCU and the per-station
|
||||
* spinlock. Assignments to the array holding it must hold
|
||||
* the spinlock, only the TX path can access it under RCU
|
||||
* lock-free if, and only if, the state has the flag
|
||||
* %HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path
|
||||
* must also acquire the spinlock and re-check the state,
|
||||
* see comments in the tx code touching it.
|
||||
* This structure's lifetime is managed by RCU, assignments to
|
||||
* the array holding it must hold the aggregation mutex.
|
||||
*
|
||||
* The TX path can access it under RCU lock-free if, and
|
||||
* only if, the state has the flag %HT_AGG_STATE_OPERATIONAL
|
||||
* set. Otherwise, the TX path must also acquire the spinlock
|
||||
* and re-check the state, see comments in the tx code
|
||||
* touching it.
|
||||
*/
|
||||
struct tid_ampdu_tx {
|
||||
struct rcu_head rcu_head;
|
||||
|
@ -115,15 +116,13 @@ struct tid_ampdu_tx {
|
|||
* @rcu_head: RCU head used for freeing this struct
|
||||
* @reorder_lock: serializes access to reorder buffer, see below.
|
||||
*
|
||||
* This structure is protected by RCU and the per-station
|
||||
* spinlock. Assignments to the array holding it must hold
|
||||
* the spinlock.
|
||||
* This structure's lifetime is managed by RCU, assignments to
|
||||
* the array holding it must hold the aggregation mutex.
|
||||
*
|
||||
* The @reorder_lock is used to protect the variables and
|
||||
* arrays such as @reorder_buf, @reorder_time, @head_seq_num,
|
||||
* @stored_mpdu_num and @reorder_time from being corrupted by
|
||||
* concurrent access of the RX path and the expired frame
|
||||
* release timer.
|
||||
* The @reorder_lock is used to protect the members of this
|
||||
* struct, except for @timeout, @buf_size and @dialog_token,
|
||||
* which are constant across the lifetime of the struct (the
|
||||
* dialog token being used only for debugging).
|
||||
*/
|
||||
struct tid_ampdu_rx {
|
||||
struct rcu_head rcu_head;
|
||||
|
|
|
@ -321,10 +321,23 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
msecs_to_jiffies(10));
|
||||
}
|
||||
|
||||
if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)
|
||||
if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
|
||||
struct ieee80211_work *wk;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(wk, &local->work_list, list) {
|
||||
if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
|
||||
continue;
|
||||
if (wk->offchan_tx.frame != skb)
|
||||
continue;
|
||||
wk->offchan_tx.frame = NULL;
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
cfg80211_mgmt_tx_status(
|
||||
skb->dev, (unsigned long) skb, skb->data, skb->len,
|
||||
!!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
|
||||
}
|
||||
|
||||
/* this was a transmitted frame, but now we want to reuse it */
|
||||
skb_orphan(skb);
|
||||
|
|
|
@ -560,6 +560,25 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
|
|||
return WORK_ACT_TIMEOUT;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_offchannel_tx(struct ieee80211_work *wk)
|
||||
{
|
||||
if (!wk->started) {
|
||||
wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);
|
||||
|
||||
/*
|
||||
* After this, offchan_tx.frame remains but now is no
|
||||
* longer a valid pointer -- we still need it as the
|
||||
* cookie for canceling this work.
|
||||
*/
|
||||
ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
|
||||
|
||||
return WORK_ACT_NONE;
|
||||
}
|
||||
|
||||
return WORK_ACT_TIMEOUT;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
|
||||
{
|
||||
|
@ -955,6 +974,9 @@ static void ieee80211_work_work(struct work_struct *work)
|
|||
case IEEE80211_WORK_REMAIN_ON_CHANNEL:
|
||||
rma = ieee80211_remain_on_channel_timeout(wk);
|
||||
break;
|
||||
case IEEE80211_WORK_OFFCHANNEL_TX:
|
||||
rma = ieee80211_offchannel_tx(wk);
|
||||
break;
|
||||
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
|
||||
rma = ieee80211_assoc_beacon_wait(wk);
|
||||
break;
|
||||
|
|
|
@ -341,9 +341,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
|
|||
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
|
||||
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct ieee80211_channel *chan,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, u64 *cookie);
|
||||
|
||||
/* SME */
|
||||
|
|
|
@ -864,9 +864,9 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
|
|||
|
||||
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct ieee80211_channel *chan,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
bool channel_type_valid,
|
||||
bool channel_type_valid, unsigned int wait,
|
||||
const u8 *buf, size_t len, u64 *cookie)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
|
@ -946,8 +946,9 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
|||
return -EINVAL;
|
||||
|
||||
/* Transmit the Action frame as requested by user space */
|
||||
return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type,
|
||||
channel_type_valid, buf, len, cookie);
|
||||
return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
|
||||
channel_type, channel_type_valid,
|
||||
wait, buf, len, cookie);
|
||||
}
|
||||
|
||||
bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
|
||||
|
|
|
@ -163,16 +163,13 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
|||
[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
|
||||
[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
|
||||
|
||||
[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
|
||||
|
||||
[NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -677,6 +674,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
CMD(remain_on_channel, REMAIN_ON_CHANNEL);
|
||||
CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
|
||||
CMD(mgmt_tx, FRAME);
|
||||
CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
|
||||
if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
|
||||
i++;
|
||||
NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
|
||||
|
@ -698,6 +696,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
|
|||
|
||||
nla_nest_end(msg, nl_cmds);
|
||||
|
||||
/* for now at least assume all drivers have it */
|
||||
if (dev->ops->mgmt_tx)
|
||||
NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
|
||||
|
||||
if (mgmt_stypes) {
|
||||
u16 stypes;
|
||||
struct nlattr *nl_ftypes, *nl_ifs;
|
||||
|
@ -4244,6 +4246,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
void *hdr;
|
||||
u64 cookie;
|
||||
struct sk_buff *msg;
|
||||
unsigned int wait = 0;
|
||||
bool offchan;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_FRAME] ||
|
||||
!info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
|
@ -4260,6 +4264,12 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_DURATION]) {
|
||||
if (!rdev->ops->mgmt_tx_cancel_wait)
|
||||
return -EINVAL;
|
||||
wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
|
||||
channel_type = nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
|
||||
|
@ -4271,6 +4281,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
channel_type_valid = true;
|
||||
}
|
||||
|
||||
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
|
||||
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
chan = rdev_freq_to_chan(rdev, freq, channel_type);
|
||||
if (chan == NULL)
|
||||
|
@ -4287,8 +4299,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
err = PTR_ERR(hdr);
|
||||
goto free_msg;
|
||||
}
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type,
|
||||
channel_type_valid,
|
||||
err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
|
||||
channel_type_valid, wait,
|
||||
nla_data(info->attrs[NL80211_ATTR_FRAME]),
|
||||
nla_len(info->attrs[NL80211_ATTR_FRAME]),
|
||||
&cookie);
|
||||
|
@ -4307,6 +4319,31 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
u64 cookie;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_COOKIE])
|
||||
return -EINVAL;
|
||||
|
||||
if (!rdev->ops->mgmt_tx_cancel_wait)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
|
||||
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
|
||||
|
||||
return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie);
|
||||
}
|
||||
|
||||
static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
|
@ -4879,6 +4916,14 @@ static struct genl_ops nl80211_ops[] = {
|
|||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
|
||||
.doit = nl80211_tx_mgmt_cancel_wait,
|
||||
.policy = nl80211_policy,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
{
|
||||
.cmd = NL80211_CMD_SET_POWER_SAVE,
|
||||
.doit = nl80211_set_power_save,
|
||||
|
|
Loading…
Reference in New Issue