Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
a130883d95
10
MAINTAINERS
10
MAINTAINERS
|
@ -5062,6 +5062,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g
|
|||
S: Maintained
|
||||
F: drivers/net/wireless/rtl818x/rtl8187*
|
||||
|
||||
RTL8192CE WIRELESS DRIVER
|
||||
M: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
M: Chaoming Li <chaoming_li@realsil.com.cn>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://linuxwireless.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/rtlwifi/
|
||||
F: drivers/net/wireless/rtlwifi/rtl8192ce/
|
||||
|
||||
S3 SAVAGE FRAMEBUFFER DRIVER
|
||||
M: Antonino Daplas <adaplas@gmail.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
|
|
|
@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
|
|||
source "drivers/net/wireless/orinoco/Kconfig"
|
||||
source "drivers/net/wireless/p54/Kconfig"
|
||||
source "drivers/net/wireless/rt2x00/Kconfig"
|
||||
source "drivers/net/wireless/rtlwifi/Kconfig"
|
||||
source "drivers/net/wireless/wl1251/Kconfig"
|
||||
source "drivers/net/wireless/wl12xx/Kconfig"
|
||||
source "drivers/net/wireless/zd1211rw/Kconfig"
|
||||
|
|
|
@ -24,6 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
|
|||
obj-$(CONFIG_ZD1211RW) += zd1211rw/
|
||||
obj-$(CONFIG_RTL8180) += rtl818x/
|
||||
obj-$(CONFIG_RTL8187) += rtl818x/
|
||||
obj-$(CONFIG_RTL8192CE) += rtlwifi/
|
||||
|
||||
# 16-bit wireless PCMCIA client drivers
|
||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||
|
|
|
@ -2351,6 +2351,10 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
|
|||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
|
||||
/* both antennas can be configured as RX or TX */
|
||||
hw->wiphy->available_antennas_tx = 0x3;
|
||||
hw->wiphy->available_antennas_rx = 0x3;
|
||||
|
||||
hw->extra_tx_headroom = 2;
|
||||
hw->channel_change_time = 5000;
|
||||
|
||||
|
@ -2654,6 +2658,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
|||
bool skip_pcu)
|
||||
{
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
int ret, ani_mode;
|
||||
|
||||
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
|
||||
|
@ -2696,6 +2701,14 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
|||
ah->ah_cal_next_nf = jiffies;
|
||||
ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
|
||||
|
||||
/* clear survey data and cycle counters */
|
||||
memset(&sc->survey, 0, sizeof(sc->survey));
|
||||
spin_lock(&common->cc_lock);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
memset(&common->cc_survey, 0, sizeof(common->cc_survey));
|
||||
memset(&common->cc_ani, 0, sizeof(common->cc_ani));
|
||||
spin_unlock(&common->cc_lock);
|
||||
|
||||
/*
|
||||
* Change channels and update the h/w rate map if we're switching;
|
||||
* e.g. 11a to 11b/g.
|
||||
|
@ -3362,25 +3375,27 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
|
|||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = sc->ah->ah_noise_floor;
|
||||
|
||||
spin_lock_bh(&common->cc_lock);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
if (cc->cycles > 0) {
|
||||
survey->filled |= SURVEY_INFO_CHANNEL_TIME |
|
||||
SURVEY_INFO_CHANNEL_TIME_BUSY |
|
||||
SURVEY_INFO_CHANNEL_TIME_RX |
|
||||
SURVEY_INFO_CHANNEL_TIME_TX;
|
||||
survey->channel_time += cc->cycles / div;
|
||||
survey->channel_time_busy += cc->rx_busy / div;
|
||||
survey->channel_time_rx += cc->rx_frame / div;
|
||||
survey->channel_time_tx += cc->tx_frame / div;
|
||||
sc->survey.channel_time += cc->cycles / div;
|
||||
sc->survey.channel_time_busy += cc->rx_busy / div;
|
||||
sc->survey.channel_time_rx += cc->rx_frame / div;
|
||||
sc->survey.channel_time_tx += cc->tx_frame / div;
|
||||
}
|
||||
memset(cc, 0, sizeof(*cc));
|
||||
spin_unlock_bh(&common->cc_lock);
|
||||
|
||||
memcpy(survey, &sc->survey, sizeof(*survey));
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->noise = sc->ah->ah_noise_floor;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM |
|
||||
SURVEY_INFO_CHANNEL_TIME |
|
||||
SURVEY_INFO_CHANNEL_TIME_BUSY |
|
||||
SURVEY_INFO_CHANNEL_TIME_RX |
|
||||
SURVEY_INFO_CHANNEL_TIME_TX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,8 @@ struct ath5k_softc {
|
|||
struct tasklet_struct ani_tasklet; /* ANI calibration */
|
||||
|
||||
struct delayed_work tx_complete_work;
|
||||
|
||||
struct survey_info survey; /* collected survey info */
|
||||
};
|
||||
|
||||
#define ath5k_hw_hasbssidmask(_ah) \
|
||||
|
|
|
@ -961,18 +961,6 @@ static void ar5008_hw_rfbus_done(struct ath_hw *ah)
|
|||
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
|
||||
}
|
||||
|
||||
static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
|
||||
{
|
||||
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
|
||||
AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
|
||||
|
||||
REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
|
||||
AR_GPIO_INPUT_MUX2_RFSILENT);
|
||||
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
|
||||
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
|
||||
}
|
||||
|
||||
static void ar5008_restore_chainmask(struct ath_hw *ah)
|
||||
{
|
||||
int rx_chainmask = ah->rxchainmask;
|
||||
|
@ -1629,7 +1617,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
|||
priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
|
||||
priv_ops->rfbus_req = ar5008_hw_rfbus_req;
|
||||
priv_ops->rfbus_done = ar5008_hw_rfbus_done;
|
||||
priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
|
||||
priv_ops->restore_chainmask = ar5008_restore_chainmask;
|
||||
priv_ops->set_diversity = ar5008_set_diversity;
|
||||
priv_ops->do_getnf = ar5008_hw_do_getnf;
|
||||
|
|
|
@ -26,24 +26,6 @@ MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002");
|
|||
|
||||
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
|
||||
|
||||
static bool ar9002_hw_macversion_supported(u32 macversion)
|
||||
{
|
||||
switch (macversion) {
|
||||
case AR_SREV_VERSION_5416_PCI:
|
||||
case AR_SREV_VERSION_5416_PCIE:
|
||||
case AR_SREV_VERSION_9160:
|
||||
case AR_SREV_VERSION_9100:
|
||||
case AR_SREV_VERSION_9280:
|
||||
case AR_SREV_VERSION_9285:
|
||||
case AR_SREV_VERSION_9287:
|
||||
case AR_SREV_VERSION_9271:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9271(ah)) {
|
||||
|
@ -565,7 +547,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
|
|||
|
||||
priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
|
||||
priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
|
||||
priv_ops->macversion_supported = ar9002_hw_macversion_supported;
|
||||
|
||||
ops->config_pci_powersave = ar9002_hw_configpcipowersave;
|
||||
|
||||
|
|
|
@ -283,7 +283,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
|||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
txPower += ah->txpower_indexoffset;
|
||||
if (txPower > 63)
|
||||
txPower = 63;
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
|
|||
|
||||
static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
|
||||
{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
|
||||
{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
|
||||
{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
|
||||
{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
|
@ -56,21 +56,21 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
|
|||
{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
|
||||
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
|
||||
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
|
||||
{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
|
||||
|
@ -88,44 +88,44 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
|
|||
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
|
||||
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
|
||||
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
|
||||
{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
|
||||
{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
|
||||
{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
|
||||
{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
|
||||
{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
|
||||
{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
|
||||
{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
|
||||
{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
|
||||
{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
|
||||
{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
|
||||
|
@ -638,6 +638,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
|
|||
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
|
||||
{0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
|
||||
{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
|
||||
{0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
|
||||
{0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
|
||||
{0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
|
||||
{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
|
||||
|
@ -680,7 +681,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
|||
{0x0000981c, 0x00020028},
|
||||
{0x00009834, 0x6400a290},
|
||||
{0x00009838, 0x0108ecff},
|
||||
{0x0000983c, 0x14750600},
|
||||
{0x0000983c, 0x0d000600},
|
||||
{0x00009880, 0x201fff00},
|
||||
{0x00009884, 0x00001042},
|
||||
{0x000098a4, 0x00200400},
|
||||
|
@ -722,7 +723,6 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
|||
{0x0000a220, 0x00000000},
|
||||
{0x0000a224, 0x00000000},
|
||||
{0x0000a228, 0x10002310},
|
||||
{0x0000a22c, 0x01036a27},
|
||||
{0x0000a23c, 0x00000000},
|
||||
{0x0000a244, 0x0c000000},
|
||||
{0x0000a2a0, 0x00000001},
|
||||
|
|
|
@ -608,120 +608,6 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_TX_IQCAL_STATUS_B1,
|
||||
AR_PHY_TX_IQCAL_STATUS_B2,
|
||||
};
|
||||
static const u32 rx_corr[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B1,
|
||||
AR_PHY_RX_IQCAL_CORR_B2,
|
||||
};
|
||||
static const u_int32_t chan_info_tab[] = {
|
||||
AR_PHY_CHAN_INFO_TAB_0,
|
||||
AR_PHY_CHAN_INFO_TAB_1,
|
||||
AR_PHY_CHAN_INFO_TAB_2,
|
||||
};
|
||||
u32 tx_corr_coeff[AR9300_MAX_CHAINS];
|
||||
s32 iq_res[6];
|
||||
s32 iqc_coeff[2];
|
||||
s32 i, j;
|
||||
u32 num_chains = 0;
|
||||
|
||||
tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0);
|
||||
tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0);
|
||||
tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0);
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (ah->txchainmask & (1 << i))
|
||||
num_chains++;
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal not complete.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_chains; i++) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
|
||||
if (REG_READ(ah, txiqcal_status[i]) &
|
||||
AR_PHY_TX_IQCAL_STATUS_FAILED) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal failed for chain %d.\n", i);
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
u_int8_t idx = 2 * j,
|
||||
offset = 4 * j;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
|
||||
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
|
||||
|
||||
/* 16 bits */
|
||||
iq_res[idx+1] = 0xffff & REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
|
||||
idx, iq_res[idx], idx+1, iq_res[idx+1]);
|
||||
}
|
||||
|
||||
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Failed in calculation of IQ correction.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
|
||||
iqc_coeff[0], iqc_coeff[1]);
|
||||
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[i],
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
|
||||
iqc_coeff[0]);
|
||||
REG_RMW_FIELD(ah, rx_corr[i],
|
||||
AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
|
||||
iqc_coeff[1] >> 7);
|
||||
REG_RMW_FIELD(ah, rx_corr[i],
|
||||
AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
|
||||
iqc_coeff[1]);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
|
||||
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
|
||||
|
||||
return;
|
||||
|
||||
TX_IQ_CAL_FAILED:
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
|
||||
}
|
||||
|
||||
static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
|
||||
{
|
||||
int diff[MPASS];
|
||||
|
@ -730,9 +616,9 @@ static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
|
|||
diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
|
||||
diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
|
||||
|
||||
if (diff[0] > MAX_MEASUREMENT &&
|
||||
diff[1] > MAX_MEASUREMENT &&
|
||||
diff[2] > MAX_MEASUREMENT)
|
||||
if (diff[0] > MAX_DIFFERENCE &&
|
||||
diff[1] > MAX_DIFFERENCE &&
|
||||
diff[2] > MAX_DIFFERENCE)
|
||||
return false;
|
||||
|
||||
if (diff[0] <= diff[1] && diff[0] <= diff[2])
|
||||
|
@ -830,6 +716,111 @@ disable_txiqcal:
|
|||
ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_TX_IQCAL_STATUS_B1,
|
||||
AR_PHY_TX_IQCAL_STATUS_B2,
|
||||
};
|
||||
static const u32 chan_info_tab[] = {
|
||||
AR_PHY_CHAN_INFO_TAB_0,
|
||||
AR_PHY_CHAN_INFO_TAB_1,
|
||||
AR_PHY_CHAN_INFO_TAB_2,
|
||||
};
|
||||
struct coeff coeff;
|
||||
s32 iq_res[6];
|
||||
s32 i, j, ip, im, nmeasurement;
|
||||
u8 nchains = get_streams(common->tx_chainmask);
|
||||
|
||||
for (ip = 0; ip < MPASS; ip++) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal not complete.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
if (nmeasurement > MAX_MEASUREMENT)
|
||||
nmeasurement = MAX_MEASUREMENT;
|
||||
|
||||
for (i = 0; i < nchains; i++) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
for (im = 0; im < nmeasurement; im++) {
|
||||
if (REG_READ(ah, txiqcal_status[i]) &
|
||||
AR_PHY_TX_IQCAL_STATUS_FAILED) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal failed for chain %d.\n", i);
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
u8 idx = 2 * j,
|
||||
offset = 4 * (3 * im + j);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ,
|
||||
0);
|
||||
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ,
|
||||
1);
|
||||
|
||||
/* 16 bits */
|
||||
iq_res[idx+1] = 0xffff & REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
|
||||
idx, iq_res[idx], idx+1, iq_res[idx+1]);
|
||||
}
|
||||
|
||||
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
|
||||
coeff.iqc_coeff)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Failed in calculation of IQ correction.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
coeff.mag_coeff[i][im][ip] =
|
||||
coeff.iqc_coeff[0] & 0x7f;
|
||||
coeff.phs_coeff[i][im][ip] =
|
||||
(coeff.iqc_coeff[0] >> 7) & 0x7f;
|
||||
|
||||
if (coeff.mag_coeff[i][im][ip] > 63)
|
||||
coeff.mag_coeff[i][im][ip] -= 128;
|
||||
if (coeff.phs_coeff[i][im][ip] > 63)
|
||||
coeff.phs_coeff[i][im][ip] -= 128;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
|
||||
|
||||
return;
|
||||
|
||||
TX_IQ_CAL_FAILED:
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
|
||||
{
|
||||
u8 tx_gain_forced;
|
||||
|
|
|
@ -73,7 +73,7 @@ static const struct ar9300_eeprom ar9300_default = {
|
|||
.regDmn = { LE16(0), LE16(0x1f) },
|
||||
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
|
||||
.opCapFlags = {
|
||||
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
|
||||
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
|
||||
.eepMisc = 0,
|
||||
},
|
||||
.rfSilent = 0,
|
||||
|
@ -650,7 +650,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
|
|||
.regDmn = { LE16(0), LE16(0x1f) },
|
||||
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
|
||||
.opCapFlags = {
|
||||
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
|
||||
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
|
||||
.eepMisc = 0,
|
||||
},
|
||||
.rfSilent = 0,
|
||||
|
@ -1228,7 +1228,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
|
|||
.regDmn = { LE16(0), LE16(0x1f) },
|
||||
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
|
||||
.opCapFlags = {
|
||||
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
|
||||
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
|
||||
.eepMisc = 0,
|
||||
},
|
||||
.rfSilent = 0,
|
||||
|
@ -1806,7 +1806,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
|
|||
.regDmn = { LE16(0), LE16(0x1f) },
|
||||
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
|
||||
.opCapFlags = {
|
||||
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
|
||||
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
|
||||
.eepMisc = 0,
|
||||
},
|
||||
.rfSilent = 0,
|
||||
|
@ -2383,7 +2383,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
|
|||
.regDmn = { LE16(0), LE16(0x1f) },
|
||||
.txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
|
||||
.opCapFlags = {
|
||||
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
|
||||
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
|
||||
.eepMisc = 0,
|
||||
},
|
||||
.rfSilent = 0,
|
||||
|
@ -2975,7 +2975,7 @@ static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
|
|||
|
||||
static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
|
||||
{
|
||||
if (fbin == AR9300_BCHAN_UNUSED)
|
||||
if (fbin == AR5416_BCHAN_UNUSED)
|
||||
return fbin;
|
||||
|
||||
return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
|
||||
|
@ -3428,18 +3428,6 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
|
||||
enum ath9k_hal_freq_band freq_band)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
|
@ -4486,7 +4474,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
|
|||
return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
|
||||
}
|
||||
|
||||
return AR9300_MAX_RATE_POWER;
|
||||
return MAX_RATE_POWER;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4495,7 +4483,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
|
|||
static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
|
||||
u16 freq, int idx, bool is2GHz)
|
||||
{
|
||||
u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
u8 *ctl_freqbin = is2GHz ?
|
||||
&eep->ctl_freqbin_2G[idx][0] :
|
||||
&eep->ctl_freqbin_5G[idx][0];
|
||||
|
@ -4505,7 +4493,7 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
|
|||
|
||||
/* Get the edge power */
|
||||
for (edge = 0;
|
||||
(edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
|
||||
(edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
|
||||
edge++) {
|
||||
/*
|
||||
* If there's an exact channel match or an inband flag set
|
||||
|
@ -4543,9 +4531,9 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
|||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
|
||||
u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] = {
|
||||
0, 3, 6, 9, AR9300_MAX_RATE_POWER
|
||||
0, 3, 6, 9, MAX_RATE_POWER
|
||||
};
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
|
@ -4756,6 +4744,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
|||
} /* end ctl mode checking */
|
||||
}
|
||||
|
||||
static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
|
||||
{
|
||||
u8 mod_idx = mcs_idx % 8;
|
||||
|
||||
if (mod_idx <= 3)
|
||||
return mod_idx ? (base_pwridx + 1) : base_pwridx;
|
||||
else
|
||||
return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
|
||||
}
|
||||
|
||||
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
|
@ -4764,16 +4762,70 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
|||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_modal_eep_header *modal_hdr;
|
||||
u8 targetPowerValT2[ar9300RateSize];
|
||||
unsigned int i = 0;
|
||||
u8 target_power_val_t2_eep[ar9300RateSize];
|
||||
unsigned int i = 0, paprd_scale_factor = 0;
|
||||
u8 pwr_idx, min_pwridx = 0;
|
||||
|
||||
ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
modal_hdr = &eep->modalHeader2G;
|
||||
else
|
||||
modal_hdr = &eep->modalHeader5G;
|
||||
|
||||
ah->paprd_ratemask =
|
||||
le32_to_cpu(modal_hdr->papdRateMaskHt20) &
|
||||
AR9300_PAPRD_RATE_MASK;
|
||||
|
||||
ah->paprd_ratemask_ht40 =
|
||||
le32_to_cpu(modal_hdr->papdRateMaskHt40) &
|
||||
AR9300_PAPRD_RATE_MASK;
|
||||
|
||||
paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
|
||||
min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
|
||||
ALL_TARGET_HT20_0_8_16;
|
||||
|
||||
if (!ah->paprd_table_write_done) {
|
||||
memcpy(target_power_val_t2_eep, targetPowerValT2,
|
||||
sizeof(targetPowerValT2));
|
||||
for (i = 0; i < 24; i++) {
|
||||
pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
|
||||
if (ah->paprd_ratemask & (1 << i)) {
|
||||
if (targetPowerValT2[pwr_idx] &&
|
||||
targetPowerValT2[pwr_idx] ==
|
||||
target_power_val_t2_eep[pwr_idx])
|
||||
targetPowerValT2[pwr_idx] -=
|
||||
paprd_scale_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(target_power_val_t2_eep, targetPowerValT2,
|
||||
sizeof(targetPowerValT2));
|
||||
}
|
||||
|
||||
ar9003_hw_set_power_per_rate_table(ah, chan,
|
||||
targetPowerValT2, cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
||||
for (i = 0; i < ar9300RateSize; i++) {
|
||||
if ((ah->paprd_ratemask & (1 << i)) &&
|
||||
(abs(targetPowerValT2[i] -
|
||||
target_power_val_t2_eep[i]) >
|
||||
paprd_scale_factor)) {
|
||||
ah->paprd_ratemask &= ~(1 << i);
|
||||
ath_dbg(common, ATH_DBG_EEPROM,
|
||||
"paprd disabled for mcs %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
regulatory->max_power_level = 0;
|
||||
for (i = 0; i < ar9300RateSize; i++) {
|
||||
if (targetPowerValT2[i] > regulatory->max_power_level)
|
||||
|
@ -4811,6 +4863,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
|||
/* Write target power array to registers */
|
||||
ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
|
||||
ar9003_hw_calibration_apply(ah, chan->channel);
|
||||
|
||||
if (IS_CHAN_2GHZ(chan)) {
|
||||
if (IS_CHAN_HT40(chan))
|
||||
i = ALL_TARGET_HT40_0_8_16;
|
||||
else
|
||||
i = ALL_TARGET_HT20_0_8_16;
|
||||
} else {
|
||||
if (IS_CHAN_HT40(chan))
|
||||
i = ALL_TARGET_HT40_7;
|
||||
else
|
||||
i = ALL_TARGET_HT20_7;
|
||||
}
|
||||
ah->paprd_target_power = targetPowerValT2[i];
|
||||
}
|
||||
|
||||
static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
|
||||
|
@ -4843,14 +4908,33 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
|
|||
return eep->modalHeader5G.spurChans;
|
||||
}
|
||||
|
||||
unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
else {
|
||||
if (chan->channel >= 5700)
|
||||
return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
else if (chan->channel >= 5400)
|
||||
return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_2);
|
||||
else
|
||||
return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
}
|
||||
}
|
||||
|
||||
const struct eeprom_ops eep_ar9300_ops = {
|
||||
.check_eeprom = ath9k_hw_ar9300_check_eeprom,
|
||||
.get_eeprom = ath9k_hw_ar9300_get_eeprom,
|
||||
.fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
|
||||
.get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
|
||||
.get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
|
||||
.get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
|
||||
.get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
|
||||
.set_board_values = ath9k_hw_ar9300_set_board_values,
|
||||
.set_addac = ath9k_hw_ar9300_set_addac,
|
||||
.set_txpower = ath9k_hw_ar9300_set_txpower,
|
||||
|
|
|
@ -20,47 +20,22 @@
|
|||
/* #define AR9300_NUM_CTLS 21 */
|
||||
#define AR9300_NUM_CTLS_5G 9
|
||||
#define AR9300_NUM_CTLS_2G 12
|
||||
#define AR9300_CTL_MODE_M 0xF
|
||||
#define AR9300_NUM_BAND_EDGES_5G 8
|
||||
#define AR9300_NUM_BAND_EDGES_2G 4
|
||||
#define AR9300_NUM_PD_GAINS 4
|
||||
#define AR9300_PD_GAINS_IN_MASK 4
|
||||
#define AR9300_PD_GAIN_ICEPTS 5
|
||||
#define AR9300_EEPROM_MODAL_SPURS 5
|
||||
#define AR9300_MAX_RATE_POWER 63
|
||||
#define AR9300_NUM_PDADC_VALUES 128
|
||||
#define AR9300_NUM_RATES 16
|
||||
#define AR9300_BCHAN_UNUSED 0xFF
|
||||
#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
|
||||
#define AR9300_OPFLAGS_11A 0x01
|
||||
#define AR9300_OPFLAGS_11G 0x02
|
||||
#define AR9300_OPFLAGS_5G_HT40 0x04
|
||||
#define AR9300_OPFLAGS_2G_HT40 0x08
|
||||
#define AR9300_OPFLAGS_5G_HT20 0x10
|
||||
#define AR9300_OPFLAGS_2G_HT20 0x20
|
||||
#define AR9300_EEPMISC_BIG_ENDIAN 0x01
|
||||
#define AR9300_EEPMISC_WOW 0x02
|
||||
#define AR9300_CUSTOMER_DATA_SIZE 20
|
||||
|
||||
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
|
||||
#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
|
||||
#define AR9300_MAX_CHAINS 3
|
||||
#define AR9300_ANT_16S 25
|
||||
#define AR9300_FUTURE_MODAL_SZ 6
|
||||
|
||||
#define AR9300_NUM_ANT_CHAIN_FIELDS 7
|
||||
#define AR9300_NUM_ANT_COMMON_FIELDS 4
|
||||
#define AR9300_SIZE_ANT_CHAIN_FIELD 3
|
||||
#define AR9300_SIZE_ANT_COMMON_FIELD 4
|
||||
#define AR9300_ANT_CHAIN_MASK 0x7
|
||||
#define AR9300_ANT_COMMON_MASK 0xf
|
||||
#define AR9300_CHAIN_0_IDX 0
|
||||
#define AR9300_CHAIN_1_IDX 1
|
||||
#define AR9300_CHAIN_2_IDX 2
|
||||
|
||||
#define AR928X_NUM_ANT_CHAIN_FIELDS 6
|
||||
#define AR928X_SIZE_ANT_CHAIN_FIELD 2
|
||||
#define AR928X_ANT_CHAIN_MASK 0x3
|
||||
#define AR9300_PAPRD_RATE_MASK 0x01ffffff
|
||||
#define AR9300_PAPRD_SCALE_1 0x0e000000
|
||||
#define AR9300_PAPRD_SCALE_1_S 25
|
||||
#define AR9300_PAPRD_SCALE_2 0x70000000
|
||||
#define AR9300_PAPRD_SCALE_2_S 28
|
||||
|
||||
/* Delta from which to start power to pdadc table */
|
||||
/* This offset is used in both open loop and closed loop power control
|
||||
|
@ -71,12 +46,8 @@
|
|||
*/
|
||||
#define AR9300_PWR_TABLE_OFFSET 0
|
||||
|
||||
/* enable flags for voltage and temp compensation */
|
||||
#define ENABLE_TEMP_COMPENSATION 0x01
|
||||
#define ENABLE_VOLT_COMPENSATION 0x02
|
||||
/* byte addressable */
|
||||
#define AR9300_EEPROM_SIZE (16*1024)
|
||||
#define FIXED_CCA_THRESHOLD 15
|
||||
|
||||
#define AR9300_BASE_ADDR_4K 0xfff
|
||||
#define AR9300_BASE_ADDR 0x3ff
|
||||
|
@ -226,7 +197,7 @@ struct ar9300_modal_eep_header {
|
|||
int8_t tempSlope;
|
||||
int8_t voltSlope;
|
||||
/* spur channels in usual fbin coding format */
|
||||
u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
|
||||
u8 spurChans[AR_EEPROM_MODAL_SPURS];
|
||||
/* 3 Check if the register is per chain */
|
||||
int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
|
||||
u8 ob[AR9300_MAX_CHAINS];
|
||||
|
@ -344,4 +315,7 @@ s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
|
|||
s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
|
||||
|
||||
u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
|
||||
|
||||
unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
#endif
|
||||
|
|
|
@ -21,18 +21,6 @@
|
|||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
static bool ar9003_hw_macversion_supported(u32 macversion)
|
||||
{
|
||||
switch (macversion) {
|
||||
case AR_SREV_VERSION_9300:
|
||||
case AR_SREV_VERSION_9485:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The AR9003 family uses a new INI format (pre, core, post
|
||||
* arrays per subsystem). This provides support for the
|
||||
|
@ -322,7 +310,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
|
|||
|
||||
priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
|
||||
priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
|
||||
priv_ops->macversion_supported = ar9003_hw_macversion_supported;
|
||||
|
||||
ops->config_pci_powersave = ar9003_hw_configpcipowersave;
|
||||
|
||||
|
|
|
@ -322,7 +322,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
|||
if (txpower > ah->txpower_limit)
|
||||
txpower = ah->txpower_limit;
|
||||
|
||||
txpower += ah->txpower_indexoffset;
|
||||
if (txpower > 63)
|
||||
txpower = 63;
|
||||
|
||||
|
|
|
@ -19,6 +19,20 @@
|
|||
|
||||
void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
|
||||
if (val) {
|
||||
ah->paprd_table_write_done = true;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
chan->chan->max_antenna_gain * 2,
|
||||
chan->chan->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
|
||||
AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
|
||||
if (ah->caps.tx_chainmask & BIT(1))
|
||||
|
@ -30,10 +44,63 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
|||
}
|
||||
EXPORT_SYMBOL(ar9003_paprd_enable);
|
||||
|
||||
static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
static int ar9003_get_training_power_2g(struct ath_hw *ah)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_modal_eep_header *hdr;
|
||||
struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
|
||||
unsigned int power, scale, delta;
|
||||
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
|
||||
power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
||||
AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
||||
|
||||
delta = abs((int) ah->paprd_target_power - (int) power);
|
||||
if (delta > scale)
|
||||
return -1;
|
||||
|
||||
if (delta < 4)
|
||||
power -= 4 - delta;
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
static int ar9003_get_training_power_5g(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
unsigned int power, scale, delta;
|
||||
|
||||
if (chan->channel >= 5700)
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
else if (chan->channel >= 5400)
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_2);
|
||||
else
|
||||
scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
||||
AR9300_PAPRD_SCALE_1);
|
||||
|
||||
if (IS_CHAN_HT40(chan))
|
||||
power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
|
||||
AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
|
||||
else
|
||||
power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
|
||||
AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
|
||||
|
||||
power += scale;
|
||||
delta = abs((int) ah->paprd_target_power - (int) power);
|
||||
if (delta > scale)
|
||||
return -1;
|
||||
|
||||
power += 2 * get_streams(common->tx_chainmask);
|
||||
return power;
|
||||
}
|
||||
|
||||
static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
static const u32 ctrl0[3] = {
|
||||
AR_PHY_PAPRD_CTRL0_B0,
|
||||
AR_PHY_PAPRD_CTRL0_B1,
|
||||
|
@ -44,21 +111,30 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
|||
AR_PHY_PAPRD_CTRL1_B1,
|
||||
AR_PHY_PAPRD_CTRL1_B2
|
||||
};
|
||||
u32 am_mask, ht40_mask;
|
||||
int training_power;
|
||||
int i;
|
||||
|
||||
if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
|
||||
hdr = &eep->modalHeader5G;
|
||||
if (IS_CHAN_2GHZ(ah->curchan))
|
||||
training_power = ar9003_get_training_power_2g(ah);
|
||||
else
|
||||
hdr = &eep->modalHeader2G;
|
||||
training_power = ar9003_get_training_power_5g(ah);
|
||||
|
||||
am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
|
||||
ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
|
||||
if (training_power < 0) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"PAPRD target power delta out of range");
|
||||
return -ERANGE;
|
||||
}
|
||||
ah->paprd_training_power = training_power;
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Training power: %d, Target power: %d\n",
|
||||
ah->paprd_training_power, ah->paprd_target_power);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
|
||||
ah->paprd_ratemask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
|
||||
ah->paprd_ratemask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
|
||||
ah->paprd_ratemask_ht40);
|
||||
|
||||
for (i = 0; i < ah->caps.max_txchains; i++) {
|
||||
REG_RMW_FIELD(ah, ctrl0[i],
|
||||
|
@ -141,6 +217,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
|||
AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
|
||||
AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
|
||||
|
@ -595,15 +672,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
|
|||
{
|
||||
u32 *paprd_table_val = caldata->pa_table[chain];
|
||||
u32 small_signal_gain = caldata->small_signal_gain[chain];
|
||||
u32 training_power;
|
||||
u32 training_power = ah->paprd_training_power;
|
||||
u32 reg = 0;
|
||||
int i;
|
||||
|
||||
training_power =
|
||||
REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
||||
AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
||||
training_power -= 4;
|
||||
|
||||
if (chain == 0)
|
||||
reg = AR_PHY_PAPRD_MEM_TAB_B0;
|
||||
else if (chain == 1)
|
||||
|
@ -643,14 +715,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
|
|||
|
||||
int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
|
||||
{
|
||||
|
||||
unsigned int i, desired_gain, gain_index;
|
||||
unsigned int train_power;
|
||||
|
||||
train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
||||
AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
||||
|
||||
train_power = train_power - 4;
|
||||
unsigned int train_power = ah->paprd_training_power;
|
||||
|
||||
desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
|
||||
|
||||
|
@ -716,7 +782,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
|
|||
|
||||
int ar9003_paprd_init_table(struct ath_hw *ah)
|
||||
{
|
||||
ar9003_paprd_setup_single_table(ah);
|
||||
int ret;
|
||||
|
||||
ret = ar9003_paprd_setup_single_table(ah);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ar9003_paprd_get_gain_table(ah);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -578,10 +578,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
|||
u32 reg = INI_RA(iniArr, i, 0);
|
||||
u32 val = INI_RA(iniArr, i, column);
|
||||
|
||||
if (reg >= 0x16000 && reg < 0x17000)
|
||||
ath9k_hw_analog_shift_regwrite(ah, reg, val);
|
||||
else
|
||||
REG_WRITE(ah, reg, val);
|
||||
REG_WRITE(ah, reg, val);
|
||||
|
||||
DO_DELAY(regWrites);
|
||||
}
|
||||
|
@ -748,28 +745,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah)
|
|||
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the interrupt and GPIO values so the ISR can disable RF
|
||||
* on a switch signal. Assumes GPIO port and interrupt polarity
|
||||
* are set prior to call.
|
||||
*/
|
||||
static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
|
||||
{
|
||||
/* Connect rfsilent_bb_l to baseband */
|
||||
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
|
||||
AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
|
||||
/* Set input mux for rfsilent_bb_l to GPIO #0 */
|
||||
REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
|
||||
AR_GPIO_INPUT_MUX2_RFSILENT);
|
||||
|
||||
/*
|
||||
* Configure the desired GPIO port for input and
|
||||
* enable baseband rf silence.
|
||||
*/
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
|
||||
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
|
||||
{
|
||||
u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
|
||||
|
@ -1206,7 +1181,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
|||
priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
|
||||
priv_ops->rfbus_req = ar9003_hw_rfbus_req;
|
||||
priv_ops->rfbus_done = ar9003_hw_rfbus_done;
|
||||
priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
|
||||
priv_ops->set_diversity = ar9003_hw_set_diversity;
|
||||
priv_ops->ani_control = ar9003_hw_ani_control;
|
||||
priv_ops->do_getnf = ar9003_hw_do_getnf;
|
||||
|
|
|
@ -1090,6 +1090,14 @@
|
|||
#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
|
||||
#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
|
||||
|
||||
#define AR_PHY_POWERTX_RATE6 (AR_SM_BASE + 0x1d4)
|
||||
#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5 0x3F00
|
||||
#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S 8
|
||||
|
||||
#define AR_PHY_POWERTX_RATE8 (AR_SM_BASE + 0x1dc)
|
||||
#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00
|
||||
#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8
|
||||
|
||||
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
|
||||
|
||||
#endif /* AR9003_PHY_H */
|
||||
|
|
|
@ -57,6 +57,8 @@ struct ath_node;
|
|||
|
||||
#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#define ATH9K_PM_QOS_DEFAULT_VALUE 55
|
||||
|
||||
#define TSF_TO_TU(_h,_l) \
|
||||
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
|
||||
|
||||
|
@ -187,6 +189,7 @@ struct ath_txq {
|
|||
struct list_head axq_q;
|
||||
spinlock_t axq_lock;
|
||||
u32 axq_depth;
|
||||
u32 axq_ampdu_depth;
|
||||
bool stopped;
|
||||
bool axq_tx_inprogress;
|
||||
struct list_head axq_acq;
|
||||
|
@ -663,6 +666,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
|||
extern struct ieee80211_ops ath9k_ops;
|
||||
extern int modparam_nohwcrypt;
|
||||
extern int led_blink;
|
||||
extern int ath9k_pm_qos_value;
|
||||
|
||||
irqreturn_t ath_isr(int irq, void *dev);
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
|
@ -671,7 +675,6 @@ void ath9k_deinit_device(struct ath_softc *sc);
|
|||
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
struct ath9k_channel *ichan);
|
||||
void ath_update_chainmask(struct ath_softc *sc, int is_ht);
|
||||
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
struct ath9k_channel *hchan);
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
|
|||
u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
|
||||
bool is2GHz, int num_band_edges)
|
||||
{
|
||||
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < num_band_edges) &&
|
||||
|
@ -279,6 +279,219 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
|
|||
}
|
||||
}
|
||||
|
||||
void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
void *pRawDataSet,
|
||||
u8 *bChans, u16 availPiers,
|
||||
u16 tPdGainOverlap,
|
||||
u16 *pPdGainBoundaries, u8 *pPDADCValues,
|
||||
u16 numXpdGains)
|
||||
{
|
||||
int i, j, k;
|
||||
int16_t ss;
|
||||
u16 idxL = 0, idxR = 0, numPiers;
|
||||
static u8 vpdTableL[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableR[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableI[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
|
||||
u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
|
||||
u8 minPwrT4[AR5416_NUM_PD_GAINS];
|
||||
u8 maxPwrT4[AR5416_NUM_PD_GAINS];
|
||||
int16_t vpdStep;
|
||||
int16_t tmpVal;
|
||||
u16 sizeCurrVpdTable, maxIndex, tgtIndex;
|
||||
bool match;
|
||||
int16_t minDelta = 0;
|
||||
struct chan_centers centers;
|
||||
int pdgain_boundary_default;
|
||||
struct cal_data_per_freq *data_def = pRawDataSet;
|
||||
struct cal_data_per_freq_4k *data_4k = pRawDataSet;
|
||||
struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
|
||||
bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
|
||||
int intercepts;
|
||||
|
||||
if (AR_SREV_9287(ah))
|
||||
intercepts = AR9287_PD_GAIN_ICEPTS;
|
||||
else
|
||||
intercepts = AR5416_PD_GAIN_ICEPTS;
|
||||
|
||||
memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
for (numPiers = 0; numPiers < availPiers; numPiers++) {
|
||||
if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
|
||||
break;
|
||||
}
|
||||
|
||||
match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
|
||||
IS_CHAN_2GHZ(chan)),
|
||||
bChans, numPiers, &idxL, &idxR);
|
||||
|
||||
if (match) {
|
||||
if (AR_SREV_9287(ah)) {
|
||||
/* FIXME: array overrun? */
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
data_9287[idxL].pwrPdg[i],
|
||||
data_9287[idxL].vpdPdg[i],
|
||||
intercepts,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
} else if (eeprom_4k) {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
data_4k[idxL].pwrPdg[i],
|
||||
data_4k[idxL].vpdPdg[i],
|
||||
intercepts,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
data_def[idxL].pwrPdg[i],
|
||||
data_def[idxL].vpdPdg[i],
|
||||
intercepts,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
if (AR_SREV_9287(ah)) {
|
||||
pVpdL = data_9287[idxL].vpdPdg[i];
|
||||
pPwrL = data_9287[idxL].pwrPdg[i];
|
||||
pVpdR = data_9287[idxR].vpdPdg[i];
|
||||
pPwrR = data_9287[idxR].pwrPdg[i];
|
||||
} else if (eeprom_4k) {
|
||||
pVpdL = data_4k[idxL].vpdPdg[i];
|
||||
pPwrL = data_4k[idxL].pwrPdg[i];
|
||||
pVpdR = data_4k[idxR].vpdPdg[i];
|
||||
pPwrR = data_4k[idxR].pwrPdg[i];
|
||||
} else {
|
||||
pVpdL = data_def[idxL].vpdPdg[i];
|
||||
pPwrL = data_def[idxL].pwrPdg[i];
|
||||
pVpdR = data_def[idxR].vpdPdg[i];
|
||||
pPwrR = data_def[idxR].pwrPdg[i];
|
||||
}
|
||||
|
||||
minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
|
||||
|
||||
maxPwrT4[i] =
|
||||
min(pPwrL[intercepts - 1],
|
||||
pPwrR[intercepts - 1]);
|
||||
|
||||
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrL, pVpdL,
|
||||
intercepts,
|
||||
vpdTableL[i]);
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrR, pVpdR,
|
||||
intercepts,
|
||||
vpdTableR[i]);
|
||||
|
||||
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
|
||||
vpdTableI[i][j] =
|
||||
(u8)(ath9k_hw_interpolate((u16)
|
||||
FREQ2FBIN(centers.
|
||||
synth_center,
|
||||
IS_CHAN_2GHZ
|
||||
(chan)),
|
||||
bChans[idxL], bChans[idxR],
|
||||
vpdTableL[i][j], vpdTableR[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
if (i == (numXpdGains - 1))
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)(maxPwrT4[i] / 2);
|
||||
else
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
|
||||
|
||||
pPdGainBoundaries[i] =
|
||||
min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
|
||||
|
||||
if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
|
||||
minDelta = pPdGainBoundaries[0] - 23;
|
||||
pPdGainBoundaries[0] = 23;
|
||||
} else {
|
||||
minDelta = 0;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
ss = (int16_t)(0 - (minPwrT4[i] / 2));
|
||||
else
|
||||
ss = 0;
|
||||
} else {
|
||||
ss = (int16_t)((pPdGainBoundaries[i - 1] -
|
||||
(minPwrT4[i] / 2)) -
|
||||
tPdGainOverlap + 1 + minDelta);
|
||||
}
|
||||
vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
|
||||
pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
|
||||
sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
|
||||
tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
|
||||
(minPwrT4[i] / 2));
|
||||
maxIndex = (tgtIndex < sizeCurrVpdTable) ?
|
||||
tgtIndex : sizeCurrVpdTable;
|
||||
|
||||
while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
pPDADCValues[k++] = vpdTableI[i][ss++];
|
||||
}
|
||||
|
||||
vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
|
||||
vpdTableI[i][sizeCurrVpdTable - 2]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
if (tgtIndex >= maxIndex) {
|
||||
while ((ss <= tgtIndex) &&
|
||||
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
|
||||
(ss - maxIndex + 1) * vpdStep));
|
||||
pPDADCValues[k++] = (u8)((tmpVal > 255) ?
|
||||
255 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eeprom_4k)
|
||||
pdgain_boundary_default = 58;
|
||||
else
|
||||
pdgain_boundary_default = pPdGainBoundaries[i - 1];
|
||||
|
||||
while (i < AR5416_PD_GAINS_IN_MASK) {
|
||||
pPdGainBoundaries[i] = pdgain_boundary_default;
|
||||
i++;
|
||||
}
|
||||
|
||||
while (k < AR5416_NUM_PDADC_VALUES) {
|
||||
pPDADCValues[k] = pPDADCValues[k - 1];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
int ath9k_hw_eeprom_init(struct ath_hw *ah)
|
||||
{
|
||||
int status;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#ifndef EEPROM_H
|
||||
#define EEPROM_H
|
||||
|
||||
#define AR_EEPROM_MODAL_SPURS 5
|
||||
|
||||
#include "../ath.h"
|
||||
#include <net/cfg80211.h>
|
||||
#include "ar9003_eeprom.h"
|
||||
|
@ -149,8 +151,6 @@
|
|||
#define AR5416_NUM_PD_GAINS 4
|
||||
#define AR5416_PD_GAINS_IN_MASK 4
|
||||
#define AR5416_PD_GAIN_ICEPTS 5
|
||||
#define AR5416_EEPROM_MODAL_SPURS 5
|
||||
#define AR5416_MAX_RATE_POWER 63
|
||||
#define AR5416_NUM_PDADC_VALUES 128
|
||||
#define AR5416_BCHAN_UNUSED 0xFF
|
||||
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
|
||||
|
@ -175,8 +175,6 @@
|
|||
#define AR5416_EEP4K_NUM_CTLS 12
|
||||
#define AR5416_EEP4K_NUM_BAND_EDGES 4
|
||||
#define AR5416_EEP4K_NUM_PD_GAINS 2
|
||||
#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
|
||||
#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
|
||||
#define AR5416_EEP4K_MAX_CHAINS 1
|
||||
|
||||
#define AR9280_TX_GAIN_TABLE_SIZE 22
|
||||
|
@ -198,35 +196,12 @@
|
|||
#define AR9287_NUM_2G_40_TARGET_POWERS 3
|
||||
#define AR9287_NUM_CTLS 12
|
||||
#define AR9287_NUM_BAND_EDGES 4
|
||||
#define AR9287_NUM_PD_GAINS 4
|
||||
#define AR9287_PD_GAINS_IN_MASK 4
|
||||
#define AR9287_PD_GAIN_ICEPTS 1
|
||||
#define AR9287_EEPROM_MODAL_SPURS 5
|
||||
#define AR9287_MAX_RATE_POWER 63
|
||||
#define AR9287_NUM_PDADC_VALUES 128
|
||||
#define AR9287_NUM_RATES 16
|
||||
#define AR9287_BCHAN_UNUSED 0xFF
|
||||
#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64
|
||||
#define AR9287_OPFLAGS_11A 0x01
|
||||
#define AR9287_OPFLAGS_11G 0x02
|
||||
#define AR9287_OPFLAGS_2G_HT40 0x08
|
||||
#define AR9287_OPFLAGS_2G_HT20 0x20
|
||||
#define AR9287_OPFLAGS_5G_HT40 0x04
|
||||
#define AR9287_OPFLAGS_5G_HT20 0x10
|
||||
#define AR9287_EEPMISC_BIG_ENDIAN 0x01
|
||||
#define AR9287_EEPMISC_WOW 0x02
|
||||
#define AR9287_MAX_CHAINS 2
|
||||
#define AR9287_ANT_16S 32
|
||||
#define AR9287_custdatasize 20
|
||||
|
||||
#define AR9287_NUM_ANT_CHAIN_FIELDS 6
|
||||
#define AR9287_NUM_ANT_COMMON_FIELDS 4
|
||||
#define AR9287_SIZE_ANT_CHAIN_FIELD 2
|
||||
#define AR9287_SIZE_ANT_COMMON_FIELD 4
|
||||
#define AR9287_ANT_CHAIN_MASK 0x3
|
||||
#define AR9287_ANT_COMMON_MASK 0xf
|
||||
#define AR9287_CHAIN_0_IDX 0
|
||||
#define AR9287_CHAIN_1_IDX 1
|
||||
#define AR9287_DATA_SZ 32
|
||||
|
||||
#define AR9287_PWR_TABLE_OFFSET_DB -5
|
||||
|
@ -396,7 +371,7 @@ struct modal_eep_header {
|
|||
u16 xpaBiasLvlFreq[3];
|
||||
u8 futureModal[6];
|
||||
|
||||
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
|
||||
struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
|
||||
} __packed;
|
||||
|
||||
struct calDataPerFreqOpLoop {
|
||||
|
@ -464,7 +439,7 @@ struct modal_eep_4k_header {
|
|||
u8 db2_4:4, reserved:4;
|
||||
#endif
|
||||
u8 futureModal[4];
|
||||
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
|
||||
struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
|
||||
} __packed;
|
||||
|
||||
struct base_eep_ar9287_header {
|
||||
|
@ -522,7 +497,7 @@ struct modal_eep_ar9287_header {
|
|||
u8 ob_qam;
|
||||
u8 ob_pal_off;
|
||||
u8 futureModal[30];
|
||||
struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
|
||||
struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
|
||||
} __packed;
|
||||
|
||||
struct cal_data_per_freq {
|
||||
|
@ -531,8 +506,8 @@ struct cal_data_per_freq {
|
|||
} __packed;
|
||||
|
||||
struct cal_data_per_freq_4k {
|
||||
u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
|
||||
u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
|
||||
} __packed;
|
||||
|
||||
struct cal_target_power_leg {
|
||||
|
@ -558,8 +533,8 @@ struct cal_data_op_loop_ar9287 {
|
|||
} __packed;
|
||||
|
||||
struct cal_data_per_freq_ar9287 {
|
||||
u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
|
||||
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
|
||||
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
|
||||
} __packed;
|
||||
|
||||
union cal_data_per_freq_ar9287_u {
|
||||
|
@ -674,10 +649,6 @@ struct eeprom_ops {
|
|||
bool (*fill_eeprom)(struct ath_hw *hw);
|
||||
int (*get_eeprom_ver)(struct ath_hw *hw);
|
||||
int (*get_eeprom_rev)(struct ath_hw *hw);
|
||||
u8 (*get_num_ant_config)(struct ath_hw *hw,
|
||||
enum ath9k_hal_freq_band band);
|
||||
u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
|
||||
struct ath9k_channel *chan);
|
||||
void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
|
||||
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
|
||||
void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
|
||||
|
@ -716,6 +687,14 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
|
|||
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
|
||||
int ath9k_hw_eeprom_init(struct ath_hw *ah);
|
||||
|
||||
void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
void *pRawDataSet,
|
||||
u8 *bChans, u16 availPiers,
|
||||
u16 tPdGainOverlap,
|
||||
u16 *pPdGainBoundaries, u8 *pPDADCValues,
|
||||
u16 numXpdGains);
|
||||
|
||||
#define ar5416_get_ntxchains(_txchainmask) \
|
||||
(((_txchainmask >> 2) & 1) + \
|
||||
((_txchainmask >> 1) & 1) + (_txchainmask & 1))
|
||||
|
|
|
@ -153,7 +153,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
|
|||
eep->modalHeader.antCtrlChain[i] = integer;
|
||||
}
|
||||
|
||||
for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
word = swab16(eep->modalHeader.spurChans[i].spurChan);
|
||||
eep->modalHeader.spurChans[i].spurChan = word;
|
||||
}
|
||||
|
@ -227,173 +227,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
|||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
struct cal_data_per_freq_4k *pRawDataSet,
|
||||
u8 *bChans, u16 availPiers,
|
||||
u16 tPdGainOverlap,
|
||||
u16 *pPdGainBoundaries, u8 *pPDADCValues,
|
||||
u16 numXpdGains)
|
||||
{
|
||||
#define TMP_VAL_VPD_TABLE \
|
||||
((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
|
||||
int i, j, k;
|
||||
int16_t ss;
|
||||
u16 idxL = 0, idxR = 0, numPiers;
|
||||
static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
|
||||
u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
|
||||
u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
|
||||
u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
|
||||
int16_t vpdStep;
|
||||
int16_t tmpVal;
|
||||
u16 sizeCurrVpdTable, maxIndex, tgtIndex;
|
||||
bool match;
|
||||
int16_t minDelta = 0;
|
||||
struct chan_centers centers;
|
||||
#define PD_GAIN_BOUNDARY_DEFAULT 58;
|
||||
|
||||
memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
for (numPiers = 0; numPiers < availPiers; numPiers++) {
|
||||
if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
|
||||
break;
|
||||
}
|
||||
|
||||
match = ath9k_hw_get_lower_upper_index(
|
||||
(u8)FREQ2FBIN(centers.synth_center,
|
||||
IS_CHAN_2GHZ(chan)), bChans, numPiers,
|
||||
&idxL, &idxR);
|
||||
|
||||
if (match) {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pRawDataSet[idxL].pwrPdg[i],
|
||||
pRawDataSet[idxL].vpdPdg[i],
|
||||
AR5416_EEP4K_PD_GAIN_ICEPTS,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
pVpdL = pRawDataSet[idxL].vpdPdg[i];
|
||||
pPwrL = pRawDataSet[idxL].pwrPdg[i];
|
||||
pVpdR = pRawDataSet[idxR].vpdPdg[i];
|
||||
pPwrR = pRawDataSet[idxR].pwrPdg[i];
|
||||
|
||||
minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
|
||||
|
||||
maxPwrT4[i] =
|
||||
min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
|
||||
pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
|
||||
|
||||
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrL, pVpdL,
|
||||
AR5416_EEP4K_PD_GAIN_ICEPTS,
|
||||
vpdTableL[i]);
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrR, pVpdR,
|
||||
AR5416_EEP4K_PD_GAIN_ICEPTS,
|
||||
vpdTableR[i]);
|
||||
|
||||
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
|
||||
vpdTableI[i][j] =
|
||||
(u8)(ath9k_hw_interpolate((u16)
|
||||
FREQ2FBIN(centers.
|
||||
synth_center,
|
||||
IS_CHAN_2GHZ
|
||||
(chan)),
|
||||
bChans[idxL], bChans[idxR],
|
||||
vpdTableL[i][j], vpdTableR[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
if (i == (numXpdGains - 1))
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)(maxPwrT4[i] / 2);
|
||||
else
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
|
||||
|
||||
pPdGainBoundaries[i] =
|
||||
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
|
||||
|
||||
if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
|
||||
minDelta = pPdGainBoundaries[0] - 23;
|
||||
pPdGainBoundaries[0] = 23;
|
||||
} else {
|
||||
minDelta = 0;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
ss = (int16_t)(0 - (minPwrT4[i] / 2));
|
||||
else
|
||||
ss = 0;
|
||||
} else {
|
||||
ss = (int16_t)((pPdGainBoundaries[i - 1] -
|
||||
(minPwrT4[i] / 2)) -
|
||||
tPdGainOverlap + 1 + minDelta);
|
||||
}
|
||||
vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
|
||||
pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
|
||||
sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
|
||||
tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
|
||||
(minPwrT4[i] / 2));
|
||||
maxIndex = (tgtIndex < sizeCurrVpdTable) ?
|
||||
tgtIndex : sizeCurrVpdTable;
|
||||
|
||||
while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
|
||||
pPDADCValues[k++] = vpdTableI[i][ss++];
|
||||
|
||||
vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
|
||||
vpdTableI[i][sizeCurrVpdTable - 2]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
if (tgtIndex >= maxIndex) {
|
||||
while ((ss <= tgtIndex) &&
|
||||
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
|
||||
pPDADCValues[k++] = (u8)((tmpVal > 255) ?
|
||||
255 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
|
||||
pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
|
||||
i++;
|
||||
}
|
||||
|
||||
while (k < AR5416_NUM_PDADC_VALUES) {
|
||||
pPDADCValues[k] = pPDADCValues[k - 1];
|
||||
k++;
|
||||
}
|
||||
|
||||
return;
|
||||
#undef TMP_VAL_VPD_TABLE
|
||||
}
|
||||
|
||||
static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int16_t *pTxPowerIndexOffset)
|
||||
|
@ -404,7 +237,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
|||
u8 *pCalBChans = NULL;
|
||||
u16 pdGainOverlap_t2;
|
||||
static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
|
||||
u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
|
||||
u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
|
||||
u16 numPiers, i, j;
|
||||
u16 numXpdGain, xpdMask;
|
||||
u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
|
||||
|
@ -426,12 +259,12 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
|||
|
||||
numXpdGain = 0;
|
||||
|
||||
for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
|
||||
if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
|
||||
for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
|
||||
if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
|
||||
if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
|
||||
break;
|
||||
xpdGainValues[numXpdGain] =
|
||||
(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
|
||||
(u16)(AR5416_PD_GAINS_IN_MASK - i);
|
||||
numXpdGain++;
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +288,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
|
|||
if (pEepData->baseEepHeader.txMask & (1 << i)) {
|
||||
pRawDataset = pEepData->calPierData2G[i];
|
||||
|
||||
ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
|
||||
ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
|
||||
pRawDataset, pCalBChans,
|
||||
numPiers, pdGainOverlap_t2,
|
||||
gainBoundaries,
|
||||
|
@ -528,7 +361,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
u16 twiceMinEdgePower;
|
||||
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 numCtlModes;
|
||||
const u16 *pCtlMode;
|
||||
|
@ -537,7 +370,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
struct cal_ctl_data_4k *rep;
|
||||
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
|
||||
0, { 0, 0, 0, 0}
|
||||
};
|
||||
|
@ -613,7 +446,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
|||
|
||||
if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
|
||||
ah->eep_ops->get_eeprom_rev(ah) <= 2)
|
||||
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
|
||||
for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
|
||||
pEepData->ctlIndex[i]; i++) {
|
||||
|
@ -752,8 +585,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
|||
regulatory->max_power_level = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
|
||||
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
|
||||
if (ratesArray[i] > AR5416_MAX_RATE_POWER)
|
||||
ratesArray[i] = AR5416_MAX_RATE_POWER;
|
||||
if (ratesArray[i] > MAX_RATE_POWER)
|
||||
ratesArray[i] = MAX_RATE_POWER;
|
||||
|
||||
if (ratesArray[i] > regulatory->max_power_level)
|
||||
regulatory->max_power_level = ratesArray[i];
|
||||
|
@ -937,8 +770,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
|
|||
pModal = &eep->modalHeader;
|
||||
txRxAttenLocal = 23;
|
||||
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM,
|
||||
ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
|
||||
|
||||
/* Single chain for 4K EEPROM*/
|
||||
ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
|
||||
|
@ -1154,21 +986,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
|
|||
}
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
|
||||
struct modal_eep_4k_header *pModal = &eep->modalHeader;
|
||||
|
||||
return pModal->antCtrlCommon;
|
||||
}
|
||||
|
||||
static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
|
||||
enum ath9k_hal_freq_band freq_band)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
||||
{
|
||||
#define EEP_MAP4K_SPURCHAN \
|
||||
|
@ -1205,8 +1022,6 @@ const struct eeprom_ops eep_4k_ops = {
|
|||
.fill_eeprom = ath9k_hw_4k_fill_eeprom,
|
||||
.get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
|
||||
.get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
|
||||
.get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
|
||||
.get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
|
||||
.set_board_values = ath9k_hw_4k_set_board_values,
|
||||
.set_addac = ath9k_hw_4k_set_addac,
|
||||
.set_txpower = ath9k_hw_4k_set_txpower,
|
||||
|
|
|
@ -150,7 +150,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
|
|||
eep->modalHeader.antCtrlChain[i] = integer;
|
||||
}
|
||||
|
||||
for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
word = swab16(eep->modalHeader.spurChans[i].spurChan);
|
||||
eep->modalHeader.spurChans[i].spurChan = word;
|
||||
}
|
||||
|
@ -220,163 +220,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
|
|||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
struct cal_data_per_freq_ar9287 *pRawDataSet,
|
||||
u8 *bChans, u16 availPiers,
|
||||
u16 tPdGainOverlap,
|
||||
u16 *pPdGainBoundaries,
|
||||
u8 *pPDADCValues,
|
||||
u16 numXpdGains)
|
||||
{
|
||||
#define TMP_VAL_VPD_TABLE \
|
||||
((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
|
||||
|
||||
int i, j, k;
|
||||
int16_t ss;
|
||||
u16 idxL = 0, idxR = 0, numPiers;
|
||||
u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
|
||||
u8 minPwrT4[AR9287_NUM_PD_GAINS];
|
||||
u8 maxPwrT4[AR9287_NUM_PD_GAINS];
|
||||
int16_t vpdStep;
|
||||
int16_t tmpVal;
|
||||
u16 sizeCurrVpdTable, maxIndex, tgtIndex;
|
||||
bool match;
|
||||
int16_t minDelta = 0;
|
||||
struct chan_centers centers;
|
||||
static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
|
||||
memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
for (numPiers = 0; numPiers < availPiers; numPiers++) {
|
||||
if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
|
||||
break;
|
||||
}
|
||||
|
||||
match = ath9k_hw_get_lower_upper_index(
|
||||
(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
|
||||
bChans, numPiers, &idxL, &idxR);
|
||||
|
||||
if (match) {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pRawDataSet[idxL].pwrPdg[i],
|
||||
pRawDataSet[idxL].vpdPdg[i],
|
||||
AR9287_PD_GAIN_ICEPTS,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
pVpdL = pRawDataSet[idxL].vpdPdg[i];
|
||||
pPwrL = pRawDataSet[idxL].pwrPdg[i];
|
||||
pVpdR = pRawDataSet[idxR].vpdPdg[i];
|
||||
pPwrR = pRawDataSet[idxR].pwrPdg[i];
|
||||
|
||||
minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
|
||||
|
||||
maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
|
||||
pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
|
||||
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrL, pVpdL,
|
||||
AR9287_PD_GAIN_ICEPTS,
|
||||
vpdTableL[i]);
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrR, pVpdR,
|
||||
AR9287_PD_GAIN_ICEPTS,
|
||||
vpdTableR[i]);
|
||||
|
||||
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
|
||||
vpdTableI[i][j] = (u8)(ath9k_hw_interpolate(
|
||||
(u16)FREQ2FBIN(centers. synth_center,
|
||||
IS_CHAN_2GHZ(chan)),
|
||||
bChans[idxL], bChans[idxR],
|
||||
vpdTableL[i][j], vpdTableR[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
if (i == (numXpdGains - 1))
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)(maxPwrT4[i] / 2);
|
||||
else
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
|
||||
|
||||
pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
|
||||
pPdGainBoundaries[i]);
|
||||
|
||||
|
||||
minDelta = 0;
|
||||
|
||||
if (i == 0) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
ss = (int16_t)(0 - (minPwrT4[i] / 2));
|
||||
else
|
||||
ss = 0;
|
||||
} else {
|
||||
ss = (int16_t)((pPdGainBoundaries[i-1] -
|
||||
(minPwrT4[i] / 2)) -
|
||||
tPdGainOverlap + 1 + minDelta);
|
||||
}
|
||||
|
||||
vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
|
||||
pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
|
||||
sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
|
||||
tgtIndex = (u8)(pPdGainBoundaries[i] +
|
||||
tPdGainOverlap - (minPwrT4[i] / 2));
|
||||
maxIndex = (tgtIndex < sizeCurrVpdTable) ?
|
||||
tgtIndex : sizeCurrVpdTable;
|
||||
|
||||
while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
|
||||
pPDADCValues[k++] = vpdTableI[i][ss++];
|
||||
|
||||
vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
|
||||
vpdTableI[i][sizeCurrVpdTable - 2]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
if (tgtIndex > maxIndex) {
|
||||
while ((ss <= tgtIndex) &&
|
||||
(k < (AR9287_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
|
||||
pPDADCValues[k++] =
|
||||
(u8)((tmpVal > 255) ? 255 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (i < AR9287_PD_GAINS_IN_MASK) {
|
||||
pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
|
||||
i++;
|
||||
}
|
||||
|
||||
while (k < AR9287_NUM_PDADC_VALUES) {
|
||||
pPDADCValues[k] = pPDADCValues[k-1];
|
||||
k++;
|
||||
}
|
||||
|
||||
#undef TMP_VAL_VPD_TABLE
|
||||
}
|
||||
|
||||
static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
|
||||
|
@ -389,7 +232,7 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
|
|||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
for (numPiers = 0; numPiers < availPiers; numPiers++) {
|
||||
if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
|
||||
if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -455,11 +298,11 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
|||
struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
|
||||
u8 *pCalBChans = NULL;
|
||||
u16 pdGainOverlap_t2;
|
||||
u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
|
||||
u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
|
||||
u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
|
||||
u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
|
||||
u16 numPiers = 0, i, j;
|
||||
u16 numXpdGain, xpdMask;
|
||||
u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
|
||||
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
|
||||
u32 reg32, regOffset, regChainOffset, regval;
|
||||
int16_t modalIdx, diff = 0;
|
||||
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
|
||||
|
@ -487,12 +330,12 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
|||
numXpdGain = 0;
|
||||
|
||||
/* Calculate the value of xpdgains from the xpdGain Mask */
|
||||
for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
|
||||
if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
|
||||
if (numXpdGain >= AR9287_NUM_PD_GAINS)
|
||||
for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
|
||||
if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
|
||||
if (numXpdGain >= AR5416_NUM_PD_GAINS)
|
||||
break;
|
||||
xpdGainValues[numXpdGain] =
|
||||
(u16)(AR9287_PD_GAINS_IN_MASK-i);
|
||||
(u16)(AR5416_PD_GAINS_IN_MASK-i);
|
||||
numXpdGain++;
|
||||
}
|
||||
}
|
||||
|
@ -525,7 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
|||
(struct cal_data_per_freq_ar9287 *)
|
||||
pEepData->calPierData2G[i];
|
||||
|
||||
ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan,
|
||||
ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
|
||||
pRawDataset,
|
||||
pCalBChans, numPiers,
|
||||
pdGainOverlap_t2,
|
||||
|
@ -561,13 +404,13 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
|||
(int32_t)AR9287_PWR_TABLE_OFFSET_DB);
|
||||
diff *= 2;
|
||||
|
||||
for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++)
|
||||
for (j = 0; j < ((u16)AR5416_NUM_PDADC_VALUES-diff); j++)
|
||||
pdadcValues[j] = pdadcValues[j+diff];
|
||||
|
||||
for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
|
||||
j < AR9287_NUM_PDADC_VALUES; j++)
|
||||
for (j = (u16)(AR5416_NUM_PDADC_VALUES-diff);
|
||||
j < AR5416_NUM_PDADC_VALUES; j++)
|
||||
pdadcValues[j] =
|
||||
pdadcValues[AR9287_NUM_PDADC_VALUES-diff];
|
||||
pdadcValues[AR5416_NUM_PDADC_VALUES-diff];
|
||||
}
|
||||
|
||||
if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
|
||||
|
@ -610,9 +453,9 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
|||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
struct cal_ctl_data_ar9287 *rep;
|
||||
|
@ -877,8 +720,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
|||
regulatory->max_power_level = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
|
||||
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
|
||||
if (ratesArray[i] > AR9287_MAX_RATE_POWER)
|
||||
ratesArray[i] = AR9287_MAX_RATE_POWER;
|
||||
if (ratesArray[i] > MAX_RATE_POWER)
|
||||
ratesArray[i] = MAX_RATE_POWER;
|
||||
|
||||
if (ratesArray[i] > regulatory->max_power_level)
|
||||
regulatory->max_power_level = ratesArray[i];
|
||||
|
@ -1023,8 +866,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
|
|||
antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM,
|
||||
ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
|
||||
|
||||
for (i = 0; i < AR9287_MAX_CHAINS; i++) {
|
||||
regChainOffset = i * 0x1000;
|
||||
|
@ -1125,21 +967,6 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
|
|||
pModal->xpaBiasLvl);
|
||||
}
|
||||
|
||||
static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah,
|
||||
enum ath9k_hal_freq_band freq_band)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
|
||||
struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
|
||||
|
||||
return pModal->antCtrlCommon;
|
||||
}
|
||||
|
||||
static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
|
||||
u16 i, bool is2GHz)
|
||||
{
|
||||
|
@ -1177,8 +1004,6 @@ const struct eeprom_ops eep_ar9287_ops = {
|
|||
.fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
|
||||
.get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
|
||||
.get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
|
||||
.get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config,
|
||||
.get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg,
|
||||
.set_board_values = ath9k_hw_ar9287_set_board_values,
|
||||
.set_addac = ath9k_hw_ar9287_set_addac,
|
||||
.set_txpower = ath9k_hw_ar9287_set_txpower,
|
||||
|
|
|
@ -206,7 +206,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
|||
pModal->antCtrlChain[i] = integer;
|
||||
}
|
||||
|
||||
for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
word = swab16(pModal->spurChans[i].spurChan);
|
||||
pModal->spurChans[i].spurChan = word;
|
||||
}
|
||||
|
@ -374,8 +374,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
|
|||
pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
|
||||
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
|
||||
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM,
|
||||
ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
|
||||
REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
|
||||
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
if (AR_SREV_9280(ah)) {
|
||||
|
@ -588,168 +587,6 @@ static void ath9k_hw_def_set_addac(struct ath_hw *ah,
|
|||
#undef XPA_LVL_FREQ
|
||||
}
|
||||
|
||||
static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
struct cal_data_per_freq *pRawDataSet,
|
||||
u8 *bChans, u16 availPiers,
|
||||
u16 tPdGainOverlap,
|
||||
u16 *pPdGainBoundaries, u8 *pPDADCValues,
|
||||
u16 numXpdGains)
|
||||
{
|
||||
int i, j, k;
|
||||
int16_t ss;
|
||||
u16 idxL = 0, idxR = 0, numPiers;
|
||||
static u8 vpdTableL[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableR[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
static u8 vpdTableI[AR5416_NUM_PD_GAINS]
|
||||
[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
|
||||
|
||||
u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
|
||||
u8 minPwrT4[AR5416_NUM_PD_GAINS];
|
||||
u8 maxPwrT4[AR5416_NUM_PD_GAINS];
|
||||
int16_t vpdStep;
|
||||
int16_t tmpVal;
|
||||
u16 sizeCurrVpdTable, maxIndex, tgtIndex;
|
||||
bool match;
|
||||
int16_t minDelta = 0;
|
||||
struct chan_centers centers;
|
||||
|
||||
memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
for (numPiers = 0; numPiers < availPiers; numPiers++) {
|
||||
if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
|
||||
break;
|
||||
}
|
||||
|
||||
match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
|
||||
IS_CHAN_2GHZ(chan)),
|
||||
bChans, numPiers, &idxL, &idxR);
|
||||
|
||||
if (match) {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
|
||||
maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pRawDataSet[idxL].pwrPdg[i],
|
||||
pRawDataSet[idxL].vpdPdg[i],
|
||||
AR5416_PD_GAIN_ICEPTS,
|
||||
vpdTableI[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
pVpdL = pRawDataSet[idxL].vpdPdg[i];
|
||||
pPwrL = pRawDataSet[idxL].pwrPdg[i];
|
||||
pVpdR = pRawDataSet[idxR].vpdPdg[i];
|
||||
pPwrR = pRawDataSet[idxR].pwrPdg[i];
|
||||
|
||||
minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
|
||||
|
||||
maxPwrT4[i] =
|
||||
min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
|
||||
pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
|
||||
|
||||
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrL, pVpdL,
|
||||
AR5416_PD_GAIN_ICEPTS,
|
||||
vpdTableL[i]);
|
||||
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
|
||||
pPwrR, pVpdR,
|
||||
AR5416_PD_GAIN_ICEPTS,
|
||||
vpdTableR[i]);
|
||||
|
||||
for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
|
||||
vpdTableI[i][j] =
|
||||
(u8)(ath9k_hw_interpolate((u16)
|
||||
FREQ2FBIN(centers.
|
||||
synth_center,
|
||||
IS_CHAN_2GHZ
|
||||
(chan)),
|
||||
bChans[idxL], bChans[idxR],
|
||||
vpdTableL[i][j], vpdTableR[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < numXpdGains; i++) {
|
||||
if (i == (numXpdGains - 1))
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)(maxPwrT4[i] / 2);
|
||||
else
|
||||
pPdGainBoundaries[i] =
|
||||
(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
|
||||
|
||||
pPdGainBoundaries[i] =
|
||||
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
|
||||
|
||||
if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
|
||||
minDelta = pPdGainBoundaries[0] - 23;
|
||||
pPdGainBoundaries[0] = 23;
|
||||
} else {
|
||||
minDelta = 0;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
ss = (int16_t)(0 - (minPwrT4[i] / 2));
|
||||
else
|
||||
ss = 0;
|
||||
} else {
|
||||
ss = (int16_t)((pPdGainBoundaries[i - 1] -
|
||||
(minPwrT4[i] / 2)) -
|
||||
tPdGainOverlap + 1 + minDelta);
|
||||
}
|
||||
vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
|
||||
pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
|
||||
sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
|
||||
tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
|
||||
(minPwrT4[i] / 2));
|
||||
maxIndex = (tgtIndex < sizeCurrVpdTable) ?
|
||||
tgtIndex : sizeCurrVpdTable;
|
||||
|
||||
while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
pPDADCValues[k++] = vpdTableI[i][ss++];
|
||||
}
|
||||
|
||||
vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
|
||||
vpdTableI[i][sizeCurrVpdTable - 2]);
|
||||
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
|
||||
|
||||
if (tgtIndex >= maxIndex) {
|
||||
while ((ss <= tgtIndex) &&
|
||||
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
|
||||
tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
|
||||
(ss - maxIndex + 1) * vpdStep));
|
||||
pPDADCValues[k++] = (u8)((tmpVal > 255) ?
|
||||
255 : tmpVal);
|
||||
ss++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (i < AR5416_PD_GAINS_IN_MASK) {
|
||||
pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
|
||||
i++;
|
||||
}
|
||||
|
||||
while (k < AR5416_NUM_PDADC_VALUES) {
|
||||
pPDADCValues[k] = pPDADCValues[k - 1];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
|
||||
u16 *gb,
|
||||
u16 numXpdGain,
|
||||
|
@ -782,7 +619,7 @@ static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
|
|||
/* Because of a hardware limitation, ensure the gain boundary
|
||||
* is not larger than (63 - overlap)
|
||||
*/
|
||||
gb_limit = (u16)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2);
|
||||
gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
|
||||
|
||||
for (k = 0; k < numXpdGain; k++)
|
||||
gb[k] = (u16)min(gb_limit, gb[k]);
|
||||
|
@ -916,7 +753,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
|
|||
ath9k_olc_get_pdadcs(ah, pcdacIdx,
|
||||
txPower/2, pdadcValues);
|
||||
} else {
|
||||
ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
|
||||
ath9k_hw_get_gain_boundaries_pdadcs(ah,
|
||||
chan, pRawDataset,
|
||||
pCalBChans, numPiers,
|
||||
pdGainOverlap_t2,
|
||||
|
@ -1001,9 +838,9 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
|
||||
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
|
@ -1148,7 +985,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||
|
||||
if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
|
||||
ah->eep_ops->get_eeprom_rev(ah) <= 2)
|
||||
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
|
||||
twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
|
||||
for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
|
||||
if ((((cfgCtl & ~CTL_MODE_M) |
|
||||
|
@ -1293,8 +1130,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
|||
regulatory->max_power_level = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
|
||||
ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
|
||||
if (ratesArray[i] > AR5416_MAX_RATE_POWER)
|
||||
ratesArray[i] = AR5416_MAX_RATE_POWER;
|
||||
if (ratesArray[i] > MAX_RATE_POWER)
|
||||
ratesArray[i] = MAX_RATE_POWER;
|
||||
if (ratesArray[i] > regulatory->max_power_level)
|
||||
regulatory->max_power_level = ratesArray[i];
|
||||
}
|
||||
|
@ -1426,34 +1263,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
|||
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
|
||||
}
|
||||
|
||||
static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
|
||||
enum ath9k_hal_freq_band freq_band)
|
||||
{
|
||||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct modal_eep_header *pModal =
|
||||
&(eep->modalHeader[freq_band]);
|
||||
struct base_eep_header *pBase = &eep->baseEepHeader;
|
||||
u8 num_ant_config;
|
||||
|
||||
num_ant_config = 1;
|
||||
|
||||
if (pBase->version >= 0x0E0D &&
|
||||
(pModal->lna_ctl & LNA_CTL_USE_ANT1))
|
||||
num_ant_config += 1;
|
||||
|
||||
return num_ant_config;
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct modal_eep_header *pModal =
|
||||
&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
|
||||
|
||||
return pModal->antCtrlCommon;
|
||||
}
|
||||
|
||||
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
||||
{
|
||||
#define EEP_DEF_SPURCHAN \
|
||||
|
@ -1490,8 +1299,6 @@ const struct eeprom_ops eep_def_ops = {
|
|||
.fill_eeprom = ath9k_hw_def_fill_eeprom,
|
||||
.get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
|
||||
.get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
|
||||
.get_num_ant_config = ath9k_hw_def_get_num_ant_config,
|
||||
.get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
|
||||
.set_board_values = ath9k_hw_def_set_board_values,
|
||||
.set_addac = ath9k_hw_def_set_addac,
|
||||
.set_txpower = ath9k_hw_def_set_txpower,
|
||||
|
|
|
@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
|
|||
{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
|
||||
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
|
||||
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
|
||||
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
|
||||
|
||||
{ USB_DEVICE(0x0cf3, 0x7015),
|
||||
.driver_info = AR9287_USB }, /* Atheros */
|
||||
|
|
|
@ -1170,9 +1170,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
|
|||
/* setup initial channel */
|
||||
init_channel = ath9k_cmn_get_curchannel(hw, ah);
|
||||
|
||||
/* Reset SERDES registers */
|
||||
ath9k_hw_configpcipowersave(ah, 0, 0);
|
||||
|
||||
ath9k_hw_htc_resetinit(ah);
|
||||
ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
|
||||
if (ret) {
|
||||
|
@ -1258,7 +1255,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
|||
|
||||
ath9k_hw_phy_disable(ah);
|
||||
ath9k_hw_disable(ah);
|
||||
ath9k_hw_configpcipowersave(ah, 1, 1);
|
||||
ath9k_htc_ps_restore(priv);
|
||||
ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data)
|
|||
ista = (struct ath9k_htc_sta *)sta->drv_priv;
|
||||
|
||||
if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
|
||||
ieee80211_start_tx_ba_session(sta, tid);
|
||||
ieee80211_start_tx_ba_session(sta, tid, 0);
|
||||
spin_lock_bh(&priv->tx_lock);
|
||||
ista->tid_state[tid] = AGGR_PROGRESS;
|
||||
spin_unlock_bh(&priv->tx_lock);
|
||||
|
|
|
@ -223,11 +223,6 @@ static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
|
|||
return ath9k_hw_private_ops(ah)->rfbus_done(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_enable_rfkill(struct ath_hw *ah)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->restore_chainmask)
|
||||
|
|
|
@ -54,13 +54,6 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
|
|||
ath9k_hw_private_ops(ah)->init_mode_regs(ah);
|
||||
}
|
||||
|
||||
static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
|
||||
return priv_ops->macversion_supported(ah->hw_version.macVersion);
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
|
@ -284,11 +277,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
|
|||
|
||||
static void ath9k_hw_disablepcie(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9100(ah))
|
||||
if (!AR_SREV_5416(ah))
|
||||
return;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
|
||||
|
@ -300,8 +291,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
|
|||
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
}
|
||||
|
||||
/* This should work for all families including legacy */
|
||||
|
@ -418,9 +407,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
|
|||
ah->sta_id1_defaults =
|
||||
AR_STA_ID1_CRPT_MIC_ENABLE |
|
||||
AR_STA_ID1_MCAST_KSRCH;
|
||||
ah->beacon_interval = 100;
|
||||
ah->enable_32kHz_clock = DONT_USE_32KHZ;
|
||||
ah->slottime = (u32) -1;
|
||||
ah->slottime = 20;
|
||||
ah->globaltxtimeout = (u32) -1;
|
||||
ah->power_mode = ATH9K_PM_UNDEFINED;
|
||||
}
|
||||
|
@ -538,7 +526,19 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|||
else
|
||||
ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
|
||||
|
||||
if (!ath9k_hw_macversion_supported(ah)) {
|
||||
switch (ah->hw_version.macVersion) {
|
||||
case AR_SREV_VERSION_5416_PCI:
|
||||
case AR_SREV_VERSION_5416_PCIE:
|
||||
case AR_SREV_VERSION_9160:
|
||||
case AR_SREV_VERSION_9100:
|
||||
case AR_SREV_VERSION_9280:
|
||||
case AR_SREV_VERSION_9285:
|
||||
case AR_SREV_VERSION_9287:
|
||||
case AR_SREV_VERSION_9271:
|
||||
case AR_SREV_VERSION_9300:
|
||||
case AR_SREV_VERSION_9485:
|
||||
break;
|
||||
default:
|
||||
ath_err(common,
|
||||
"Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
|
||||
ah->hw_version.macVersion, ah->hw_version.macRev);
|
||||
|
@ -808,7 +808,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
|||
if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
|
||||
acktimeout += 64 - sifstime - ah->slottime;
|
||||
|
||||
ath9k_hw_setslottime(ah, slottime);
|
||||
ath9k_hw_setslottime(ah, ah->slottime);
|
||||
ath9k_hw_set_ack_timeout(ah, acktimeout);
|
||||
ath9k_hw_set_cts_timeout(ah, acktimeout);
|
||||
if (ah->globaltxtimeout != (u32) -1)
|
||||
|
@ -1272,6 +1272,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|||
|
||||
ath9k_hw_mark_phy_inactive(ah);
|
||||
|
||||
ah->paprd_table_write_done = false;
|
||||
|
||||
/* Only required on the first reset */
|
||||
if (AR_SREV_9271(ah) && ah->htc_reset_init) {
|
||||
REG_WRITE(ah,
|
||||
|
@ -1383,7 +1385,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|||
ath9k_hw_init_qos(ah);
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
|
||||
ath9k_enable_rfkill(ah);
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
|
||||
|
||||
ath9k_hw_init_global_settings(ah);
|
||||
|
||||
|
@ -1627,17 +1629,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
|
|||
{
|
||||
int flags = 0;
|
||||
|
||||
ah->beacon_interval = beacon_period;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
switch (ah->opmode) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
|
||||
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
|
||||
REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
|
||||
flags |= AR_TBTT_TIMER_EN;
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
REG_SET_BIT(ah, AR_TXCFG,
|
||||
|
@ -1661,14 +1655,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
|
|||
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
|
||||
break;
|
||||
default:
|
||||
if (ah->is_monitoring) {
|
||||
REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
|
||||
TU_TO_USEC(next_beacon));
|
||||
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
|
||||
REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
|
||||
flags |= AR_TBTT_TIMER_EN;
|
||||
break;
|
||||
}
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON,
|
||||
"%s: unsupported opmode: %d\n",
|
||||
__func__, ah->opmode);
|
||||
|
@ -1920,11 +1906,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
|||
AR_SREV_5416(ah))
|
||||
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
|
||||
|
||||
pCap->num_antcfg_5ghz =
|
||||
ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
|
||||
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) && common->btcoex_enabled) {
|
||||
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
|
||||
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
|
||||
|
|
|
@ -204,8 +204,6 @@ struct ath9k_hw_capabilities {
|
|||
u16 tx_triglevel_max;
|
||||
u16 reg_cap;
|
||||
u8 num_gpio_pins;
|
||||
u8 num_antcfg_2ghz;
|
||||
u8 num_antcfg_5ghz;
|
||||
u8 rx_hp_qdepth;
|
||||
u8 rx_lp_qdepth;
|
||||
u8 rx_status_len;
|
||||
|
@ -238,7 +236,6 @@ struct ath9k_ops_config {
|
|||
#define SPUR_DISABLE 0
|
||||
#define SPUR_ENABLE_IOCTL 1
|
||||
#define SPUR_ENABLE_EEPROM 2
|
||||
#define AR_EEPROM_MODAL_SPURS 5
|
||||
#define AR_SPUR_5413_1 1640
|
||||
#define AR_SPUR_5413_2 1200
|
||||
#define AR_NO_SPUR 0x8000
|
||||
|
@ -535,7 +532,6 @@ struct ath_hw_radar_conf {
|
|||
*
|
||||
* @init_mode_regs: Initializes mode registers
|
||||
* @init_mode_gain_regs: Initialize TX/RX gain registers
|
||||
* @macversion_supported: If this specific mac revision is supported
|
||||
*
|
||||
* @rf_set_freq: change frequency
|
||||
* @spur_mitigate_freq: spur mitigation
|
||||
|
@ -557,7 +553,6 @@ struct ath_hw_private_ops {
|
|||
|
||||
void (*init_mode_regs)(struct ath_hw *ah);
|
||||
void (*init_mode_gain_regs)(struct ath_hw *ah);
|
||||
bool (*macversion_supported)(u32 macversion);
|
||||
void (*setup_calibration)(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal);
|
||||
|
||||
|
@ -581,7 +576,6 @@ struct ath_hw_private_ops {
|
|||
void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
bool (*rfbus_req)(struct ath_hw *ah);
|
||||
void (*rfbus_done)(struct ath_hw *ah);
|
||||
void (*enable_rfkill)(struct ath_hw *ah);
|
||||
void (*restore_chainmask)(struct ath_hw *ah);
|
||||
void (*set_diversity)(struct ath_hw *ah, bool value);
|
||||
u32 (*compute_pll_control)(struct ath_hw *ah,
|
||||
|
@ -767,9 +761,7 @@ struct ath_hw {
|
|||
u32 *bank6Temp;
|
||||
|
||||
u8 txpower_limit;
|
||||
int16_t txpower_indexoffset;
|
||||
int coverage_class;
|
||||
u32 beacon_interval;
|
||||
u32 slottime;
|
||||
u32 globaltxtimeout;
|
||||
|
||||
|
@ -840,6 +832,11 @@ struct ath_hw {
|
|||
u32 bb_watchdog_last_status;
|
||||
u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
|
||||
|
||||
unsigned int paprd_target_power;
|
||||
unsigned int paprd_training_power;
|
||||
unsigned int paprd_ratemask;
|
||||
unsigned int paprd_ratemask_ht40;
|
||||
bool paprd_table_write_done;
|
||||
u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
|
||||
u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
|
||||
/*
|
||||
|
@ -873,6 +870,11 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
|
|||
return &ah->ops;
|
||||
}
|
||||
|
||||
static inline u8 get_streams(int mask)
|
||||
{
|
||||
return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
|
||||
}
|
||||
|
||||
/* Initialization, Detach, Reset */
|
||||
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
|
||||
void ath9k_hw_deinit(struct ath_hw *ah);
|
||||
|
|
|
@ -41,9 +41,14 @@ static int ath9k_btcoex_enable;
|
|||
module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
|
||||
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
|
||||
|
||||
int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
|
||||
module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
|
||||
|
||||
/* We use the hw_value as an index into our private channel structure */
|
||||
|
||||
#define CHAN2G(_freq, _idx) { \
|
||||
.band = IEEE80211_BAND_2GHZ, \
|
||||
.center_freq = (_freq), \
|
||||
.hw_value = (_idx), \
|
||||
.max_power = 20, \
|
||||
|
|
|
@ -320,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc)
|
|||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ath_tx_control txctl;
|
||||
int time_left;
|
||||
|
||||
memset(&txctl, 0, sizeof(txctl));
|
||||
txctl.txq = sc->tx.txq_map[WME_AC_BE];
|
||||
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->band = hw->conf.channel->band;
|
||||
tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
||||
tx_info->control.rates[0].idx = 0;
|
||||
tx_info->control.rates[0].count = 1;
|
||||
tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
|
||||
tx_info->control.rates[1].idx = -1;
|
||||
|
||||
init_completion(&sc->paprd_complete);
|
||||
sc->paprd_pending = true;
|
||||
txctl.paprd = BIT(chain);
|
||||
if (ath_tx_start(hw, skb, &txctl) != 0)
|
||||
return false;
|
||||
|
||||
time_left = wait_for_completion_timeout(&sc->paprd_complete,
|
||||
msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
|
||||
sc->paprd_pending = false;
|
||||
|
||||
if (!time_left)
|
||||
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
|
||||
"Timeout waiting for paprd training on TX chain %d\n",
|
||||
chain);
|
||||
|
||||
return !!time_left;
|
||||
}
|
||||
|
||||
void ath_paprd_calibrate(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
|
||||
|
@ -327,28 +363,23 @@ void ath_paprd_calibrate(struct work_struct *work)
|
|||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
int band = hw->conf.channel->band;
|
||||
struct ieee80211_supported_band *sband = &sc->sbands[band];
|
||||
struct ath_tx_control txctl;
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ftype;
|
||||
int chain_ok = 0;
|
||||
int chain;
|
||||
int len = 1800;
|
||||
int time_left;
|
||||
int i;
|
||||
|
||||
if (!caldata)
|
||||
return;
|
||||
|
||||
if (ar9003_paprd_init_table(ah) < 0)
|
||||
return;
|
||||
|
||||
skb = alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
skb_put(skb, len);
|
||||
memset(skb->data, 0, len);
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
@ -359,40 +390,25 @@ void ath_paprd_calibrate(struct work_struct *work)
|
|||
memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
|
||||
memset(&txctl, 0, sizeof(txctl));
|
||||
txctl.txq = sc->tx.txq_map[WME_AC_BE];
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ar9003_paprd_init_table(ah);
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if (!(common->tx_chainmask & BIT(chain)))
|
||||
continue;
|
||||
|
||||
chain_ok = 0;
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->band = band;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
tx_info->control.rates[i].idx = sband->n_bitrates - 1;
|
||||
tx_info->control.rates[i].count = 6;
|
||||
}
|
||||
|
||||
init_completion(&sc->paprd_complete);
|
||||
sc->paprd_pending = true;
|
||||
ar9003_paprd_setup_gain_table(ah, chain);
|
||||
txctl.paprd = BIT(chain);
|
||||
if (ath_tx_start(hw, skb, &txctl) != 0)
|
||||
break;
|
||||
|
||||
time_left = wait_for_completion_timeout(&sc->paprd_complete,
|
||||
msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
|
||||
sc->paprd_pending = false;
|
||||
if (!time_left) {
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
|
||||
"Timeout waiting for paprd training on TX chain %d\n",
|
||||
chain);
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Sending PAPRD frame for thermal measurement "
|
||||
"on chain %d\n", chain);
|
||||
if (!ath_paprd_send_frame(sc, skb, chain))
|
||||
goto fail_paprd;
|
||||
|
||||
ar9003_paprd_setup_gain_table(ah, chain);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Sending PAPRD training frame on chain %d\n", chain);
|
||||
if (!ath_paprd_send_frame(sc, skb, chain))
|
||||
goto fail_paprd;
|
||||
}
|
||||
|
||||
if (!ar9003_paprd_is_done(ah))
|
||||
break;
|
||||
|
@ -517,37 +533,11 @@ set_timer:
|
|||
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
|
||||
if (!ah->caldata->paprd_done)
|
||||
ieee80211_queue_work(sc->hw, &sc->paprd_work);
|
||||
else
|
||||
else if (!ah->paprd_table_write_done)
|
||||
ath_paprd_activate(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update tx/rx chainmask. For legacy association,
|
||||
* hard code chainmask to 1x1, for 11n association, use
|
||||
* the chainmask configuration, for bt coexistence, use
|
||||
* the chainmask configuration even in legacy mode.
|
||||
*/
|
||||
void ath_update_chainmask(struct ath_softc *sc, int is_ht)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
|
||||
(ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
|
||||
common->tx_chainmask = ah->caps.tx_chainmask;
|
||||
common->rx_chainmask = ah->caps.rx_chainmask;
|
||||
} else {
|
||||
common->tx_chainmask = 1;
|
||||
common->rx_chainmask = 1;
|
||||
}
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"tx chmask: %d, rx chmask: %d\n",
|
||||
common->tx_chainmask,
|
||||
common->rx_chainmask);
|
||||
}
|
||||
|
||||
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
|
||||
{
|
||||
struct ath_node *an;
|
||||
|
@ -900,8 +890,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
ath_update_txpow(sc);
|
||||
if (ath_startrecv(sc) != 0) {
|
||||
ath_err(common, "Unable to restart recv logic\n");
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (sc->sc_flags & SC_OP_BEACONS)
|
||||
ath_beacon_config(sc, NULL); /* restart beacons */
|
||||
|
@ -915,6 +904,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||
ath9k_hw_set_gpio(ah, ah->led_pin, 0);
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
@ -1180,7 +1170,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
|||
ath9k_btcoex_timer_resume(sc);
|
||||
}
|
||||
|
||||
pm_qos_update_request(&sc->pm_qos_req, 55);
|
||||
/* User has the option to provide pm-qos value as a module
|
||||
* parameter rather than using the default value of
|
||||
* 'ATH9K_PM_QOS_DEFAULT_VALUE'.
|
||||
*/
|
||||
pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
|
||||
|
||||
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
|
||||
common->bus_ops->extn_synch_en(common);
|
||||
|
@ -1333,8 +1327,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
|||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
/* Finally, put the chip in FULL SLEEP mode */
|
||||
ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
|
||||
sc->ps_idle = true;
|
||||
ath_radio_disable(sc, hw);
|
||||
|
||||
sc->sc_flags |= SC_OP_INVALID;
|
||||
|
||||
|
@ -1428,13 +1422,78 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ath9k_reclaim_beacon(struct ath_softc *sc,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
|
||||
/* Disable SWBA interrupt */
|
||||
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||
tasklet_kill(&sc->bcon_tasklet);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
ath_beacon_return(sc, avp);
|
||||
sc->sc_flags &= ~SC_OP_BEACONS;
|
||||
|
||||
if (sc->nbcnvifs > 0) {
|
||||
/* Re-enable beaconing */
|
||||
sc->sc_ah->imask |= ATH9K_INT_SWBA;
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
}
|
||||
|
||||
static int ath9k_change_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum nl80211_iftype new_type,
|
||||
bool p2p)
|
||||
{
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
switch (new_type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
if (sc->nbcnvifs >= ATH_BCBUF) {
|
||||
ath_err(common, "No beacon slot available\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
/* Stop ANI */
|
||||
sc->sc_flags &= ~SC_OP_ANI_RUN;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
if ((vif->type == NL80211_IFTYPE_AP) ||
|
||||
(vif->type == NL80211_IFTYPE_ADHOC))
|
||||
ath9k_reclaim_beacon(sc, vif);
|
||||
break;
|
||||
default:
|
||||
ath_err(common, "Interface type %d not yet supported\n",
|
||||
vif->type);
|
||||
mutex_unlock(&sc->mutex);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
vif->type = new_type;
|
||||
vif->p2p = p2p;
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
struct ath_softc *sc = aphy->sc;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
|
||||
|
||||
|
@ -1447,26 +1506,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
|||
/* Reclaim beacon resources */
|
||||
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
|
||||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
|
||||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
|
||||
/* Disable SWBA interrupt */
|
||||
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||
ath9k_ps_restore(sc);
|
||||
tasklet_kill(&sc->bcon_tasklet);
|
||||
}
|
||||
|
||||
ath_beacon_return(sc, avp);
|
||||
sc->sc_flags &= ~SC_OP_BEACONS;
|
||||
|
||||
if (sc->nbcnvifs) {
|
||||
/* Re-enable SWBA interrupt */
|
||||
sc->sc_ah->imask |= ATH9K_INT_SWBA;
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))
|
||||
ath9k_reclaim_beacon(sc, vif);
|
||||
|
||||
sc->nvifs--;
|
||||
|
||||
|
@ -1612,8 +1653,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
|||
/* XXX: remove me eventualy */
|
||||
ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
|
||||
|
||||
ath_update_chainmask(sc, conf_is_ht(conf));
|
||||
|
||||
/* update survey stats for the old channel before switching */
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
ath_update_survey_stats(sc);
|
||||
|
@ -1845,10 +1884,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
|||
/* Set aggregation protection mode parameters */
|
||||
sc->config.ath_aggr_prot = 0;
|
||||
|
||||
/* Only legacy IBSS for now */
|
||||
if (vif->type == NL80211_IFTYPE_ADHOC)
|
||||
ath_update_chainmask(sc, 0);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
|
||||
common->curbssid, common->curaid);
|
||||
|
||||
|
@ -1940,7 +1975,9 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
|
|||
struct ath_softc *sc = aphy->sc;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
ath9k_ps_wakeup(sc);
|
||||
tsf = ath9k_hw_gettsf64(sc->sc_ah);
|
||||
ath9k_ps_restore(sc);
|
||||
mutex_unlock(&sc->mutex);
|
||||
|
||||
return tsf;
|
||||
|
@ -1952,7 +1989,9 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
|
|||
struct ath_softc *sc = aphy->sc;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_settsf64(sc->sc_ah, tsf);
|
||||
ath9k_ps_restore(sc);
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
|
@ -2111,6 +2150,7 @@ struct ieee80211_ops ath9k_ops = {
|
|||
.start = ath9k_start,
|
||||
.stop = ath9k_stop,
|
||||
.add_interface = ath9k_add_interface,
|
||||
.change_interface = ath9k_change_interface,
|
||||
.remove_interface = ath9k_remove_interface,
|
||||
.config = ath9k_config,
|
||||
.configure_filter = ath9k_configure_filter,
|
||||
|
|
|
@ -309,6 +309,9 @@ static int ath_pci_resume(struct device *device)
|
|||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
|
||||
|
||||
sc->ps_idle = true;
|
||||
ath_radio_disable(sc, hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1373,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
|||
an = (struct ath_node *)sta->drv_priv;
|
||||
|
||||
if(ath_tx_aggr_check(sc, an, tid))
|
||||
ieee80211_start_tx_ba_session(sta, tid);
|
||||
ieee80211_start_tx_ba_session(sta, tid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,6 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
|
|||
/* sync hw configuration for hw code */
|
||||
common->hw = aphy->hw;
|
||||
|
||||
ath_update_chainmask(sc, sc->chan_is_ht);
|
||||
if (ath_set_channel(sc, aphy->hw,
|
||||
&sc->sc_ah->channels[sc->chan_idx]) < 0) {
|
||||
printk(KERN_DEBUG "ath9k: Failed to set channel for new "
|
||||
|
|
|
@ -838,7 +838,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
|||
ath_tx_txqaddbuf(sc, txq, &bf_q);
|
||||
TX_STAT_INC(txq->axq_qnum, a_aggr);
|
||||
|
||||
} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
|
||||
} while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
|
||||
status != ATH_AGGR_BAW_CLOSED);
|
||||
}
|
||||
|
||||
|
@ -999,6 +999,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
|||
INIT_LIST_HEAD(&txq->axq_acq);
|
||||
spin_lock_init(&txq->axq_lock);
|
||||
txq->axq_depth = 0;
|
||||
txq->axq_ampdu_depth = 0;
|
||||
txq->axq_tx_inprogress = false;
|
||||
sc->tx.txqsetup |= 1<<qnum;
|
||||
|
||||
|
@ -1068,6 +1069,12 @@ int ath_cabq_update(struct ath_softc *sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||
return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drain a given TX queue (could be Beacon or Data)
|
||||
*
|
||||
|
@ -1126,7 +1133,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
|||
}
|
||||
|
||||
txq->axq_depth--;
|
||||
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_isampdu(bf))
|
||||
|
@ -1316,6 +1324,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
|||
ath9k_hw_txstart(ah, txq->axq_qnum);
|
||||
}
|
||||
txq->axq_depth++;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth++;
|
||||
}
|
||||
|
||||
static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
|
@ -1336,7 +1346,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
|||
*/
|
||||
if (!list_empty(&tid->buf_q) || tid->paused ||
|
||||
!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
|
||||
txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
|
||||
txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
|
||||
/*
|
||||
* Add this frame to software queue for scheduling later
|
||||
* for aggregation.
|
||||
|
@ -1685,17 +1695,20 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
|
|||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct list_head bf_head;
|
||||
struct ath_atx_tid *tid;
|
||||
struct ath_atx_tid *tid = NULL;
|
||||
u8 tidno;
|
||||
|
||||
spin_lock_bh(&txctl->txq->axq_lock);
|
||||
|
||||
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) {
|
||||
if (ieee80211_is_data_qos(hdr->frame_control) && txctl->an) {
|
||||
tidno = ieee80211_get_qos_ctl(hdr)[0] &
|
||||
IEEE80211_QOS_CTL_TID_MASK;
|
||||
tid = ATH_AN_2_TID(txctl->an, tidno);
|
||||
|
||||
WARN_ON(tid->ac->txq != txctl->txq);
|
||||
}
|
||||
|
||||
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
|
||||
/*
|
||||
* Try aggregation if it's a unicast data frame
|
||||
* and the destination is HT capable.
|
||||
|
@ -1712,7 +1725,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
|
|||
ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
|
||||
bf->bf_state.bfs_paprd);
|
||||
|
||||
ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head);
|
||||
ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&txctl->txq->axq_lock);
|
||||
|
@ -2037,6 +2050,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
|||
txq->axq_tx_inprogress = false;
|
||||
if (bf_held)
|
||||
list_del(&bf_held->list);
|
||||
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (bf_held)
|
||||
|
@ -2165,6 +2181,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
|
|||
INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
|
||||
txq->axq_depth--;
|
||||
txq->axq_tx_inprogress = false;
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
txok = !(txs.ts_status & ATH9K_TXERR_MASK);
|
||||
|
|
|
@ -58,6 +58,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
|
|||
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
|
||||
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
|
||||
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
|
||||
if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)
|
||||
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -342,6 +342,14 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
|
|||
/* We always apply this */
|
||||
ath_reg_apply_radar_flags(wiphy);
|
||||
|
||||
/*
|
||||
* This would happen when we have sent a custom regulatory request
|
||||
* a world regulatory domain and the scheduler hasn't yet processed
|
||||
* any pending requests in the queue.
|
||||
*/
|
||||
if (!request)
|
||||
return 0;
|
||||
|
||||
switch (request->initiator) {
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
case NL80211_REGDOM_SET_BY_CORE:
|
||||
|
|
|
@ -416,10 +416,10 @@ enum {
|
|||
|
||||
/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
|
||||
#define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
|
||||
#define B43_TMSLOW_PHYCLKSPEED 0x00C00000 /* PHY clock speed mask (N-PHY only) */
|
||||
#define B43_TMSLOW_PHYCLKSPEED_40MHZ 0x00000000 /* 40 MHz PHY */
|
||||
#define B43_TMSLOW_PHYCLKSPEED_80MHZ 0x00400000 /* 80 MHz PHY */
|
||||
#define B43_TMSLOW_PHYCLKSPEED_160MHZ 0x00800000 /* 160 MHz PHY */
|
||||
#define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */
|
||||
#define B43_TMSLOW_PHY_BANDWIDTH_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */
|
||||
#define B43_TMSLOW_PHY_BANDWIDTH_20MHZ 0x00400000 /* 20 MHz bandwidth, 80 MHz PHY */
|
||||
#define B43_TMSLOW_PHY_BANDWIDTH_40MHZ 0x00800000 /* 40 MHz bandwidth, 160 MHz PHY */
|
||||
#define B43_TMSLOW_PLLREFSEL 0x00200000 /* PLL Frequency Reference Select (rev >= 5) */
|
||||
#define B43_TMSLOW_MACPHYCLKEN 0x00100000 /* MAC PHY Clock Control Enable (rev >= 5) */
|
||||
#define B43_TMSLOW_PHYRESET 0x00080000 /* PHY Reset */
|
||||
|
|
|
@ -1150,12 +1150,8 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
|
|||
|
||||
flags |= B43_TMSLOW_PHYCLKEN;
|
||||
flags |= B43_TMSLOW_PHYRESET;
|
||||
if (dev->phy.type == B43_PHYTYPE_N) {
|
||||
if (b43_channel_type_is_40mhz(dev->phy.channel_type))
|
||||
flags |= B43_TMSLOW_PHYCLKSPEED_160MHZ;
|
||||
else
|
||||
flags |= B43_TMSLOW_PHYCLKSPEED_80MHZ;
|
||||
}
|
||||
if (dev->phy.type == B43_PHYTYPE_N)
|
||||
flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
|
||||
ssb_device_enable(dev->dev, flags);
|
||||
msleep(2); /* Wait for the PLL to turn on. */
|
||||
|
||||
|
|
|
@ -1209,29 +1209,18 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
|
|||
b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
|
||||
}
|
||||
|
||||
/* TODO: convert to b43_ntab_write? */
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
|
||||
|
||||
if (dev->phy.rev < 2) {
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
|
||||
|
@ -3278,9 +3267,9 @@ static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
|
|||
{
|
||||
u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
|
||||
if (on)
|
||||
tmslow |= SSB_TMSLOW_PHYCLK;
|
||||
tmslow |= B43_TMSLOW_MACPHYCLKEN;
|
||||
else
|
||||
tmslow &= ~SSB_TMSLOW_PHYCLK;
|
||||
tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
|
||||
ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
|
||||
}
|
||||
|
||||
|
|
|
@ -1835,12 +1835,12 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
|
|||
/* Volatile tables */
|
||||
ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
|
||||
ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
|
||||
ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
|
||||
ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
|
||||
ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
|
||||
ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
|
||||
ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
|
||||
ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
|
||||
ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
|
||||
ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
|
||||
ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
|
||||
ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
|
||||
ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
|
||||
|
|
|
@ -147,7 +147,11 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
|
||||
|
||||
priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
|
||||
priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
|
||||
if (priv->cfg->rx_with_siso_diversity)
|
||||
priv->hw_params.rx_chains_num = 1;
|
||||
else
|
||||
priv->hw_params.rx_chains_num =
|
||||
num_of_ant(priv->cfg->valid_rx_ant);
|
||||
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
|
||||
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
|
||||
|
||||
|
@ -272,60 +276,49 @@ static struct iwl_ht_params iwl1000_ht_params = {
|
|||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_1000 \
|
||||
.fw_name_pre = IWL1000_FW_PRE, \
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.ops = &iwl1000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
IWL_DEVICE_1000,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
|
||||
.fw_name_pre = IWL1000_FW_PRE,
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
IWL_DEVICE_1000,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_100 \
|
||||
.fw_name_pre = IWL100_FW_PRE, \
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.ops = &iwl1000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
|
||||
struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
IWL_DEVICE_100,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl100_bg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
|
||||
.ops = &iwl1000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl1000_base_params,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_100,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
|
||||
|
|
|
@ -520,65 +520,44 @@ static struct iwl_ht_params iwl5000_ht_params = {
|
|||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5000 \
|
||||
.fw_name_pre = IWL5000_FW_PRE, \
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
|
||||
.ops = &iwl5000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
IWL_DEVICE_5000,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_bgn_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 BGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
IWL_DEVICE_5000,
|
||||
.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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_abg_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 ABG",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
IWL_DEVICE_5000,
|
||||
.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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5100_agn_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 AGN",
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
IWL_DEVICE_5000,
|
||||
.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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5350_agn_cfg = {
|
||||
|
@ -593,35 +572,32 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
|||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.internal_wimax_coex = true,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5150 \
|
||||
.fw_name_pre = IWL5150_FW_PRE, \
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
|
||||
.ops = &iwl5150_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
|
||||
struct iwl_cfg iwl5150_agn_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
|
||||
.fw_name_pre = IWL5150_FW_PRE,
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
IWL_DEVICE_5150,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl5150_abg_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
|
||||
.fw_name_pre = IWL5150_FW_PRE,
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5150_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
IWL_DEVICE_5150,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
|
||||
|
|
|
@ -182,7 +182,11 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
|
||||
|
||||
priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
|
||||
priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
|
||||
if (priv->cfg->rx_with_siso_diversity)
|
||||
priv->hw_params.rx_chains_num = 1;
|
||||
else
|
||||
priv->hw_params.rx_chains_num =
|
||||
num_of_ant(priv->cfg->valid_rx_ant);
|
||||
priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
|
||||
priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
|
||||
|
||||
|
@ -511,7 +515,7 @@ static struct iwl_base_params iwl6050_base_params = {
|
|||
.chain_noise_calib_by_driver = true,
|
||||
.shadow_reg_enable = true,
|
||||
};
|
||||
static struct iwl_base_params iwl6000_coex_base_params = {
|
||||
static struct iwl_base_params iwl6000_g2_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
|
||||
|
@ -520,7 +524,7 @@ static struct iwl_base_params iwl6000_coex_base_params = {
|
|||
.use_bsm = false,
|
||||
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 51,
|
||||
.led_compensation = 57,
|
||||
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
|
||||
.supports_idle = true,
|
||||
.adv_thermal_throttle = true,
|
||||
|
@ -550,243 +554,156 @@ static struct iwl_bt_params iwl6000_bt_params = {
|
|||
.bt_sco_disable = true,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6005 \
|
||||
.fw_name_pre = IWL6000G2A_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
|
||||
.ops = &iwl6000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.need_temp_offset_calib = true, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
struct iwl_cfg iwl6005_2agn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6005_2abg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_6005,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6005_2bg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_6005,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6030 \
|
||||
.fw_name_pre = IWL6000G2B_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
|
||||
.ops = &iwl6000g2b_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.bt_params = &iwl6000_bt_params, \
|
||||
.need_dc_calib = true, \
|
||||
.need_temp_offset_calib = true, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.adv_pm = true, \
|
||||
/* \
|
||||
*Due to bluetooth, we transmit 2.4 GHz probes \
|
||||
* only on antenna A \
|
||||
*/ \
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A
|
||||
|
||||
struct iwl_cfg iwl6030_2agn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6030_2abg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6030_2bgn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6030_2bg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1030_bgn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl1030_bg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.need_temp_offset_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.rx_with_siso_diversity = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BG",
|
||||
IWL_DEVICE_6030,
|
||||
.rx_with_siso_diversity = true,
|
||||
};
|
||||
|
||||
/*
|
||||
* "i": Internal configuration, use internal Power Amplifier
|
||||
*/
|
||||
#define IWL_DEVICE_6000i \
|
||||
.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, /* .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, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_base_params, \
|
||||
.pa_type = IWL_PA_INTERNAL, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
struct iwl_cfg iwl6000i_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
|
||||
.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, /* .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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
IWL_DEVICE_6000i,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
|
||||
.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, /* .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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
IWL_DEVICE_6000i,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
|
||||
.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, /* .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,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.pa_type = IWL_PA_INTERNAL,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
IWL_DEVICE_6000i,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6050 \
|
||||
.fw_name_pre = IWL6050_FW_PRE, \
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN, \
|
||||
.ops = &iwl6050_ops, \
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6050_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
|
||||
struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
|
||||
.fw_name_pre = IWL6050_FW_PRE,
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.ops = &iwl6050_ops,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
IWL_DEVICE_6050,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
|
||||
IWL_DEVICE_6050,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6150_bgn_cfg = {
|
||||
|
@ -802,21 +719,7 @@ struct iwl_cfg iwl6150_bgn_cfg = {
|
|||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
|
||||
.fw_name_pre = IWL6050_FW_PRE,
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN,
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
|
||||
.ops = &iwl6050_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.internal_wimax_coex = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
|
@ -834,45 +737,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
|||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bgn_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl130_bg_cfg = {
|
||||
.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,
|
||||
.eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
|
||||
.ops = &iwl6000g2b_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_coex_base_params,
|
||||
.bt_params = &iwl6000_bt_params,
|
||||
.need_dc_calib = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.adv_pm = true,
|
||||
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
|
||||
.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
|
||||
.use_new_eeprom_reading = true,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
|
|
|
@ -856,6 +856,9 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
|
|||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
if (!priv->bt_enable_flag)
|
||||
return -EINVAL;
|
||||
|
||||
/* make request to uCode to retrieve statistics information */
|
||||
mutex_lock(&priv->mutex);
|
||||
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
|
||||
|
|
|
@ -75,109 +75,6 @@
|
|||
#include "iwl-agn.h"
|
||||
#include "iwl-io.h"
|
||||
|
||||
/************************** EEPROM BANDS ****************************
|
||||
*
|
||||
* The iwl_eeprom_band definitions below provide the mapping from the
|
||||
* EEPROM contents to the specific channel number supported for each
|
||||
* band.
|
||||
*
|
||||
* For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
|
||||
* definition below maps to physical channel 42 in the 5.2GHz spectrum.
|
||||
* The specific geography and calibration information for that channel
|
||||
* is contained in the eeprom map itself.
|
||||
*
|
||||
* During init, we copy the eeprom information and channel map
|
||||
* information into priv->channel_info_24/52 and priv->channel_map_24/52
|
||||
*
|
||||
* channel_map_24/52 provides the index in the channel_info array for a
|
||||
* given channel. We have to have two separate maps as there is channel
|
||||
* overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
|
||||
* band_2
|
||||
*
|
||||
* A value of 0xff stored in the channel_map indicates that the channel
|
||||
* is not supported by the hardware at all.
|
||||
*
|
||||
* A value of 0xfe in the channel_map indicates that the channel is not
|
||||
* valid for Tx with the current hardware. This means that
|
||||
* while the system can tune and receive on a given channel, it may not
|
||||
* be able to associate or transmit any frames on that
|
||||
* channel. There is no corresponding channel information for that
|
||||
* entry.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* struct iwl_txpwr_section: eeprom section information
|
||||
* @offset: indirect address into eeprom image
|
||||
* @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
|
||||
* @band: band type for the section
|
||||
* @is_common - true: common section, false: channel section
|
||||
* @is_cck - true: cck section, false: not cck section
|
||||
* @is_ht_40 - true: all channel in the section are HT40 channel,
|
||||
* false: legacy or HT 20 MHz
|
||||
* ignore if it is common section
|
||||
* @iwl_eeprom_section_channel: channel array in the section,
|
||||
* ignore if common section
|
||||
*/
|
||||
struct iwl_txpwr_section {
|
||||
u32 offset;
|
||||
u8 count;
|
||||
enum ieee80211_band band;
|
||||
bool is_common;
|
||||
bool is_cck;
|
||||
bool is_ht40;
|
||||
u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
|
||||
};
|
||||
|
||||
/**
|
||||
* section 1 - 3 are regulatory tx power apply to all channels based on
|
||||
* modulation: CCK, OFDM
|
||||
* Band: 2.4GHz, 5.2GHz
|
||||
* section 4 - 10 are regulatory tx power apply to specified channels
|
||||
* For example:
|
||||
* 1L - Channel 1 Legacy
|
||||
* 1HT - Channel 1 HT
|
||||
* (1,+1) - Channel 1 HT40 "_above_"
|
||||
*
|
||||
* Section 1: all CCK channels
|
||||
* Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
|
||||
* Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
|
||||
* Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
|
||||
* Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
|
||||
* Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
|
||||
* Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
|
||||
* Section 8: 2.4 GHz channel: 13L, 13HT
|
||||
* Section 9: 2.4 GHz channel: 140L, 140HT
|
||||
* Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
|
||||
*
|
||||
*/
|
||||
static const struct iwl_txpwr_section enhinfo[] = {
|
||||
{ EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
|
||||
{ EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
|
||||
{ EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
|
||||
{ EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
|
||||
false, false, false,
|
||||
{1, 1, 2, 2, 10, 10, 11, 11 } },
|
||||
{ EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
|
||||
false, false, true,
|
||||
{ 1, 2, 6, 7, 9 } },
|
||||
{ EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
|
||||
false, false, false,
|
||||
{ 36, 64, 100, 36, 64, 100 } },
|
||||
{ EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
|
||||
false, false, true,
|
||||
{ 36, 60, 100 } },
|
||||
{ EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
|
||||
false, false, false,
|
||||
{ 13, 13 } },
|
||||
{ EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
|
||||
false, false, false,
|
||||
{ 140, 140 } },
|
||||
{ EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
|
||||
false, false, true,
|
||||
{ 132, 44 } },
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* EEPROM related functions
|
||||
|
@ -306,15 +203,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
|
|||
{
|
||||
s8 max_txpower_avg = 0; /* (dBm) */
|
||||
|
||||
IWL_DEBUG_INFO(priv, "%d - "
|
||||
"chain_a: %d dB chain_b: %d dB "
|
||||
"chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
|
||||
element,
|
||||
enhanced_txpower[element].chain_a_max >> 1,
|
||||
enhanced_txpower[element].chain_b_max >> 1,
|
||||
enhanced_txpower[element].chain_c_max >> 1,
|
||||
enhanced_txpower[element].mimo2_max >> 1,
|
||||
enhanced_txpower[element].mimo3_max >> 1);
|
||||
/* Take the highest tx power from any valid chains */
|
||||
if ((priv->cfg->valid_tx_ant & ANT_A) &&
|
||||
(enhanced_txpower[element].chain_a_max > max_txpower_avg))
|
||||
|
@ -344,157 +232,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
|
|||
return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_update_common_txpower: update channel tx power
|
||||
* update tx power per band based on EEPROM enhanced tx power info.
|
||||
*/
|
||||
static s8 iwl_update_common_txpower(struct iwl_priv *priv,
|
||||
struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
|
||||
int section, int element, s8 *max_txpower_in_half_dbm)
|
||||
{
|
||||
struct iwl_channel_info *ch_info;
|
||||
int ch;
|
||||
bool is_ht40 = false;
|
||||
s8 max_txpower_avg; /* (dBm) */
|
||||
|
||||
/* it is common section, contain all type (Legacy, HT and HT40)
|
||||
* based on the element in the section to determine
|
||||
* is it HT 40 or not
|
||||
*/
|
||||
if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
|
||||
is_ht40 = true;
|
||||
max_txpower_avg =
|
||||
iwl_get_max_txpower_avg(priv, enhanced_txpower,
|
||||
element, max_txpower_in_half_dbm);
|
||||
|
||||
ch_info = priv->channel_info;
|
||||
|
||||
for (ch = 0; ch < priv->channel_count; ch++) {
|
||||
/* find matching band and update tx power if needed */
|
||||
if ((ch_info->band == enhinfo[section].band) &&
|
||||
(ch_info->max_power_avg < max_txpower_avg) &&
|
||||
(!is_ht40)) {
|
||||
/* Update regulatory-based run-time data */
|
||||
ch_info->max_power_avg = ch_info->curr_txpow =
|
||||
max_txpower_avg;
|
||||
ch_info->scan_power = max_txpower_avg;
|
||||
}
|
||||
if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
|
||||
(ch_info->ht40_max_power_avg < max_txpower_avg)) {
|
||||
/* Update regulatory-based run-time data */
|
||||
ch_info->ht40_max_power_avg = max_txpower_avg;
|
||||
}
|
||||
ch_info++;
|
||||
}
|
||||
return max_txpower_avg;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_update_channel_txpower: update channel tx power
|
||||
* update channel tx power based on EEPROM enhanced tx power info.
|
||||
*/
|
||||
static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
|
||||
struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
|
||||
int section, int element, s8 *max_txpower_in_half_dbm)
|
||||
{
|
||||
struct iwl_channel_info *ch_info;
|
||||
int ch;
|
||||
u8 channel;
|
||||
s8 max_txpower_avg; /* (dBm) */
|
||||
|
||||
channel = enhinfo[section].iwl_eeprom_section_channel[element];
|
||||
max_txpower_avg =
|
||||
iwl_get_max_txpower_avg(priv, enhanced_txpower,
|
||||
element, max_txpower_in_half_dbm);
|
||||
|
||||
ch_info = priv->channel_info;
|
||||
for (ch = 0; ch < priv->channel_count; ch++) {
|
||||
/* find matching channel and update tx power if needed */
|
||||
if (ch_info->channel == channel) {
|
||||
if ((ch_info->max_power_avg < max_txpower_avg) &&
|
||||
(!enhinfo[section].is_ht40)) {
|
||||
/* Update regulatory-based run-time data */
|
||||
ch_info->max_power_avg = max_txpower_avg;
|
||||
ch_info->curr_txpow = max_txpower_avg;
|
||||
ch_info->scan_power = max_txpower_avg;
|
||||
}
|
||||
if ((enhinfo[section].is_ht40) &&
|
||||
(ch_info->ht40_max_power_avg < max_txpower_avg)) {
|
||||
/* Update regulatory-based run-time data */
|
||||
ch_info->ht40_max_power_avg = max_txpower_avg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ch_info++;
|
||||
}
|
||||
return max_txpower_avg;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
|
||||
*/
|
||||
static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv)
|
||||
{
|
||||
int eeprom_section_count = 0;
|
||||
int section, element;
|
||||
struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
|
||||
u32 offset;
|
||||
s8 max_txpower_avg; /* (dBm) */
|
||||
s8 max_txpower_in_half_dbm; /* (half-dBm) */
|
||||
|
||||
/* Loop through all the sections
|
||||
* adjust bands and channel's max tx power
|
||||
* Set the tx_power_user_lmt to the highest power
|
||||
* supported by any channels and chains
|
||||
*/
|
||||
for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
|
||||
eeprom_section_count = enhinfo[section].count;
|
||||
offset = enhinfo[section].offset;
|
||||
enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
|
||||
/*
|
||||
* check for valid entry -
|
||||
* different version of EEPROM might contain different set
|
||||
* of enhanced tx power table
|
||||
* always check for valid entry before process
|
||||
* the information
|
||||
*/
|
||||
if (!(enhanced_txpower->flags || enhanced_txpower->channel) ||
|
||||
enhanced_txpower->delta_20_in_40)
|
||||
continue;
|
||||
|
||||
for (element = 0; element < eeprom_section_count; element++) {
|
||||
if (enhinfo[section].is_common)
|
||||
max_txpower_avg =
|
||||
iwl_update_common_txpower(priv,
|
||||
enhanced_txpower, section,
|
||||
element,
|
||||
&max_txpower_in_half_dbm);
|
||||
else
|
||||
max_txpower_avg =
|
||||
iwl_update_channel_txpower(priv,
|
||||
enhanced_txpower, section,
|
||||
element,
|
||||
&max_txpower_in_half_dbm);
|
||||
|
||||
/* Update the tx_power_user_lmt to the highest power
|
||||
* supported by any channel */
|
||||
if (max_txpower_avg > priv->tx_power_user_lmt)
|
||||
priv->tx_power_user_lmt = max_txpower_avg;
|
||||
|
||||
/*
|
||||
* Update the tx_power_lmt_in_half_dbm to
|
||||
* the highest power supported by any channel
|
||||
*/
|
||||
if (max_txpower_in_half_dbm >
|
||||
priv->tx_power_lmt_in_half_dbm)
|
||||
priv->tx_power_lmt_in_half_dbm =
|
||||
max_txpower_in_half_dbm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
|
||||
struct iwl_eeprom_enhanced_txpwr *txp,
|
||||
|
@ -533,7 +270,10 @@ iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
|
|||
#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
|
||||
#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)
|
||||
|
||||
static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
|
||||
#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
|
||||
? # x " " : "")
|
||||
|
||||
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
|
||||
int idx, entries;
|
||||
|
@ -547,13 +287,39 @@ static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
|
|||
entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
|
||||
|
||||
txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
|
||||
|
||||
for (idx = 0; idx < entries; idx++) {
|
||||
txp = &txp_array[idx];
|
||||
|
||||
/* skip invalid entries */
|
||||
if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
|
||||
continue;
|
||||
|
||||
IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n",
|
||||
(txp->channel && (txp->flags &
|
||||
IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ?
|
||||
"Common " : (txp->channel) ?
|
||||
"Channel" : "Common",
|
||||
(txp->channel),
|
||||
TXP_CHECK_AND_PRINT(VALID),
|
||||
TXP_CHECK_AND_PRINT(BAND_52G),
|
||||
TXP_CHECK_AND_PRINT(OFDM),
|
||||
TXP_CHECK_AND_PRINT(40MHZ),
|
||||
TXP_CHECK_AND_PRINT(HT_AP),
|
||||
TXP_CHECK_AND_PRINT(RES1),
|
||||
TXP_CHECK_AND_PRINT(RES2),
|
||||
TXP_CHECK_AND_PRINT(COMMON_TYPE),
|
||||
txp->flags);
|
||||
IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x "
|
||||
"chain_B: 0X%02x chain_C: 0X%02x\n",
|
||||
txp->chain_a_max, txp->chain_b_max,
|
||||
txp->chain_c_max);
|
||||
IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x "
|
||||
"MIMO3: 0x%02x High 20_on_40: 0x%02x "
|
||||
"Low 20_on_40: 0x%02x\n",
|
||||
txp->mimo2_max, txp->mimo3_max,
|
||||
((txp->delta_20_in_40 & 0xf0) >> 4),
|
||||
(txp->delta_20_in_40 & 0x0f));
|
||||
|
||||
max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
|
||||
&max_txp_avg_halfdbm);
|
||||
|
||||
|
@ -569,11 +335,3 @@ static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
|
|||
iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
|
||||
}
|
||||
}
|
||||
|
||||
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->use_new_eeprom_reading)
|
||||
iwlcore_eeprom_enhanced_txpower_new(priv);
|
||||
else
|
||||
iwlcore_eeprom_enhanced_txpower_old(priv);
|
||||
}
|
||||
|
|
|
@ -1845,6 +1845,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
|
|||
bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
|
||||
IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
|
||||
}
|
||||
priv->bt_enable_flag = bt_cmd.flags;
|
||||
if (priv->bt_full_concurrent)
|
||||
memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
|
||||
sizeof(iwlagn_concurrent_lookup));
|
||||
|
|
|
@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
|||
if (load > IWL_AGG_LOAD_THRESHOLD) {
|
||||
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
|
||||
sta->addr, tid);
|
||||
ret = ieee80211_start_tx_ba_session(sta, tid);
|
||||
ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
|
||||
if (ret == -EAGAIN) {
|
||||
/*
|
||||
* driver and mac80211 is out of sync
|
||||
|
@ -2873,6 +2873,10 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
|
|||
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
|
||||
lq_sta->is_agg = 0;
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
lq_sta->dbg_fixed_rate = 0;
|
||||
#endif
|
||||
|
||||
rs_initialize_lq(priv, conf, sta, lq_sta);
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (WARN_ON(!ctx->vif)) {
|
||||
if (unlikely(!iwl_is_ready(priv))) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(!ctx->vif)) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1237,7 +1237,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
|
|||
int i, sh, ack;
|
||||
u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
|
||||
u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
|
||||
u64 bitmap, sent_bitmap;
|
||||
int successes = 0;
|
||||
struct ieee80211_tx_info *info;
|
||||
|
||||
|
@ -1278,6 +1277,8 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
|
|||
IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
|
||||
ba_resp->txed, ba_resp->txed_2_done);
|
||||
} else {
|
||||
u64 bitmap, sent_bitmap;
|
||||
|
||||
/* don't use 64-bit values for now */
|
||||
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
|
||||
|
||||
|
@ -1298,7 +1299,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
|
|||
sent_bitmap >>= 1;
|
||||
++i;
|
||||
}
|
||||
|
||||
IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
|
||||
(unsigned long long)bitmap);
|
||||
}
|
||||
|
||||
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
@ -1313,8 +1318,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
|
|||
}
|
||||
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
|
||||
|
||||
IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -957,6 +957,22 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
|
|||
/* Cancel currently queued command. */
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||
|
||||
/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
|
||||
if (priv->cfg->internal_wimax_coex &&
|
||||
(!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
|
||||
APMS_CLK_VAL_MRB_FUNC_MODE) ||
|
||||
(iwl_read_prph(priv, APMG_PS_CTRL_REG) &
|
||||
APMG_PS_CTRL_VAL_RESET_REQ))) {
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
/*
|
||||
*Keep the restart process from trying to send host
|
||||
* commands by clearing the INIT status bit
|
||||
*/
|
||||
clear_bit(STATUS_READY, &priv->status);
|
||||
IWL_ERR(priv, "RF is used by WiMAX\n");
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_ERR(priv, "Loaded firmware version: %s\n",
|
||||
priv->hw->wiphy->fw_version);
|
||||
|
||||
|
@ -1207,6 +1223,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
|
|||
else
|
||||
bt_cmd.flags = BT_COEX_ENABLE;
|
||||
|
||||
priv->bt_enable_flag = bt_cmd.flags;
|
||||
IWL_DEBUG_INFO(priv, "BT coex %s\n",
|
||||
(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
|
||||
|
||||
|
|
|
@ -364,6 +364,8 @@ struct iwl_ht_params {
|
|||
* @scan_antennas: available antenna for scan operation
|
||||
* @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
|
||||
* @adv_pm: advance power management
|
||||
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity
|
||||
* @internal_wimax_coex: internal wifi/wimax combo device
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt API version. The
|
||||
* driver specifies which APIs it supports (with @ucode_api_max being the
|
||||
|
@ -412,7 +414,8 @@ struct iwl_cfg {
|
|||
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
|
||||
enum iwl_led_mode led_mode;
|
||||
const bool adv_pm;
|
||||
const bool use_new_eeprom_reading; /* temporary, remove later */
|
||||
const bool rx_with_siso_diversity;
|
||||
const bool internal_wimax_coex;
|
||||
};
|
||||
|
||||
/***************************
|
||||
|
|
|
@ -120,6 +120,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
|
|||
/* 0x000000F0 - 0x00000010 */
|
||||
#define IWL_DL_MACDUMP (1 << 4)
|
||||
#define IWL_DL_HCMD_DUMP (1 << 5)
|
||||
#define IWL_DL_EEPROM (1 << 6)
|
||||
#define IWL_DL_RADIO (1 << 7)
|
||||
/* 0x00000F00 - 0x00000100 */
|
||||
#define IWL_DL_POWER (1 << 8)
|
||||
|
@ -164,6 +165,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
|
|||
#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
|
||||
#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
|
||||
#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
|
||||
#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a)
|
||||
#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
|
||||
#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
|
||||
#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
|
||||
|
|
|
@ -1567,6 +1567,13 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
|
|||
const size_t bufsz = sizeof(buf);
|
||||
ssize_t ret;
|
||||
|
||||
if (!priv->bt_enable_flag) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
return ret;
|
||||
}
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
|
||||
priv->bt_enable_flag);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
|
||||
priv->bt_full_concurrent ? "full concurrency" : "3-wire");
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
|
||||
|
|
|
@ -1468,6 +1468,7 @@ struct iwl_priv {
|
|||
};
|
||||
|
||||
/* bt coex */
|
||||
u8 bt_enable_flag;
|
||||
u8 bt_status;
|
||||
u8 bt_traffic_load, last_bt_traffic_load;
|
||||
bool bt_ch_announce;
|
||||
|
|
|
@ -147,7 +147,7 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
|
|||
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
|
||||
int ret = 0;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp);
|
||||
IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
|
||||
switch (gp) {
|
||||
case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
|
||||
if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
|
||||
|
@ -354,7 +354,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
|
|||
*/
|
||||
valid_addr = next_link_addr;
|
||||
next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
|
||||
IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
|
||||
IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n",
|
||||
usedblocks, next_link_addr);
|
||||
if (iwl_read_otp_word(priv, next_link_addr, &link_value))
|
||||
return -EINVAL;
|
||||
|
@ -374,7 +374,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
|
|||
} while (usedblocks <= priv->cfg->base_params->max_ll_items);
|
||||
|
||||
/* OTP has no valid blocks */
|
||||
IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
|
||||
IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
|||
return -ENOENT;
|
||||
/* allocate eeprom */
|
||||
sz = priv->cfg->base_params->eeprom_size;
|
||||
IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz);
|
||||
IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
|
||||
priv->eeprom = kzalloc(sz, GFP_KERNEL);
|
||||
if (!priv->eeprom) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -492,7 +492,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
|
|||
}
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
|
||||
IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
|
||||
(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
|
||||
? "OTP" : "EEPROM",
|
||||
iwl_eeprom_query16(priv, EEPROM_VERSION));
|
||||
|
@ -594,7 +594,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
|
|||
if (!is_channel_valid(ch_info))
|
||||
return -1;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
|
||||
IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
|
||||
" Ad-Hoc %ssupported\n",
|
||||
ch_info->channel,
|
||||
is_channel_a_band(ch_info) ?
|
||||
|
@ -634,11 +634,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
|
|||
struct iwl_channel_info *ch_info;
|
||||
|
||||
if (priv->channel_count) {
|
||||
IWL_DEBUG_INFO(priv, "Channel map already initialized.\n");
|
||||
IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n");
|
||||
IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n");
|
||||
|
||||
priv->channel_count =
|
||||
ARRAY_SIZE(iwl_eeprom_band_1) +
|
||||
|
@ -647,7 +647,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
|
|||
ARRAY_SIZE(iwl_eeprom_band_4) +
|
||||
ARRAY_SIZE(iwl_eeprom_band_5);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count);
|
||||
IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
|
||||
priv->channel_count);
|
||||
|
||||
priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
|
||||
priv->channel_count, GFP_KERNEL);
|
||||
|
@ -686,7 +687,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
|
|||
IEEE80211_CHAN_NO_HT40;
|
||||
|
||||
if (!(is_channel_valid(ch_info))) {
|
||||
IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
|
||||
IWL_DEBUG_EEPROM(priv,
|
||||
"Ch. %d Flags %x [%sGHz] - "
|
||||
"No traffic\n",
|
||||
ch_info->channel,
|
||||
ch_info->flags,
|
||||
|
@ -702,7 +704,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
|
|||
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
|
||||
ch_info->min_power = 0;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
|
||||
IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] "
|
||||
"%s%s%s%s%s%s(0x%02x %ddBm):"
|
||||
" Ad-Hoc %ssupported\n",
|
||||
ch_info->channel,
|
||||
is_channel_a_band(ch_info) ?
|
||||
|
|
|
@ -231,59 +231,6 @@ struct iwl_eeprom_enhanced_txpwr {
|
|||
#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
|
||||
|
||||
/* 6000 and up regulatory tx power - indirect access */
|
||||
/* max. elements per section */
|
||||
#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8)
|
||||
#define EEPROM_TXPOWER_COMMON_HT40_INDEX (2)
|
||||
|
||||
/**
|
||||
* Partition the enhanced tx power portion of eeprom image into
|
||||
* 10 sections based on band, modulation, frequency and channel
|
||||
*
|
||||
* Section 1: all CCK channels
|
||||
* Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40 ) channels
|
||||
* Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
|
||||
* Section 4: 2.4 GHz 20MHz channels: 1, 2, 10, 11. Both Legacy and HT
|
||||
* Section 5: 2.4 GHz 40MHz channels: 1, 2, 6, 7, 9, (_above_)
|
||||
* Section 6: 5.2 GHz 20MHz channels: 36, 64, 100, both Legacy and HT
|
||||
* Section 7: 5.2 GHz 40MHz channels: 36, 60, 100 (_above_)
|
||||
* Section 8: 2.4 GHz channel 13, Both Legacy and HT
|
||||
* Section 9: 2.4 GHz channel 140, Both Legacy and HT
|
||||
* Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
|
||||
*/
|
||||
/* 2.4 GHz band: CCK */
|
||||
#define EEPROM_LB_CCK_20_COMMON ((0xA8)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
|
||||
/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
|
||||
#define EEPROM_LB_OFDM_COMMON ((0xB0)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
|
||||
/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
|
||||
#define EEPROM_HB_OFDM_COMMON ((0xC8)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
|
||||
/* 2.4GHz band channels:
|
||||
* 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
|
||||
#define EEPROM_LB_OFDM_20_BAND ((0xE0)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
|
||||
/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
|
||||
#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
|
||||
/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
|
||||
#define EEPROM_HB_OFDM_20_BAND ((0x148)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
|
||||
/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
|
||||
#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
|
||||
/* 2.4 GHz band, channnel 13: Legacy, HT */
|
||||
#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
|
||||
/* 5.2 GHz band, channnel 140: Legacy, HT */
|
||||
#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
|
||||
/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
|
||||
#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
|
||||
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
|
||||
|
||||
|
||||
/* 5050 Specific */
|
||||
#define EEPROM_5050_TX_POWER_VERSION (4)
|
||||
#define EEPROM_5050_EEPROM_VERSION (0x21E)
|
||||
|
|
|
@ -83,10 +83,10 @@
|
|||
#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058)
|
||||
#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C)
|
||||
|
||||
#define APMS_CLK_VAL_MRB_FUNC_MODE (0x00000001)
|
||||
#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
|
||||
#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
|
||||
|
||||
|
||||
#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000)
|
||||
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
|
||||
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
|
||||
|
|
|
@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
|
|||
|
||||
static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
|
||||
struct net_device *ndev,
|
||||
u8 key_index)
|
||||
u8 key_index, bool unicast,
|
||||
bool multicast)
|
||||
{
|
||||
struct iwm_priv *iwm = ndev_to_iwm(ndev);
|
||||
|
||||
|
|
|
@ -1422,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
|||
|
||||
static int lbs_cfg_set_default_key(struct wiphy *wiphy,
|
||||
struct net_device *netdev,
|
||||
u8 key_index)
|
||||
u8 key_index, bool unicast,
|
||||
bool multicast)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
|
||||
|
|
|
@ -554,7 +554,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
|||
u8 key_index, bool pairwise, const u8 *mac_addr);
|
||||
|
||||
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index);
|
||||
u8 key_index, bool unicast, bool multicast);
|
||||
|
||||
static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *mac, struct station_info *sinfo);
|
||||
|
@ -2381,7 +2381,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
|||
}
|
||||
|
||||
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index)
|
||||
u8 key_index, bool unicast, bool multicast)
|
||||
{
|
||||
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
|
||||
struct usbnet *usbdev = priv->usbdev;
|
||||
|
|
|
@ -632,6 +632,88 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
|
|||
rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt2400pci_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
|
||||
rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
|
||||
rt2x00_set_field32(®, CSR14_TBCN, 1);
|
||||
rt2x00_set_field32(®, CSR14_BEACON_GEN, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2400pci_kick_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_AC_VI:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_TX, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_ATIM:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2400pci_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_ATIM:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_ABORT, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
|
||||
rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
|
||||
rt2x00_set_field32(®, CSR14_TBCN, 0);
|
||||
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
|
@ -878,17 +960,6 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX,
|
||||
(state == STATE_RADIO_RX_OFF));
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
}
|
||||
|
||||
static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
|
@ -987,10 +1058,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
case STATE_RADIO_OFF:
|
||||
rt2400pci_disable_radio(rt2x00dev);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt2400pci_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -1122,32 +1189,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
|
|||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
}
|
||||
|
||||
static void rt2400pci_kick_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
}
|
||||
|
||||
static void rt2400pci_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
if (queue->qid == QID_BEACON) {
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
|
||||
} else {
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_ABORT, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -1281,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
|
|||
* 4 - Priority ring transmit done interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
|
||||
rt2400pci_txdone(rt2x00dev, QID_AC_BE);
|
||||
rt2400pci_txdone(rt2x00dev, QID_AC_VO);
|
||||
|
||||
/*
|
||||
* 5 - Tx ring transmit done interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
|
||||
rt2400pci_txdone(rt2x00dev, QID_AC_BK);
|
||||
rt2400pci_txdone(rt2x00dev, QID_AC_VI);
|
||||
|
||||
/* Enable interrupts again. */
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
|
@ -1625,10 +1666,11 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
|
|||
.link_stats = rt2400pci_link_stats,
|
||||
.reset_tuner = rt2400pci_reset_tuner,
|
||||
.link_tuner = rt2400pci_link_tuner,
|
||||
.start_queue = rt2400pci_start_queue,
|
||||
.kick_queue = rt2400pci_kick_queue,
|
||||
.stop_queue = rt2400pci_stop_queue,
|
||||
.write_tx_desc = rt2400pci_write_tx_desc,
|
||||
.write_beacon = rt2400pci_write_beacon,
|
||||
.kick_tx_queue = rt2400pci_kick_tx_queue,
|
||||
.kill_tx_queue = rt2400pci_kill_tx_queue,
|
||||
.fill_rxdone = rt2400pci_fill_rxdone,
|
||||
.config_filter = rt2400pci_config_filter,
|
||||
.config_intf = rt2400pci_config_intf,
|
||||
|
|
|
@ -722,6 +722,88 @@ dynamic_cca_tune:
|
|||
rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt2500pci_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
|
||||
rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
|
||||
rt2x00_set_field32(®, CSR14_TBCN, 1);
|
||||
rt2x00_set_field32(®, CSR14_BEACON_GEN, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2500pci_kick_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_AC_VI:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_TX, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_ATIM:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2500pci_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_ATIM:
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_ABORT, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
break;
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
|
||||
rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
|
||||
rt2x00_set_field32(®, CSR14_TBCN, 0);
|
||||
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
|
@ -1033,17 +1115,6 @@ static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
|
||||
rt2x00_set_field32(®, RXCSR0_DISABLE_RX,
|
||||
(state == STATE_RADIO_RX_OFF));
|
||||
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
|
||||
}
|
||||
|
||||
static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
|
@ -1142,10 +1213,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
case STATE_RADIO_OFF:
|
||||
rt2500pci_disable_radio(rt2x00dev);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt2500pci_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -1276,32 +1343,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
|
|||
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
|
||||
}
|
||||
|
||||
static void rt2500pci_kick_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
|
||||
rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
}
|
||||
|
||||
static void rt2500pci_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
if (queue->qid == QID_BEACON) {
|
||||
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
|
||||
} else {
|
||||
rt2x00pci_register_read(rt2x00dev, TXCSR0, ®);
|
||||
rt2x00_set_field32(®, TXCSR0_ABORT, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -1414,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
|
|||
* 4 - Priority ring transmit done interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
|
||||
rt2500pci_txdone(rt2x00dev, QID_AC_BE);
|
||||
rt2500pci_txdone(rt2x00dev, QID_AC_VO);
|
||||
|
||||
/*
|
||||
* 5 - Tx ring transmit done interrupt.
|
||||
*/
|
||||
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
|
||||
rt2500pci_txdone(rt2x00dev, QID_AC_BK);
|
||||
rt2500pci_txdone(rt2x00dev, QID_AC_VI);
|
||||
|
||||
/* Enable interrupts again. */
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
|
@ -1922,10 +1963,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
|
|||
.link_stats = rt2500pci_link_stats,
|
||||
.reset_tuner = rt2500pci_reset_tuner,
|
||||
.link_tuner = rt2500pci_link_tuner,
|
||||
.start_queue = rt2500pci_start_queue,
|
||||
.kick_queue = rt2500pci_kick_queue,
|
||||
.stop_queue = rt2500pci_stop_queue,
|
||||
.write_tx_desc = rt2500pci_write_tx_desc,
|
||||
.write_beacon = rt2500pci_write_beacon,
|
||||
.kick_tx_queue = rt2500pci_kick_tx_queue,
|
||||
.kill_tx_queue = rt2500pci_kill_tx_queue,
|
||||
.fill_rxdone = rt2500pci_fill_rxdone,
|
||||
.config_filter = rt2500pci_config_filter,
|
||||
.config_intf = rt2500pci_config_intf,
|
||||
|
|
|
@ -738,6 +738,55 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
|
|||
qual->vgc_level = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt2500usb_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u16 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, 0);
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1);
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2500usb_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u16 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, 1);
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0);
|
||||
rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization functions.
|
||||
*/
|
||||
|
@ -931,17 +980,6 @@ static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX,
|
||||
(state == STATE_RADIO_RX_OFF));
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
|
||||
}
|
||||
|
||||
static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
/*
|
||||
|
@ -1017,10 +1055,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
case STATE_RADIO_OFF:
|
||||
rt2500usb_disable_radio(rt2x00dev);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt2500usb_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -1203,14 +1237,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
|
|||
return length;
|
||||
}
|
||||
|
||||
static void rt2500usb_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
if (queue->qid == QID_BEACON)
|
||||
rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
|
||||
|
||||
rt2x00usb_kill_tx_queue(queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -1811,11 +1837,13 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
|
|||
.link_stats = rt2500usb_link_stats,
|
||||
.reset_tuner = rt2500usb_reset_tuner,
|
||||
.watchdog = rt2x00usb_watchdog,
|
||||
.start_queue = rt2500usb_start_queue,
|
||||
.kick_queue = rt2x00usb_kick_queue,
|
||||
.stop_queue = rt2500usb_stop_queue,
|
||||
.flush_queue = rt2x00usb_flush_queue,
|
||||
.write_tx_desc = rt2500usb_write_tx_desc,
|
||||
.write_beacon = rt2500usb_write_beacon,
|
||||
.get_tx_data_len = rt2500usb_get_tx_data_len,
|
||||
.kick_tx_queue = rt2x00usb_kick_tx_queue,
|
||||
.kill_tx_queue = rt2500usb_kill_tx_queue,
|
||||
.fill_rxdone = rt2500usb_fill_rxdone,
|
||||
.config_shared_key = rt2500usb_config_key,
|
||||
.config_pairwise_key = rt2500usb_config_key,
|
||||
|
|
|
@ -46,8 +46,11 @@
|
|||
* RF2020 2.4G B/G
|
||||
* RF3021 2.4G 1T2R
|
||||
* RF3022 2.4G 2T2R
|
||||
* RF3052 2.4G 2T2R
|
||||
* RF3320 2.4G 1T1R
|
||||
* RF3052 2.4G/5G 2T2R
|
||||
* RF2853 2.4G/5G 3T3R
|
||||
* RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
|
||||
* RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
|
||||
* RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
|
||||
*/
|
||||
#define RF2820 0x0001
|
||||
#define RF2850 0x0002
|
||||
|
@ -58,7 +61,10 @@
|
|||
#define RF3021 0x0007
|
||||
#define RF3022 0x0008
|
||||
#define RF3052 0x0009
|
||||
#define RF2853 0x000a
|
||||
#define RF3320 0x000b
|
||||
#define RF3322 0x000c
|
||||
#define RF3853 0x000d
|
||||
|
||||
/*
|
||||
* Chipset revisions.
|
||||
|
@ -207,10 +213,10 @@
|
|||
|
||||
/*
|
||||
* WMM_AIFSN_CFG: Aifsn for each EDCA AC
|
||||
* AIFSN0: AC_BE
|
||||
* AIFSN1: AC_BK
|
||||
* AIFSN2: AC_VI
|
||||
* AIFSN3: AC_VO
|
||||
* AIFSN0: AC_VO
|
||||
* AIFSN1: AC_VI
|
||||
* AIFSN2: AC_BE
|
||||
* AIFSN3: AC_BK
|
||||
*/
|
||||
#define WMM_AIFSN_CFG 0x0214
|
||||
#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f)
|
||||
|
@ -220,10 +226,10 @@
|
|||
|
||||
/*
|
||||
* WMM_CWMIN_CSR: CWmin for each EDCA AC
|
||||
* CWMIN0: AC_BE
|
||||
* CWMIN1: AC_BK
|
||||
* CWMIN2: AC_VI
|
||||
* CWMIN3: AC_VO
|
||||
* CWMIN0: AC_VO
|
||||
* CWMIN1: AC_VI
|
||||
* CWMIN2: AC_BE
|
||||
* CWMIN3: AC_BK
|
||||
*/
|
||||
#define WMM_CWMIN_CFG 0x0218
|
||||
#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f)
|
||||
|
@ -233,10 +239,10 @@
|
|||
|
||||
/*
|
||||
* WMM_CWMAX_CSR: CWmax for each EDCA AC
|
||||
* CWMAX0: AC_BE
|
||||
* CWMAX1: AC_BK
|
||||
* CWMAX2: AC_VI
|
||||
* CWMAX3: AC_VO
|
||||
* CWMAX0: AC_VO
|
||||
* CWMAX1: AC_VI
|
||||
* CWMAX2: AC_BE
|
||||
* CWMAX3: AC_BK
|
||||
*/
|
||||
#define WMM_CWMAX_CFG 0x021c
|
||||
#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f)
|
||||
|
@ -245,18 +251,18 @@
|
|||
#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000)
|
||||
|
||||
/*
|
||||
* AC_TXOP0: AC_BK/AC_BE TXOP register
|
||||
* AC0TXOP: AC_BK in unit of 32us
|
||||
* AC1TXOP: AC_BE in unit of 32us
|
||||
* AC_TXOP0: AC_VO/AC_VI TXOP register
|
||||
* AC0TXOP: AC_VO in unit of 32us
|
||||
* AC1TXOP: AC_VI in unit of 32us
|
||||
*/
|
||||
#define WMM_TXOP0_CFG 0x0220
|
||||
#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff)
|
||||
#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* AC_TXOP1: AC_VO/AC_VI TXOP register
|
||||
* AC2TXOP: AC_VI in unit of 32us
|
||||
* AC3TXOP: AC_VO in unit of 32us
|
||||
* AC_TXOP1: AC_BE/AC_BK TXOP register
|
||||
* AC2TXOP: AC_BE in unit of 32us
|
||||
* AC3TXOP: AC_BK in unit of 32us
|
||||
*/
|
||||
#define WMM_TXOP1_CFG 0x0224
|
||||
#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff)
|
||||
|
@ -282,7 +288,7 @@
|
|||
#define MCU_CMD_CFG 0x022c
|
||||
|
||||
/*
|
||||
* AC_BK register offsets
|
||||
* AC_VO register offsets
|
||||
*/
|
||||
#define TX_BASE_PTR0 0x0230
|
||||
#define TX_MAX_CNT0 0x0234
|
||||
|
@ -290,7 +296,7 @@
|
|||
#define TX_DTX_IDX0 0x023c
|
||||
|
||||
/*
|
||||
* AC_BE register offsets
|
||||
* AC_VI register offsets
|
||||
*/
|
||||
#define TX_BASE_PTR1 0x0240
|
||||
#define TX_MAX_CNT1 0x0244
|
||||
|
@ -298,7 +304,7 @@
|
|||
#define TX_DTX_IDX1 0x024c
|
||||
|
||||
/*
|
||||
* AC_VI register offsets
|
||||
* AC_BE register offsets
|
||||
*/
|
||||
#define TX_BASE_PTR2 0x0250
|
||||
#define TX_MAX_CNT2 0x0254
|
||||
|
@ -306,7 +312,7 @@
|
|||
#define TX_DTX_IDX2 0x025c
|
||||
|
||||
/*
|
||||
* AC_VO register offsets
|
||||
* AC_BK register offsets
|
||||
*/
|
||||
#define TX_BASE_PTR3 0x0260
|
||||
#define TX_MAX_CNT3 0x0264
|
||||
|
@ -699,8 +705,18 @@
|
|||
|
||||
/*
|
||||
* CH_TIME_CFG: count as channel busy
|
||||
* EIFS_BUSY: Count EIFS as channel busy
|
||||
* NAV_BUSY: Count NAS as channel busy
|
||||
* RX_BUSY: Count RX as channel busy
|
||||
* TX_BUSY: Count TX as channel busy
|
||||
* TMR_EN: Enable channel statistics timer
|
||||
*/
|
||||
#define CH_TIME_CFG 0x110c
|
||||
#define CH_TIME_CFG_EIFS_BUSY FIELD32(0x00000010)
|
||||
#define CH_TIME_CFG_NAV_BUSY FIELD32(0x00000008)
|
||||
#define CH_TIME_CFG_RX_BUSY FIELD32(0x00000004)
|
||||
#define CH_TIME_CFG_TX_BUSY FIELD32(0x00000002)
|
||||
#define CH_TIME_CFG_TMR_EN FIELD32(0x00000001)
|
||||
|
||||
/*
|
||||
* PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
|
||||
|
@ -1841,32 +1857,51 @@ struct mac_iveiv_entry {
|
|||
#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
|
||||
|
||||
/*
|
||||
* EEPROM ANTENNA config
|
||||
* EEPROM NIC Configuration 0
|
||||
* RXPATH: 1: 1R, 2: 2R, 3: 3R
|
||||
* TXPATH: 1: 1T, 2: 2T
|
||||
* TXPATH: 1: 1T, 2: 2T, 3: 3T
|
||||
* RF_TYPE: RFIC type
|
||||
*/
|
||||
#define EEPROM_ANTENNA 0x001a
|
||||
#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f)
|
||||
#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0)
|
||||
#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00)
|
||||
#define EEPROM_NIC_CONF0 0x001a
|
||||
#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
|
||||
#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
|
||||
#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
|
||||
|
||||
/*
|
||||
* EEPROM NIC config
|
||||
* CARDBUS_ACCEL: 0 - enable, 1 - disable
|
||||
* EEPROM NIC Configuration 1
|
||||
* HW_RADIO: 0: disable, 1: enable
|
||||
* EXTERNAL_TX_ALC: 0: disable, 1: enable
|
||||
* EXTERNAL_LNA_2G: 0: disable, 1: enable
|
||||
* EXTERNAL_LNA_5G: 0: disable, 1: enable
|
||||
* CARDBUS_ACCEL: 0: enable, 1: disable
|
||||
* BW40M_SB_2G: 0: disable, 1: enable
|
||||
* BW40M_SB_5G: 0: disable, 1: enable
|
||||
* WPS_PBC: 0: disable, 1: enable
|
||||
* BW40M_2G: 0: enable, 1: disable
|
||||
* BW40M_5G: 0: enable, 1: disable
|
||||
* BROADBAND_EXT_LNA: 0: disable, 1: enable
|
||||
* ANT_DIVERSITY: 00: Disable, 01: Diversity,
|
||||
* 10: Main antenna, 11: Aux antenna
|
||||
* INTERNAL_TX_ALC: 0: disable, 1: enable
|
||||
* BT_COEXIST: 0: disable, 1: enable
|
||||
* DAC_TEST: 0: disable, 1: enable
|
||||
*/
|
||||
#define EEPROM_NIC 0x001b
|
||||
#define EEPROM_NIC_HW_RADIO FIELD16(0x0001)
|
||||
#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002)
|
||||
#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004)
|
||||
#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008)
|
||||
#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010)
|
||||
#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020)
|
||||
#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040)
|
||||
#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
|
||||
#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
|
||||
#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
|
||||
#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800)
|
||||
#define EEPROM_NIC_DAC_TEST FIELD16(0x8000)
|
||||
#define EEPROM_NIC_CONF1 0x001b
|
||||
#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
|
||||
#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
|
||||
#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
|
||||
#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008)
|
||||
#define EEPROM_NIC_CONF1_CARDBUS_ACCEL FIELD16(0x0010)
|
||||
#define EEPROM_NIC_CONF1_BW40M_SB_2G FIELD16(0x0020)
|
||||
#define EEPROM_NIC_CONF1_BW40M_SB_5G FIELD16(0x0040)
|
||||
#define EEPROM_NIC_CONF1_WPS_PBC FIELD16(0x0080)
|
||||
#define EEPROM_NIC_CONF1_BW40M_2G FIELD16(0x0100)
|
||||
#define EEPROM_NIC_CONF1_BW40M_5G FIELD16(0x0200)
|
||||
#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400)
|
||||
#define EEPROM_NIC_CONF1_ANT_DIVERSITY FIELD16(0x1800)
|
||||
#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000)
|
||||
#define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000)
|
||||
#define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* EEPROM frequency
|
||||
|
@ -1888,9 +1923,9 @@ struct mac_iveiv_entry {
|
|||
* POLARITY_GPIO_4: Polarity GPIO4 setting.
|
||||
* LED_MODE: Led mode.
|
||||
*/
|
||||
#define EEPROM_LED1 0x001e
|
||||
#define EEPROM_LED2 0x001f
|
||||
#define EEPROM_LED3 0x0020
|
||||
#define EEPROM_LED_AG_CONF 0x001e
|
||||
#define EEPROM_LED_ACT_CONF 0x001f
|
||||
#define EEPROM_LED_POLARITY 0x0020
|
||||
#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
|
||||
#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
|
||||
#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
|
||||
|
@ -1901,6 +1936,17 @@ struct mac_iveiv_entry {
|
|||
#define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080)
|
||||
#define EEPROM_LED_LED_MODE FIELD16(0x1f00)
|
||||
|
||||
/*
|
||||
* EEPROM NIC Configuration 2
|
||||
* RX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
|
||||
* TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
|
||||
* CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
|
||||
*/
|
||||
#define EEPROM_NIC_CONF2 0x0021
|
||||
#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
|
||||
#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
|
||||
#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
|
||||
|
||||
/*
|
||||
* EEPROM LNA
|
||||
*/
|
||||
|
@ -1951,7 +1997,7 @@ struct mac_iveiv_entry {
|
|||
|
||||
/*
|
||||
* EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
|
||||
* This is delta in 40MHZ.
|
||||
* This is delta in 40MHZ.
|
||||
* VALUE: Tx Power dalta value (MAX=4)
|
||||
* TYPE: 1: Plus the delta value, 0: minus the delta value
|
||||
* TXPOWER: Enable:
|
||||
|
@ -2007,9 +2053,9 @@ struct mac_iveiv_entry {
|
|||
#define MCU_CURRENT 0x36
|
||||
#define MCU_LED 0x50
|
||||
#define MCU_LED_STRENGTH 0x51
|
||||
#define MCU_LED_1 0x52
|
||||
#define MCU_LED_2 0x53
|
||||
#define MCU_LED_3 0x54
|
||||
#define MCU_LED_AG_CONF 0x52
|
||||
#define MCU_LED_ACT_CONF 0x53
|
||||
#define MCU_LED_LED_POLARITY 0x54
|
||||
#define MCU_RADAR 0x60
|
||||
#define MCU_BOOT_SIGNAL 0x72
|
||||
#define MCU_BBP_SIGNAL 0x80
|
||||
|
|
|
@ -772,6 +772,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
|
|||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
unsigned int beacon_base;
|
||||
unsigned int padding_len;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
|
@ -806,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
|
|||
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
|
||||
/*
|
||||
* Write entire beacon with TXWI to register.
|
||||
* Write entire beacon with TXWI and padding to register.
|
||||
*/
|
||||
padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
|
||||
skb_pad(entry->skb, padding_len);
|
||||
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
|
||||
rt2800_register_multiwrite(rt2x00dev, beacon_base,
|
||||
entry->skb->data, entry->skb->len);
|
||||
rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
|
||||
entry->skb->len + padding_len);
|
||||
|
||||
/*
|
||||
* Enable beaconing again.
|
||||
|
@ -1625,6 +1628,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
|||
}
|
||||
|
||||
msleep(1);
|
||||
|
||||
/*
|
||||
* Clear channel statistic counters
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, CH_IDLE_STA, ®);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®);
|
||||
}
|
||||
|
||||
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
|
||||
|
@ -1930,8 +1940,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
|||
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
|
||||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
|
||||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
|
||||
0x0000002c);
|
||||
else
|
||||
|
@ -2259,6 +2269,17 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
|||
rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
|
||||
rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
|
||||
|
||||
/*
|
||||
* Set up channel statistics timer
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, CH_TIME_CFG, ®);
|
||||
rt2x00_set_field32(®, CH_TIME_CFG_EIFS_BUSY, 1);
|
||||
rt2x00_set_field32(®, CH_TIME_CFG_NAV_BUSY, 1);
|
||||
rt2x00_set_field32(®, CH_TIME_CFG_RX_BUSY, 1);
|
||||
rt2x00_set_field32(®, CH_TIME_CFG_TX_BUSY, 1);
|
||||
rt2x00_set_field32(®, CH_TIME_CFG_TMR_EN, 1);
|
||||
rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2376,10 +2397,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
rt2800_bbp_read(rt2x00dev, 138, &value);
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
|
||||
value |= 0x20;
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
|
||||
value &= ~0x02;
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 138, value);
|
||||
|
@ -2591,8 +2612,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
|||
rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
|
||||
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
|
||||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
|
||||
rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3);
|
||||
else
|
||||
rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0);
|
||||
|
@ -2665,10 +2686,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
|||
if (rt2x00_rt(rt2x00dev, RT3090)) {
|
||||
rt2800_bbp_read(rt2x00dev, 138, &bbp);
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
|
||||
rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
|
||||
rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 138, bbp);
|
||||
|
@ -2767,16 +2788,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Initialize LED control
|
||||
*/
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
|
||||
word & 0xff, (word >> 8) & 0xff);
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
|
||||
word & 0xff, (word >> 8) & 0xff);
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
|
||||
rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
|
||||
word & 0xff, (word >> 8) & 0xff);
|
||||
|
||||
return 0;
|
||||
|
@ -2870,38 +2891,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
EEPROM(rt2x00dev, "MAC: %pM\n", mac);
|
||||
}
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
|
||||
if (word == 0xffff) {
|
||||
rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
|
||||
rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
|
||||
rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
|
||||
EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
|
||||
rt2x00_rt(rt2x00dev, RT2872)) {
|
||||
/*
|
||||
* There is a max of 2 RX streams for RT28x0 series
|
||||
*/
|
||||
if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
|
||||
rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
|
||||
if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
|
||||
}
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
|
||||
if (word == 0xffff) {
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
|
||||
rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
|
||||
EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
|
||||
}
|
||||
|
||||
|
@ -2916,9 +2940,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
LED_MODE_TXRX_ACTIVITY);
|
||||
rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
|
||||
EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word);
|
||||
}
|
||||
|
||||
|
@ -2982,12 +3006,12 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Read EEPROM word for configuration.
|
||||
*/
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
|
||||
|
||||
/*
|
||||
* Identify RF chipset.
|
||||
*/
|
||||
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
|
||||
value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
|
||||
rt2800_register_read(rt2x00dev, MAC_CSR0, ®);
|
||||
|
||||
rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
|
||||
|
@ -3023,9 +3047,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
* Identify default antenna configuration.
|
||||
*/
|
||||
rt2x00dev->default_ant.tx =
|
||||
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
|
||||
rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
|
||||
rt2x00dev->default_ant.rx =
|
||||
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
|
||||
rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
|
||||
|
||||
/*
|
||||
* Read frequency offset and RF programming sequence.
|
||||
|
@ -3036,17 +3060,17 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Read external LNA informations.
|
||||
*/
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
|
||||
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
|
||||
__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
|
||||
__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
|
||||
|
||||
/*
|
||||
* Detect if this device has an hardware controlled radio.
|
||||
*/
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
|
||||
__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
|
||||
|
||||
/*
|
||||
|
@ -3258,7 +3282,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||
rt2x00dev->hw->max_report_rates = 7;
|
||||
rt2x00dev->hw->max_rate_tries = 1;
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
|
||||
|
||||
/*
|
||||
* Initialize hw_mode information.
|
||||
|
@ -3302,11 +3326,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||
IEEE80211_HT_CAP_SGI_20 |
|
||||
IEEE80211_HT_CAP_SGI_40;
|
||||
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2)
|
||||
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2)
|
||||
spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC;
|
||||
|
||||
spec->ht.cap |=
|
||||
rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) <<
|
||||
rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) <<
|
||||
IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
|
||||
spec->ht.ampdu_factor = 3;
|
||||
|
@ -3314,10 +3338,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||
spec->ht.mcs.tx_params =
|
||||
IEEE80211_HT_MCS_TX_DEFINED |
|
||||
IEEE80211_HT_MCS_TX_RX_DIFF |
|
||||
((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
|
||||
((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) <<
|
||||
IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
|
||||
|
||||
switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
|
||||
switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) {
|
||||
case 3:
|
||||
spec->ht.mcs.rx_mask[2] = 0xff;
|
||||
case 2:
|
||||
|
@ -3536,6 +3560,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_ampdu_action);
|
||||
|
||||
int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
u32 idle, busy, busy_ext;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
|
||||
rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext);
|
||||
|
||||
if (idle || busy) {
|
||||
survey->filled = SURVEY_INFO_CHANNEL_TIME |
|
||||
SURVEY_INFO_CHANNEL_TIME_BUSY |
|
||||
SURVEY_INFO_CHANNEL_TIME_EXT_BUSY;
|
||||
|
||||
survey->channel_time = (idle + busy) / 1000;
|
||||
survey->channel_time_busy = busy / 1000;
|
||||
survey->channel_time_ext_busy = busy_ext / 1000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_get_survey);
|
||||
|
||||
MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_DESCRIPTION("Ralink RT2800 library");
|
||||
|
|
|
@ -199,5 +199,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw);
|
|||
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
|
||||
int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey);
|
||||
|
||||
#endif /* RT2800LIB_H */
|
||||
|
|
|
@ -185,6 +185,77 @@ static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
|
|||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt2800pci_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1);
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
static void rt2800pci_kick_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
struct queue_entry *entry;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
||||
rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
|
||||
break;
|
||||
case QID_MGMT:
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
||||
rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800pci_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0);
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware functions
|
||||
*/
|
||||
|
@ -323,17 +394,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX,
|
||||
(state == STATE_RADIO_RX_ON));
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
}
|
||||
|
||||
static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
|
@ -477,10 +537,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
rt2800pci_disable_radio(rt2x00dev);
|
||||
rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt2800pci_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -565,41 +621,6 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
|
|||
skbdesc->desc_len = TXD_DESC_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* TX data initialization
|
||||
*/
|
||||
static void rt2800pci_kick_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
||||
unsigned int qidx;
|
||||
|
||||
if (queue->qid == QID_MGMT)
|
||||
qidx = 5;
|
||||
else
|
||||
qidx = queue->qid;
|
||||
|
||||
rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx);
|
||||
}
|
||||
|
||||
static void rt2800pci_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
if (queue->qid == QID_BEACON) {
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®);
|
||||
rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE));
|
||||
rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK));
|
||||
rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI));
|
||||
rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO));
|
||||
rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -682,7 +703,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
|||
* this tx status.
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status report with "
|
||||
"unexpected pid %u, dropping", qid);
|
||||
"unexpected pid %u, dropping\n", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -693,7 +714,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
|||
* processing here and drop the tx status
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status for an unavailable "
|
||||
"queue %u, dropping", qid);
|
||||
"queue %u, dropping\n", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -703,7 +724,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
|||
* and drop the tx status.
|
||||
*/
|
||||
WARNING(rt2x00dev, "Got TX status for an empty "
|
||||
"queue %u, dropping", qid);
|
||||
"queue %u, dropping\n", qid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -944,6 +965,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
|||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||
.ampdu_action = rt2800_ampdu_action,
|
||||
.flush = rt2x00mac_flush,
|
||||
.get_survey = rt2800_get_survey,
|
||||
};
|
||||
|
||||
static const struct rt2800_ops rt2800pci_rt2800_ops = {
|
||||
|
@ -976,11 +998,12 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
|||
.link_stats = rt2800_link_stats,
|
||||
.reset_tuner = rt2800_reset_tuner,
|
||||
.link_tuner = rt2800_link_tuner,
|
||||
.start_queue = rt2800pci_start_queue,
|
||||
.kick_queue = rt2800pci_kick_queue,
|
||||
.stop_queue = rt2800pci_stop_queue,
|
||||
.write_tx_desc = rt2800pci_write_tx_desc,
|
||||
.write_tx_data = rt2800_write_tx_data,
|
||||
.write_beacon = rt2800_write_beacon,
|
||||
.kick_tx_queue = rt2800pci_kick_tx_queue,
|
||||
.kill_tx_queue = rt2800pci_kill_tx_queue,
|
||||
.fill_rxdone = rt2800pci_fill_rxdone,
|
||||
.config_shared_key = rt2800_config_shared_key,
|
||||
.config_pairwise_key = rt2800_config_pairwise_key,
|
||||
|
|
|
@ -49,6 +49,55 @@ static int modparam_nohwcrypt;
|
|||
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt2800usb_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1);
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800usb_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0);
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0);
|
||||
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
|
||||
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware functions
|
||||
*/
|
||||
|
@ -107,17 +156,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
|
||||
rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX,
|
||||
(state == STATE_RADIO_RX_ON));
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
|
||||
}
|
||||
|
||||
static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
|
@ -214,10 +252,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
rt2800usb_disable_radio(rt2x00dev);
|
||||
rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt2800usb_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -253,7 +287,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
|
|||
rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®);
|
||||
if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
|
||||
WARNING(rt2x00dev, "TX HW queue 0 timed out,"
|
||||
" invoke forced kick");
|
||||
" invoke forced kick\n");
|
||||
|
||||
rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
|
||||
|
||||
|
@ -269,7 +303,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
|
|||
rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®);
|
||||
if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
|
||||
WARNING(rt2x00dev, "TX HW queue 1 timed out,"
|
||||
" invoke forced kick");
|
||||
" invoke forced kick\n");
|
||||
|
||||
rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
|
||||
|
||||
|
@ -389,14 +423,6 @@ static void rt2800usb_work_txdone(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
static void rt2800usb_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
if (queue->qid == QID_BEACON)
|
||||
rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
|
||||
|
||||
rt2x00usb_kill_tx_queue(queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -562,6 +588,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
|
|||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||
.ampdu_action = rt2800_ampdu_action,
|
||||
.flush = rt2x00mac_flush,
|
||||
.get_survey = rt2800_get_survey,
|
||||
};
|
||||
|
||||
static const struct rt2800_ops rt2800usb_rt2800_ops = {
|
||||
|
@ -591,12 +618,14 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
|
|||
.reset_tuner = rt2800_reset_tuner,
|
||||
.link_tuner = rt2800_link_tuner,
|
||||
.watchdog = rt2800usb_watchdog,
|
||||
.start_queue = rt2800usb_start_queue,
|
||||
.kick_queue = rt2x00usb_kick_queue,
|
||||
.stop_queue = rt2800usb_stop_queue,
|
||||
.flush_queue = rt2x00usb_flush_queue,
|
||||
.write_tx_desc = rt2800usb_write_tx_desc,
|
||||
.write_tx_data = rt2800usb_write_tx_data,
|
||||
.write_beacon = rt2800_write_beacon,
|
||||
.get_tx_data_len = rt2800usb_get_tx_data_len,
|
||||
.kick_tx_queue = rt2x00usb_kick_tx_queue,
|
||||
.kill_tx_queue = rt2800usb_kill_tx_queue,
|
||||
.fill_rxdone = rt2800usb_fill_rxdone,
|
||||
.config_shared_key = rt2800_config_shared_key,
|
||||
.config_pairwise_key = rt2800_config_pairwise_key,
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
|
||||
#ifdef CONFIG_RT2X00_DEBUG
|
||||
#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
|
||||
DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args);
|
||||
DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args)
|
||||
#else
|
||||
#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
|
||||
do { } while (0)
|
||||
|
@ -567,7 +567,15 @@ struct rt2x00lib_ops {
|
|||
struct link_qual *qual);
|
||||
void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
|
||||
struct link_qual *qual, const u32 count);
|
||||
|
||||
/*
|
||||
* Data queue handlers.
|
||||
*/
|
||||
void (*watchdog) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*start_queue) (struct data_queue *queue);
|
||||
void (*kick_queue) (struct data_queue *queue);
|
||||
void (*stop_queue) (struct data_queue *queue);
|
||||
void (*flush_queue) (struct data_queue *queue);
|
||||
|
||||
/*
|
||||
* TX control handlers
|
||||
|
@ -579,8 +587,6 @@ struct rt2x00lib_ops {
|
|||
void (*write_beacon) (struct queue_entry *entry,
|
||||
struct txentry_desc *txdesc);
|
||||
int (*get_tx_data_len) (struct queue_entry *entry);
|
||||
void (*kick_tx_queue) (struct data_queue *queue);
|
||||
void (*kill_tx_queue) (struct data_queue *queue);
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
|
@ -1068,6 +1074,78 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
|
|||
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
|
||||
enum queue_index index);
|
||||
|
||||
/**
|
||||
* rt2x00queue_pause_queue - Pause a data queue
|
||||
* @queue: Pointer to &struct data_queue.
|
||||
*
|
||||
* This function will pause the data queue locally, preventing
|
||||
* new frames to be added to the queue (while the hardware is
|
||||
* still allowed to run).
|
||||
*/
|
||||
void rt2x00queue_pause_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00queue_unpause_queue - unpause a data queue
|
||||
* @queue: Pointer to &struct data_queue.
|
||||
*
|
||||
* This function will unpause the data queue locally, allowing
|
||||
* new frames to be added to the queue again.
|
||||
*/
|
||||
void rt2x00queue_unpause_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00queue_start_queue - Start a data queue
|
||||
* @queue: Pointer to &struct data_queue.
|
||||
*
|
||||
* This function will start handling all pending frames in the queue.
|
||||
*/
|
||||
void rt2x00queue_start_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00queue_stop_queue - Halt a data queue
|
||||
* @queue: Pointer to &struct data_queue.
|
||||
*
|
||||
* This function will stop all pending frames in the queue.
|
||||
*/
|
||||
void rt2x00queue_stop_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00queue_flush_queue - Flush a data queue
|
||||
* @queue: Pointer to &struct data_queue.
|
||||
* @drop: True to drop all pending frames.
|
||||
*
|
||||
* This function will flush the queue. After this call
|
||||
* the queue is guarenteed to be empty.
|
||||
*/
|
||||
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop);
|
||||
|
||||
/**
|
||||
* rt2x00queue_start_queues - Start all data queues
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
*
|
||||
* This function will loop through all available queues to start them
|
||||
*/
|
||||
void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/**
|
||||
* rt2x00queue_stop_queues - Halt all data queues
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
*
|
||||
* This function will loop through all available queues to stop
|
||||
* any pending frames.
|
||||
*/
|
||||
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/**
|
||||
* rt2x00queue_flush_queues - Flush all data queues
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
* @drop: True to drop all pending frames.
|
||||
*
|
||||
* This function will loop through all available queues to flush
|
||||
* any pending frames.
|
||||
*/
|
||||
void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
|
||||
|
||||
/*
|
||||
* Debugfs handlers.
|
||||
*/
|
||||
|
@ -1093,6 +1171,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
|||
*/
|
||||
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2x00lib_dmastart(struct queue_entry *entry);
|
||||
void rt2x00lib_dmadone(struct queue_entry *entry);
|
||||
void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
struct txdone_entry_desc *txdesc);
|
||||
|
|
|
@ -146,8 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
|||
* else the changes will be ignored by the device.
|
||||
*/
|
||||
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
STATE_RADIO_RX_OFF);
|
||||
rt2x00queue_stop_queue(rt2x00dev->rx);
|
||||
|
||||
/*
|
||||
* Write new antenna setup to device and reset the link tuner.
|
||||
|
@ -161,8 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
|||
memcpy(active, &config, sizeof(config));
|
||||
|
||||
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev,
|
||||
STATE_RADIO_RX_ON);
|
||||
rt2x00queue_start_queue(rt2x00dev->rx);
|
||||
}
|
||||
|
||||
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
|
|
|
@ -339,12 +339,13 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
|
|||
return -ENOMEM;
|
||||
|
||||
temp = data +
|
||||
sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
|
||||
sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
|
||||
|
||||
queue_for_each(intf->rt2x00dev, queue) {
|
||||
spin_lock_irqsave(&queue->index_lock, irqflags);
|
||||
|
||||
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
|
||||
temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
|
||||
queue->qid, (unsigned int)queue->flags,
|
||||
queue->count, queue->limit, queue->length,
|
||||
queue->index[Q_INDEX],
|
||||
queue->index[Q_INDEX_DMA_DONE],
|
||||
|
|
|
@ -66,9 +66,9 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
|
|||
set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
|
||||
|
||||
/*
|
||||
* Enable RX.
|
||||
* Enable queues.
|
||||
*/
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
|
||||
rt2x00queue_start_queues(rt2x00dev);
|
||||
rt2x00link_start_tuner(rt2x00dev);
|
||||
|
||||
/*
|
||||
|
@ -76,11 +76,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
|
|||
*/
|
||||
rt2x00link_start_watchdog(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Start the TX queues.
|
||||
*/
|
||||
ieee80211_wake_queues(rt2x00dev->hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -89,22 +84,17 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
|
|||
if (!test_and_clear_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Stop the TX queues in mac80211.
|
||||
*/
|
||||
ieee80211_stop_queues(rt2x00dev->hw);
|
||||
rt2x00queue_stop_queues(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Stop watchdog monitoring.
|
||||
*/
|
||||
rt2x00link_stop_watchdog(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Disable RX.
|
||||
* Stop all queues
|
||||
*/
|
||||
rt2x00link_stop_tuner(rt2x00dev);
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
|
||||
rt2x00queue_stop_queues(rt2x00dev);
|
||||
rt2x00queue_flush_queues(rt2x00dev, true);
|
||||
|
||||
/*
|
||||
* Disable radio.
|
||||
|
@ -236,8 +226,16 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
|
||||
|
||||
void rt2x00lib_dmastart(struct queue_entry *entry)
|
||||
{
|
||||
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
|
||||
|
||||
void rt2x00lib_dmadone(struct queue_entry *entry)
|
||||
{
|
||||
set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
|
||||
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
|
||||
}
|
||||
|
@ -249,7 +247,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
|
|||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
|
||||
unsigned int header_length, i;
|
||||
u8 rate_idx, rate_flags, retry_rates;
|
||||
u8 skbdesc_flags = skbdesc->flags;
|
||||
|
@ -403,7 +400,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
|
|||
* is reenabled when the txdone handler has finished.
|
||||
*/
|
||||
if (!rt2x00queue_threshold(entry->queue))
|
||||
ieee80211_wake_queue(rt2x00dev->hw, qid);
|
||||
rt2x00queue_unpause_queue(entry->queue);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
|
||||
|
||||
|
@ -566,10 +563,8 @@ submit_entry:
|
|||
entry->flags = 0;
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
|
||||
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
|
||||
test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
|
||||
test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||
rt2x00dev->ops->lib->clear_entry(entry);
|
||||
rt2x00queue_index_inc(entry->queue, Q_INDEX);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
|
||||
|
||||
|
|
|
@ -177,15 +177,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
|
|||
*/
|
||||
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
|
||||
|
||||
/**
|
||||
* rt2x00queue_stop_queues - Halt all data queues
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
*
|
||||
* This function will loop through all available queues to stop
|
||||
* any pending outgoing frames.
|
||||
*/
|
||||
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
/**
|
||||
* rt2x00queue_init_queues - Initialize all data queues
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
|
|
|
@ -104,7 +104,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
enum data_queue_qid qid = skb_get_queue_mapping(skb);
|
||||
struct data_queue *queue;
|
||||
struct data_queue *queue = NULL;
|
||||
|
||||
/*
|
||||
* Mac80211 might be calling this function while we are trying
|
||||
|
@ -153,7 +153,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
goto exit_fail;
|
||||
|
||||
if (rt2x00queue_threshold(queue))
|
||||
ieee80211_stop_queue(rt2x00dev->hw, qid);
|
||||
rt2x00queue_pause_queue(queue);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
|
@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
|
|||
* if for any reason the link tuner must be reset, this will be
|
||||
* handled by rt2x00lib_config().
|
||||
*/
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
|
||||
rt2x00queue_stop_queue(rt2x00dev->rx);
|
||||
|
||||
/*
|
||||
* When we've just turned on the radio, we want to reprogram
|
||||
|
@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
|
|||
rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
|
||||
|
||||
/* Turn RX back on */
|
||||
rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
|
||||
rt2x00queue_start_queue(rt2x00dev->rx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -718,36 +718,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
|
|||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct data_queue *queue;
|
||||
unsigned int i = 0;
|
||||
|
||||
ieee80211_stop_queues(hw);
|
||||
|
||||
/*
|
||||
* Run over all queues to kick them, this will force
|
||||
* any pending frames to be transmitted.
|
||||
*/
|
||||
tx_queue_for_each(rt2x00dev, queue) {
|
||||
rt2x00dev->ops->lib->kick_tx_queue(queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* All queues have been kicked, now wait for each queue
|
||||
* to become empty. With a bit of luck, we only have to wait
|
||||
* for the first queue to become empty, because while waiting
|
||||
* for the that queue, the other queues will have transmitted
|
||||
* all their frames as well (since they were already kicked).
|
||||
*/
|
||||
tx_queue_for_each(rt2x00dev, queue) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (rt2x00queue_empty(queue))
|
||||
break;
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
if (!rt2x00queue_empty(queue))
|
||||
WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
|
||||
}
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
tx_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00queue_flush_queue(queue, drop);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_flush);
|
||||
|
|
|
@ -81,6 +81,13 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
|
|||
skbdesc->desc = entry_priv->desc;
|
||||
skbdesc->desc_len = entry->queue->desc_size;
|
||||
|
||||
/*
|
||||
* DMA is already done, notify rt2x00lib that
|
||||
* it finished successfully.
|
||||
*/
|
||||
rt2x00lib_dmastart(entry);
|
||||
rt2x00lib_dmadone(entry);
|
||||
|
||||
/*
|
||||
* Send the frame to rt2x00lib for further processing.
|
||||
*/
|
||||
|
|
|
@ -64,7 +64,7 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
|
|||
const void *value,
|
||||
const u32 length)
|
||||
{
|
||||
memcpy_toio(rt2x00dev->csr.base + offset, value, length);
|
||||
__iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -199,15 +199,18 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
|
|||
|
||||
void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
|
||||
{
|
||||
unsigned int l2pad = L2PAD_SIZE(header_length);
|
||||
/*
|
||||
* L2 padding is only present if the skb contains more than just the
|
||||
* IEEE 802.11 header.
|
||||
*/
|
||||
unsigned int l2pad = (skb->len > header_length) ?
|
||||
L2PAD_SIZE(header_length) : 0;
|
||||
|
||||
if (!l2pad)
|
||||
return;
|
||||
|
||||
memmove(skb->data + header_length, skb->data + header_length + l2pad,
|
||||
skb->len - header_length - l2pad);
|
||||
|
||||
skb_trim(skb, skb->len - l2pad);
|
||||
memmove(skb->data + l2pad, skb->data, header_length);
|
||||
skb_pull(skb, l2pad);
|
||||
}
|
||||
|
||||
static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
|
||||
|
@ -468,7 +471,7 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
|
|||
*/
|
||||
if (rt2x00queue_threshold(queue) ||
|
||||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
|
||||
queue->rt2x00dev->ops->lib->kick_tx_queue(queue);
|
||||
queue->rt2x00dev->ops->lib->kick_queue(queue);
|
||||
}
|
||||
|
||||
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
|
||||
|
@ -582,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
|
|||
rt2x00queue_free_skb(intf->beacon);
|
||||
|
||||
if (!enable_beacon) {
|
||||
rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
|
||||
rt2x00queue_stop_queue(intf->beacon->queue);
|
||||
mutex_unlock(&intf->beacon_skb_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
@ -735,6 +738,210 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
|
|||
spin_unlock_irqrestore(&queue->index_lock, irqflags);
|
||||
}
|
||||
|
||||
void rt2x00queue_pause_queue(struct data_queue *queue)
|
||||
{
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
|
||||
!test_bit(QUEUE_STARTED, &queue->flags) ||
|
||||
test_and_set_bit(QUEUE_PAUSED, &queue->flags))
|
||||
return;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
/*
|
||||
* For TX queues, we have to disable the queue
|
||||
* inside mac80211.
|
||||
*/
|
||||
ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
|
||||
|
||||
void rt2x00queue_unpause_queue(struct data_queue *queue)
|
||||
{
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
|
||||
!test_bit(QUEUE_STARTED, &queue->flags) ||
|
||||
!test_and_clear_bit(QUEUE_PAUSED, &queue->flags))
|
||||
return;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
/*
|
||||
* For TX queues, we have to enable the queue
|
||||
* inside mac80211.
|
||||
*/
|
||||
ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
|
||||
break;
|
||||
case QID_RX:
|
||||
/*
|
||||
* For RX we need to kick the queue now in order to
|
||||
* receive frames.
|
||||
*/
|
||||
queue->rt2x00dev->ops->lib->kick_queue(queue);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_unpause_queue);
|
||||
|
||||
void rt2x00queue_start_queue(struct data_queue *queue)
|
||||
{
|
||||
mutex_lock(&queue->status_lock);
|
||||
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
|
||||
test_and_set_bit(QUEUE_STARTED, &queue->flags)) {
|
||||
mutex_unlock(&queue->status_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
set_bit(QUEUE_PAUSED, &queue->flags);
|
||||
|
||||
queue->rt2x00dev->ops->lib->start_queue(queue);
|
||||
|
||||
rt2x00queue_unpause_queue(queue);
|
||||
|
||||
mutex_unlock(&queue->status_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_start_queue);
|
||||
|
||||
void rt2x00queue_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
mutex_lock(&queue->status_lock);
|
||||
|
||||
if (!test_and_clear_bit(QUEUE_STARTED, &queue->flags)) {
|
||||
mutex_unlock(&queue->status_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
rt2x00queue_pause_queue(queue);
|
||||
|
||||
queue->rt2x00dev->ops->lib->stop_queue(queue);
|
||||
|
||||
mutex_unlock(&queue->status_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
|
||||
|
||||
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
|
||||
{
|
||||
unsigned int i;
|
||||
bool started;
|
||||
bool tx_queue =
|
||||
(queue->qid == QID_AC_VO) ||
|
||||
(queue->qid == QID_AC_VI) ||
|
||||
(queue->qid == QID_AC_BE) ||
|
||||
(queue->qid == QID_AC_BK);
|
||||
|
||||
mutex_lock(&queue->status_lock);
|
||||
|
||||
/*
|
||||
* If the queue has been started, we must stop it temporarily
|
||||
* to prevent any new frames to be queued on the device. If
|
||||
* we are not dropping the pending frames, the queue must
|
||||
* only be stopped in the software and not the hardware,
|
||||
* otherwise the queue will never become empty on its own.
|
||||
*/
|
||||
started = test_bit(QUEUE_STARTED, &queue->flags);
|
||||
if (started) {
|
||||
/*
|
||||
* Pause the queue
|
||||
*/
|
||||
rt2x00queue_pause_queue(queue);
|
||||
|
||||
/*
|
||||
* If we are not supposed to drop any pending
|
||||
* frames, this means we must force a start (=kick)
|
||||
* to the queue to make sure the hardware will
|
||||
* start transmitting.
|
||||
*/
|
||||
if (!drop && tx_queue)
|
||||
queue->rt2x00dev->ops->lib->kick_queue(queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if driver supports flushing, we can only guarentee
|
||||
* full support for flushing if the driver is able
|
||||
* to cancel all pending frames (drop = true).
|
||||
*/
|
||||
if (drop && queue->rt2x00dev->ops->lib->flush_queue)
|
||||
queue->rt2x00dev->ops->lib->flush_queue(queue);
|
||||
|
||||
/*
|
||||
* When we don't want to drop any frames, or when
|
||||
* the driver doesn't fully flush the queue correcly,
|
||||
* we must wait for the queue to become empty.
|
||||
*/
|
||||
for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
|
||||
msleep(10);
|
||||
|
||||
/*
|
||||
* The queue flush has failed...
|
||||
*/
|
||||
if (unlikely(!rt2x00queue_empty(queue)))
|
||||
WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid);
|
||||
|
||||
/*
|
||||
* Restore the queue to the previous status
|
||||
*/
|
||||
if (started)
|
||||
rt2x00queue_unpause_queue(queue);
|
||||
|
||||
mutex_unlock(&queue->status_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
|
||||
|
||||
void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
/*
|
||||
* rt2x00queue_start_queue will call ieee80211_wake_queue
|
||||
* for each queue after is has been properly initialized.
|
||||
*/
|
||||
tx_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00queue_start_queue(queue);
|
||||
|
||||
rt2x00queue_start_queue(rt2x00dev->rx);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_start_queues);
|
||||
|
||||
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
/*
|
||||
* rt2x00queue_stop_queue will call ieee80211_stop_queue
|
||||
* as well, but we are completely shutting doing everything
|
||||
* now, so it is much safer to stop all TX queues at once,
|
||||
* and use rt2x00queue_stop_queue for cleaning up.
|
||||
*/
|
||||
ieee80211_stop_queues(rt2x00dev->hw);
|
||||
|
||||
tx_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00queue_stop_queue(queue);
|
||||
|
||||
rt2x00queue_stop_queue(rt2x00dev->rx);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues);
|
||||
|
||||
void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
tx_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00queue_flush_queue(queue, drop);
|
||||
|
||||
rt2x00queue_flush_queue(rt2x00dev->rx, drop);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues);
|
||||
|
||||
static void rt2x00queue_reset(struct data_queue *queue)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
@ -753,14 +960,6 @@ static void rt2x00queue_reset(struct data_queue *queue)
|
|||
spin_unlock_irqrestore(&queue->index_lock, irqflags);
|
||||
}
|
||||
|
||||
void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
txall_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00dev->ops->lib->kill_tx_queue(queue);
|
||||
}
|
||||
|
||||
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
@ -769,11 +968,8 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
|
|||
queue_for_each(rt2x00dev, queue) {
|
||||
rt2x00queue_reset(queue);
|
||||
|
||||
for (i = 0; i < queue->limit; i++) {
|
||||
for (i = 0; i < queue->limit; i++)
|
||||
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
|
||||
if (queue->qid == QID_RX)
|
||||
rt2x00queue_index_inc(queue, Q_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -902,6 +1098,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
|
|||
static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
|
||||
struct data_queue *queue, enum data_queue_qid qid)
|
||||
{
|
||||
mutex_init(&queue->status_lock);
|
||||
spin_lock_init(&queue->index_lock);
|
||||
|
||||
queue->rt2x00dev = rt2x00dev;
|
||||
|
@ -944,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Initialize queue parameters.
|
||||
* RX: qid = QID_RX
|
||||
* TX: qid = QID_AC_BE + index
|
||||
* TX: qid = QID_AC_VO + index
|
||||
* TX: cw_min: 2^5 = 32.
|
||||
* TX: cw_max: 2^10 = 1024.
|
||||
* BCN: qid = QID_BEACON
|
||||
|
@ -952,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
|
|||
*/
|
||||
rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
|
||||
|
||||
qid = QID_AC_BE;
|
||||
qid = QID_AC_VO;
|
||||
tx_queue_for_each(rt2x00dev, queue)
|
||||
rt2x00queue_init(rt2x00dev, queue, qid++);
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@
|
|||
/**
|
||||
* enum data_queue_qid: Queue identification
|
||||
*
|
||||
* @QID_AC_VO: AC VO queue
|
||||
* @QID_AC_VI: AC VI queue
|
||||
* @QID_AC_BE: AC BE queue
|
||||
* @QID_AC_BK: AC BK queue
|
||||
* @QID_AC_VI: AC VI queue
|
||||
* @QID_AC_VO: AC VO queue
|
||||
* @QID_HCCA: HCCA queue
|
||||
* @QID_MGMT: MGMT queue (prio queue)
|
||||
* @QID_RX: RX queue
|
||||
|
@ -57,10 +57,10 @@
|
|||
* @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
|
||||
*/
|
||||
enum data_queue_qid {
|
||||
QID_AC_BE = 0,
|
||||
QID_AC_BK = 1,
|
||||
QID_AC_VI = 2,
|
||||
QID_AC_VO = 3,
|
||||
QID_AC_VO = 0,
|
||||
QID_AC_VI = 1,
|
||||
QID_AC_BE = 2,
|
||||
QID_AC_BK = 3,
|
||||
QID_HCCA = 4,
|
||||
QID_MGMT = 13,
|
||||
QID_RX = 14,
|
||||
|
@ -340,12 +340,16 @@ struct txentry_desc {
|
|||
* @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
|
||||
* while transfering the data to the hardware. No TX status report will
|
||||
* be expected from the hardware.
|
||||
* @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
|
||||
* returned. It is now waiting for the status reporting before the
|
||||
* entry can be reused again.
|
||||
*/
|
||||
enum queue_entry_flags {
|
||||
ENTRY_BCN_ASSIGNED,
|
||||
ENTRY_OWNER_DEVICE_DATA,
|
||||
ENTRY_DATA_PENDING,
|
||||
ENTRY_DATA_IO_FAILED
|
||||
ENTRY_DATA_IO_FAILED,
|
||||
ENTRY_DATA_STATUS_PENDING,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -391,6 +395,23 @@ enum queue_index {
|
|||
Q_INDEX_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum data_queue_flags: Status flags for data queues
|
||||
*
|
||||
* @QUEUE_STARTED: The queue has been started. Fox RX queues this means the
|
||||
* device might be DMA'ing skbuffers. TX queues will accept skbuffers to
|
||||
* be transmitted and beacon queues will start beaconing the configured
|
||||
* beacons.
|
||||
* @QUEUE_PAUSED: The queue has been started but is currently paused.
|
||||
* When this bit is set, the queue has been stopped in mac80211,
|
||||
* preventing new frames to be enqueued. However, a few frames
|
||||
* might still appear shortly after the pausing...
|
||||
*/
|
||||
enum data_queue_flags {
|
||||
QUEUE_STARTED,
|
||||
QUEUE_PAUSED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct data_queue: Data queue
|
||||
*
|
||||
|
@ -398,6 +419,9 @@ enum queue_index {
|
|||
* @entries: Base address of the &struct queue_entry which are
|
||||
* part of this queue.
|
||||
* @qid: The queue identification, see &enum data_queue_qid.
|
||||
* @flags: Entry flags, see &enum queue_entry_flags.
|
||||
* @status_lock: The mutex for protecting the start/stop/flush
|
||||
* handling on this queue.
|
||||
* @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
|
||||
* @index_crypt needs to be changed this lock should be grabbed to prevent
|
||||
* index corruption due to concurrency.
|
||||
|
@ -421,8 +445,11 @@ struct data_queue {
|
|||
struct queue_entry *entries;
|
||||
|
||||
enum data_queue_qid qid;
|
||||
unsigned long flags;
|
||||
|
||||
struct mutex status_lock;
|
||||
spinlock_t index_lock;
|
||||
|
||||
unsigned int count;
|
||||
unsigned short limit;
|
||||
unsigned short threshold;
|
||||
|
|
|
@ -83,8 +83,6 @@ enum dev_state {
|
|||
*/
|
||||
STATE_RADIO_ON,
|
||||
STATE_RADIO_OFF,
|
||||
STATE_RADIO_RX_ON,
|
||||
STATE_RADIO_RX_OFF,
|
||||
STATE_RADIO_IRQ_ON,
|
||||
STATE_RADIO_IRQ_OFF,
|
||||
STATE_RADIO_IRQ_ON_ISR,
|
||||
|
|
|
@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work)
|
|||
while (!rt2x00queue_empty(queue)) {
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
|
||||
if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
||||
if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
|
||||
!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
break;
|
||||
|
||||
rt2x00usb_work_txdone_entry(entry);
|
||||
|
@ -235,8 +236,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
|||
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
u32 length;
|
||||
int status;
|
||||
|
||||
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
|
||||
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
|
||||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -251,106 +254,15 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
|||
entry->skb->data, length,
|
||||
rt2x00usb_interrupt_txdone, entry);
|
||||
|
||||
if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
|
||||
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
if (status == -ENODEV)
|
||||
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
||||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
rt2x00lib_dmadone(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void rt2x00usb_kick_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00usb_kick_tx_entry);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
|
||||
|
||||
static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
|
||||
|
||||
if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
||||
return;
|
||||
|
||||
usb_kill_urb(entry_priv->urb);
|
||||
|
||||
/*
|
||||
* Kill guardian urb (if required by driver).
|
||||
*/
|
||||
if ((entry->queue->qid == QID_BEACON) &&
|
||||
(test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
|
||||
usb_kill_urb(bcn_priv->guardian_urb);
|
||||
}
|
||||
|
||||
void rt2x00usb_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00usb_kill_tx_entry);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
|
||||
|
||||
static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
unsigned short threshold = queue->threshold;
|
||||
|
||||
WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
|
||||
" invoke forced forced reset", queue->qid);
|
||||
|
||||
/*
|
||||
* Temporarily disable the TX queue, this will force mac80211
|
||||
* to use the other queues until this queue has been restored.
|
||||
*
|
||||
* Set the queue threshold to the queue limit. This prevents the
|
||||
* queue from being enabled during the txdone handler.
|
||||
*/
|
||||
queue->threshold = queue->limit;
|
||||
ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
|
||||
|
||||
/*
|
||||
* Kill all entries in the queue, afterwards we need to
|
||||
* wait a bit for all URBs to be cancelled.
|
||||
*/
|
||||
rt2x00usb_kill_tx_queue(queue);
|
||||
|
||||
/*
|
||||
* In case that a driver has overriden the txdone_work
|
||||
* function, we invoke the TX done through there.
|
||||
*/
|
||||
rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
|
||||
|
||||
/*
|
||||
* The queue has been reset, and mac80211 is allowed to use the
|
||||
* queue again.
|
||||
*/
|
||||
queue->threshold = threshold;
|
||||
ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
|
||||
}
|
||||
|
||||
static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
|
||||
{
|
||||
WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
|
||||
" invoke forced tx handler", queue->qid);
|
||||
|
||||
ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
|
||||
}
|
||||
|
||||
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
tx_queue_for_each(rt2x00dev, queue) {
|
||||
if (!rt2x00queue_empty(queue)) {
|
||||
if (rt2x00queue_dma_timeout(queue))
|
||||
rt2x00usb_watchdog_tx_dma(queue);
|
||||
if (rt2x00queue_status_timeout(queue))
|
||||
rt2x00usb_watchdog_tx_status(queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
|
||||
|
||||
/*
|
||||
* RX data handlers.
|
||||
*/
|
||||
|
@ -365,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
|
|||
while (!rt2x00queue_empty(rt2x00dev->rx)) {
|
||||
entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
|
||||
|
||||
if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
||||
if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
|
||||
!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -410,6 +323,154 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
|
|||
ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
|
||||
}
|
||||
|
||||
static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
int status;
|
||||
|
||||
if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
|
||||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
return;
|
||||
|
||||
rt2x00lib_dmastart(entry);
|
||||
|
||||
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
|
||||
usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
|
||||
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
if (status == -ENODEV)
|
||||
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
||||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
rt2x00lib_dmadone(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void rt2x00usb_kick_queue(struct data_queue *queue)
|
||||
{
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
if (!rt2x00queue_empty(queue))
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00usb_kick_tx_entry);
|
||||
break;
|
||||
case QID_RX:
|
||||
if (!rt2x00queue_full(queue))
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00usb_kick_rx_entry);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
|
||||
|
||||
static void rt2x00usb_flush_entry(struct queue_entry *entry)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
|
||||
|
||||
if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
||||
return;
|
||||
|
||||
usb_kill_urb(entry_priv->urb);
|
||||
|
||||
/*
|
||||
* Kill guardian urb (if required by driver).
|
||||
*/
|
||||
if ((entry->queue->qid == QID_BEACON) &&
|
||||
(test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
|
||||
usb_kill_urb(bcn_priv->guardian_urb);
|
||||
}
|
||||
|
||||
void rt2x00usb_flush_queue(struct data_queue *queue)
|
||||
{
|
||||
struct work_struct *completion;
|
||||
unsigned int i;
|
||||
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00usb_flush_entry);
|
||||
|
||||
/*
|
||||
* Obtain the queue completion handler
|
||||
*/
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
case QID_AC_VI:
|
||||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
completion = &queue->rt2x00dev->txdone_work;
|
||||
break;
|
||||
case QID_RX:
|
||||
completion = &queue->rt2x00dev->rxdone_work;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
/*
|
||||
* Check if the driver is already done, otherwise we
|
||||
* have to sleep a little while to give the driver/hw
|
||||
* the oppurtunity to complete interrupt process itself.
|
||||
*/
|
||||
if (rt2x00queue_empty(queue))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Schedule the completion handler manually, when this
|
||||
* worker function runs, it should cleanup the queue.
|
||||
*/
|
||||
ieee80211_queue_work(queue->rt2x00dev->hw, completion);
|
||||
|
||||
/*
|
||||
* Wait for a little while to give the driver
|
||||
* the oppurtunity to recover itself.
|
||||
*/
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);
|
||||
|
||||
static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
|
||||
{
|
||||
WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
|
||||
" invoke forced forced reset\n", queue->qid);
|
||||
|
||||
rt2x00queue_flush_queue(queue, true);
|
||||
}
|
||||
|
||||
static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
|
||||
{
|
||||
WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
|
||||
" invoke forced tx handler\n", queue->qid);
|
||||
|
||||
ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
|
||||
}
|
||||
|
||||
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
tx_queue_for_each(rt2x00dev, queue) {
|
||||
if (!rt2x00queue_empty(queue)) {
|
||||
if (rt2x00queue_dma_timeout(queue))
|
||||
rt2x00usb_watchdog_tx_dma(queue);
|
||||
if (rt2x00queue_status_timeout(queue))
|
||||
rt2x00usb_watchdog_tx_status(queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
|
||||
|
||||
/*
|
||||
* Radio handlers
|
||||
*/
|
||||
|
@ -417,12 +478,6 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
|
|||
{
|
||||
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
|
||||
REGISTER_TIMEOUT);
|
||||
|
||||
/*
|
||||
* The USB version of kill_tx_queue also works
|
||||
* on the RX queue.
|
||||
*/
|
||||
rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
|
||||
|
||||
|
@ -431,25 +486,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
|
|||
*/
|
||||
void rt2x00usb_clear_entry(struct queue_entry *entry)
|
||||
{
|
||||
struct usb_device *usb_dev =
|
||||
to_usb_device_intf(entry->queue->rt2x00dev->dev);
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
int pipe;
|
||||
|
||||
entry->flags = 0;
|
||||
|
||||
if (entry->queue->qid == QID_RX) {
|
||||
pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
|
||||
usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
|
||||
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||
if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
|
||||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
rt2x00lib_dmadone(entry);
|
||||
}
|
||||
}
|
||||
if (entry->queue->qid == QID_RX)
|
||||
rt2x00usb_kick_rx_entry(entry);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
|
||||
|
||||
|
|
|
@ -378,22 +378,22 @@ struct queue_entry_priv_usb_bcn {
|
|||
};
|
||||
|
||||
/**
|
||||
* rt2x00usb_kick_tx_queue - Kick data queue
|
||||
* rt2x00usb_kick_queue - Kick data queue
|
||||
* @queue: Data queue to kick
|
||||
*
|
||||
* This will walk through all entries of the queue and push all pending
|
||||
* frames to the hardware as a single burst.
|
||||
*/
|
||||
void rt2x00usb_kick_tx_queue(struct data_queue *queue);
|
||||
void rt2x00usb_kick_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00usb_kill_tx_queue - Kill data queue
|
||||
* @queue: Data queue to kill
|
||||
* rt2x00usb_flush_queue - Flush data queue
|
||||
* @queue: Data queue to stop
|
||||
*
|
||||
* This will walk through all entries of the queue and kill all
|
||||
* previously kicked frames before they can be send.
|
||||
* URB's which were send to the device.
|
||||
*/
|
||||
void rt2x00usb_kill_tx_queue(struct data_queue *queue);
|
||||
void rt2x00usb_flush_queue(struct data_queue *queue);
|
||||
|
||||
/**
|
||||
* rt2x00usb_watchdog - Watchdog for USB communication
|
||||
|
|
|
@ -1139,6 +1139,106 @@ dynamic_cca_tune:
|
|||
rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt61pci_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt61pci_kick_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_VI:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_BE:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_BK:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt61pci_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_VI:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_BE:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_AC_BK:
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
break;
|
||||
case QID_RX:
|
||||
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware functions
|
||||
*/
|
||||
|
@ -1616,17 +1716,6 @@ static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX,
|
||||
(state == STATE_RADIO_RX_OFF));
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
}
|
||||
|
||||
static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
|
@ -1743,10 +1832,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
case STATE_RADIO_OFF:
|
||||
rt61pci_disable_radio(rt2x00dev);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt61pci_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -1876,6 +1961,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
|
|||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||
unsigned int beacon_base;
|
||||
unsigned int padding_len;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
|
@ -1897,13 +1983,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
|
|||
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
|
||||
/*
|
||||
* Write entire beacon with descriptor to register.
|
||||
* Write entire beacon with descriptor and padding to register.
|
||||
*/
|
||||
padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
|
||||
skb_pad(entry->skb, padding_len);
|
||||
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
|
||||
rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
|
||||
entry_priv->desc, TXINFO_SIZE);
|
||||
rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
|
||||
entry->skb->data, entry->skb->len);
|
||||
entry->skb->data,
|
||||
entry->skb->len + padding_len);
|
||||
|
||||
/*
|
||||
* Enable beaconing again.
|
||||
|
@ -1925,37 +2014,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
|
|||
entry->skb = NULL;
|
||||
}
|
||||
|
||||
static void rt61pci_kick_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
}
|
||||
|
||||
static void rt61pci_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
if (queue->qid == QID_BEACON) {
|
||||
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®);
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI));
|
||||
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));
|
||||
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -2840,10 +2898,11 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
|
|||
.link_stats = rt61pci_link_stats,
|
||||
.reset_tuner = rt61pci_reset_tuner,
|
||||
.link_tuner = rt61pci_link_tuner,
|
||||
.start_queue = rt61pci_start_queue,
|
||||
.kick_queue = rt61pci_kick_queue,
|
||||
.stop_queue = rt61pci_stop_queue,
|
||||
.write_tx_desc = rt61pci_write_tx_desc,
|
||||
.write_beacon = rt61pci_write_beacon,
|
||||
.kick_tx_queue = rt61pci_kick_tx_queue,
|
||||
.kill_tx_queue = rt61pci_kill_tx_queue,
|
||||
.fill_rxdone = rt61pci_fill_rxdone,
|
||||
.config_shared_key = rt61pci_config_shared_key,
|
||||
.config_pairwise_key = rt61pci_config_pairwise_key,
|
||||
|
|
|
@ -784,25 +784,25 @@ struct hw_pairwise_ta_entry {
|
|||
*/
|
||||
|
||||
/*
|
||||
* AC0_BASE_CSR: AC_BK base address.
|
||||
* AC0_BASE_CSR: AC_VO base address.
|
||||
*/
|
||||
#define AC0_BASE_CSR 0x3400
|
||||
#define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
|
||||
|
||||
/*
|
||||
* AC1_BASE_CSR: AC_BE base address.
|
||||
* AC1_BASE_CSR: AC_VI base address.
|
||||
*/
|
||||
#define AC1_BASE_CSR 0x3404
|
||||
#define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
|
||||
|
||||
/*
|
||||
* AC2_BASE_CSR: AC_VI base address.
|
||||
* AC2_BASE_CSR: AC_BE base address.
|
||||
*/
|
||||
#define AC2_BASE_CSR 0x3408
|
||||
#define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
|
||||
|
||||
/*
|
||||
* AC3_BASE_CSR: AC_VO base address.
|
||||
* AC3_BASE_CSR: AC_BK base address.
|
||||
*/
|
||||
#define AC3_BASE_CSR 0x340c
|
||||
#define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
|
||||
|
@ -814,7 +814,7 @@ struct hw_pairwise_ta_entry {
|
|||
#define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
|
||||
|
||||
/*
|
||||
* TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO.
|
||||
* TX_RING_CSR0: TX Ring size for AC_VO, AC_VI, AC_BE, AC_BK.
|
||||
*/
|
||||
#define TX_RING_CSR0 0x3418
|
||||
#define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff)
|
||||
|
@ -833,10 +833,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* AIFSN_CSR: AIFSN for each EDCA AC.
|
||||
* AIFSN0: For AC_BK.
|
||||
* AIFSN1: For AC_BE.
|
||||
* AIFSN2: For AC_VI.
|
||||
* AIFSN3: For AC_VO.
|
||||
* AIFSN0: For AC_VO.
|
||||
* AIFSN1: For AC_VI.
|
||||
* AIFSN2: For AC_BE.
|
||||
* AIFSN3: For AC_BK.
|
||||
*/
|
||||
#define AIFSN_CSR 0x3420
|
||||
#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
|
||||
|
@ -846,10 +846,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* CWMIN_CSR: CWmin for each EDCA AC.
|
||||
* CWMIN0: For AC_BK.
|
||||
* CWMIN1: For AC_BE.
|
||||
* CWMIN2: For AC_VI.
|
||||
* CWMIN3: For AC_VO.
|
||||
* CWMIN0: For AC_VO.
|
||||
* CWMIN1: For AC_VI.
|
||||
* CWMIN2: For AC_BE.
|
||||
* CWMIN3: For AC_BK.
|
||||
*/
|
||||
#define CWMIN_CSR 0x3424
|
||||
#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
|
||||
|
@ -859,10 +859,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* CWMAX_CSR: CWmax for each EDCA AC.
|
||||
* CWMAX0: For AC_BK.
|
||||
* CWMAX1: For AC_BE.
|
||||
* CWMAX2: For AC_VI.
|
||||
* CWMAX3: For AC_VO.
|
||||
* CWMAX0: For AC_VO.
|
||||
* CWMAX1: For AC_VI.
|
||||
* CWMAX2: For AC_BE.
|
||||
* CWMAX3: For AC_BK.
|
||||
*/
|
||||
#define CWMAX_CSR 0x3428
|
||||
#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
|
||||
|
@ -883,14 +883,14 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* TX_CNTL_CSR: KICK/Abort TX.
|
||||
* KICK_TX_AC0: For AC_BK.
|
||||
* KICK_TX_AC1: For AC_BE.
|
||||
* KICK_TX_AC2: For AC_VI.
|
||||
* KICK_TX_AC3: For AC_VO.
|
||||
* ABORT_TX_AC0: For AC_BK.
|
||||
* ABORT_TX_AC1: For AC_BE.
|
||||
* ABORT_TX_AC2: For AC_VI.
|
||||
* ABORT_TX_AC3: For AC_VO.
|
||||
* KICK_TX_AC0: For AC_VO.
|
||||
* KICK_TX_AC1: For AC_VI.
|
||||
* KICK_TX_AC2: For AC_BE.
|
||||
* KICK_TX_AC3: For AC_BK.
|
||||
* ABORT_TX_AC0: For AC_VO.
|
||||
* ABORT_TX_AC1: For AC_VI.
|
||||
* ABORT_TX_AC2: For AC_BE.
|
||||
* ABORT_TX_AC3: For AC_BK.
|
||||
*/
|
||||
#define TX_CNTL_CSR 0x3430
|
||||
#define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001)
|
||||
|
@ -1010,18 +1010,18 @@ struct hw_pairwise_ta_entry {
|
|||
#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
|
||||
|
||||
/*
|
||||
* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
|
||||
* AC0_TX_OP: For AC_BK, in unit of 32us.
|
||||
* AC1_TX_OP: For AC_BE, in unit of 32us.
|
||||
* AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
|
||||
* AC0_TX_OP: For AC_VO, in unit of 32us.
|
||||
* AC1_TX_OP: For AC_VI, in unit of 32us.
|
||||
*/
|
||||
#define AC_TXOP_CSR0 0x3474
|
||||
#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
|
||||
#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
|
||||
* AC2_TX_OP: For AC_VI, in unit of 32us.
|
||||
* AC3_TX_OP: For AC_VO, in unit of 32us.
|
||||
* AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
|
||||
* AC2_TX_OP: For AC_BE, in unit of 32us.
|
||||
* AC3_TX_OP: For AC_BK, in unit of 32us.
|
||||
*/
|
||||
#define AC_TXOP_CSR1 0x3478
|
||||
#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
|
||||
|
|
|
@ -1030,6 +1030,55 @@ dynamic_cca_tune:
|
|||
max_t(u8, qual->vgc_level - 4, low_bound));
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
static void rt73usb_start_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0);
|
||||
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
|
||||
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rt73usb_stop_queue(struct data_queue *queue)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
|
||||
u32 reg;
|
||||
|
||||
switch (queue->qid) {
|
||||
case QID_RX:
|
||||
rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1);
|
||||
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
break;
|
||||
case QID_BEACON:
|
||||
rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
|
||||
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
|
||||
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware functions
|
||||
*/
|
||||
|
@ -1324,17 +1373,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|||
/*
|
||||
* Device state switch handlers.
|
||||
*/
|
||||
static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
||||
enum dev_state state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX,
|
||||
(state == STATE_RADIO_RX_OFF));
|
||||
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
}
|
||||
|
||||
static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
/*
|
||||
|
@ -1401,10 +1439,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|||
case STATE_RADIO_OFF:
|
||||
rt73usb_disable_radio(rt2x00dev);
|
||||
break;
|
||||
case STATE_RADIO_RX_ON:
|
||||
case STATE_RADIO_RX_OFF:
|
||||
rt73usb_toggle_rx(rt2x00dev, state);
|
||||
break;
|
||||
case STATE_RADIO_IRQ_ON:
|
||||
case STATE_RADIO_IRQ_ON_ISR:
|
||||
case STATE_RADIO_IRQ_OFF:
|
||||
|
@ -1512,6 +1546,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
|
|||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
unsigned int beacon_base;
|
||||
unsigned int padding_len;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
|
@ -1539,11 +1574,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
|
|||
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
|
||||
/*
|
||||
* Write entire beacon with descriptor to register.
|
||||
* Write entire beacon with descriptor and padding to register.
|
||||
*/
|
||||
padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
|
||||
skb_pad(entry->skb, padding_len);
|
||||
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
|
||||
rt2x00usb_register_multiwrite(rt2x00dev, beacon_base,
|
||||
entry->skb->data, entry->skb->len);
|
||||
rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
|
||||
entry->skb->len + padding_len);
|
||||
|
||||
/*
|
||||
* Enable beaconing again.
|
||||
|
@ -1579,14 +1616,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
|
|||
return length;
|
||||
}
|
||||
|
||||
static void rt73usb_kill_tx_queue(struct data_queue *queue)
|
||||
{
|
||||
if (queue->qid == QID_BEACON)
|
||||
rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
|
||||
|
||||
rt2x00usb_kill_tx_queue(queue);
|
||||
}
|
||||
|
||||
/*
|
||||
* RX control handlers
|
||||
*/
|
||||
|
@ -2278,11 +2307,13 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
|||
.reset_tuner = rt73usb_reset_tuner,
|
||||
.link_tuner = rt73usb_link_tuner,
|
||||
.watchdog = rt2x00usb_watchdog,
|
||||
.start_queue = rt73usb_start_queue,
|
||||
.kick_queue = rt2x00usb_kick_queue,
|
||||
.stop_queue = rt73usb_stop_queue,
|
||||
.flush_queue = rt2x00usb_flush_queue,
|
||||
.write_tx_desc = rt73usb_write_tx_desc,
|
||||
.write_beacon = rt73usb_write_beacon,
|
||||
.get_tx_data_len = rt73usb_get_tx_data_len,
|
||||
.kick_tx_queue = rt2x00usb_kick_tx_queue,
|
||||
.kill_tx_queue = rt73usb_kill_tx_queue,
|
||||
.fill_rxdone = rt73usb_fill_rxdone,
|
||||
.config_shared_key = rt73usb_config_shared_key,
|
||||
.config_pairwise_key = rt73usb_config_pairwise_key,
|
||||
|
|
|
@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* AIFSN_CSR: AIFSN for each EDCA AC.
|
||||
* AIFSN0: For AC_BK.
|
||||
* AIFSN1: For AC_BE.
|
||||
* AIFSN2: For AC_VI.
|
||||
* AIFSN3: For AC_VO.
|
||||
* AIFSN0: For AC_VO.
|
||||
* AIFSN1: For AC_VI.
|
||||
* AIFSN2: For AC_BE.
|
||||
* AIFSN3: For AC_BK.
|
||||
*/
|
||||
#define AIFSN_CSR 0x0400
|
||||
#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
|
||||
|
@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* CWMIN_CSR: CWmin for each EDCA AC.
|
||||
* CWMIN0: For AC_BK.
|
||||
* CWMIN1: For AC_BE.
|
||||
* CWMIN2: For AC_VI.
|
||||
* CWMIN3: For AC_VO.
|
||||
* CWMIN0: For AC_VO.
|
||||
* CWMIN1: For AC_VI.
|
||||
* CWMIN2: For AC_BE.
|
||||
* CWMIN3: For AC_BK.
|
||||
*/
|
||||
#define CWMIN_CSR 0x0404
|
||||
#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
|
||||
|
@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry {
|
|||
|
||||
/*
|
||||
* CWMAX_CSR: CWmax for each EDCA AC.
|
||||
* CWMAX0: For AC_BK.
|
||||
* CWMAX1: For AC_BE.
|
||||
* CWMAX2: For AC_VI.
|
||||
* CWMAX3: For AC_VO.
|
||||
* CWMAX0: For AC_VO.
|
||||
* CWMAX1: For AC_VI.
|
||||
* CWMAX2: For AC_BE.
|
||||
* CWMAX3: For AC_BK.
|
||||
*/
|
||||
#define CWMAX_CSR 0x0408
|
||||
#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
|
||||
|
@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry {
|
|||
#define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000)
|
||||
|
||||
/*
|
||||
* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register.
|
||||
* AC0_TX_OP: For AC_BK, in unit of 32us.
|
||||
* AC1_TX_OP: For AC_BE, in unit of 32us.
|
||||
* AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
|
||||
* AC0_TX_OP: For AC_VO, in unit of 32us.
|
||||
* AC1_TX_OP: For AC_VI, in unit of 32us.
|
||||
*/
|
||||
#define AC_TXOP_CSR0 0x040c
|
||||
#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
|
||||
#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register.
|
||||
* AC2_TX_OP: For AC_VI, in unit of 32us.
|
||||
* AC3_TX_OP: For AC_VO, in unit of 32us.
|
||||
* AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
|
||||
* AC2_TX_OP: For AC_BE, in unit of 32us.
|
||||
* AC3_TX_OP: For AC_BK, in unit of 32us.
|
||||
*/
|
||||
#define AC_TXOP_CSR1 0x0410
|
||||
#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
config RTL8192CE
|
||||
tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
|
||||
depends on MAC80211 && EXPERIMENTAL
|
||||
select FW_LOADER
|
||||
select RTLWIFI
|
||||
---help---
|
||||
This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
|
||||
wireless network adapters.
|
||||
|
||||
If you choose to build it as a module, it will be called rtl8192ce
|
||||
|
||||
config RTLWIFI
|
||||
tristate
|
||||
depends on RTL8192CE
|
||||
default m
|
|
@ -0,0 +1,13 @@
|
|||
obj-$(CONFIG_RTLWIFI) += rtlwifi.o
|
||||
rtlwifi-objs := \
|
||||
base.o \
|
||||
cam.o \
|
||||
core.o \
|
||||
debug.o \
|
||||
efuse.o \
|
||||
pci.o \
|
||||
ps.o \
|
||||
rc.o \
|
||||
regd.o
|
||||
|
||||
obj-$(CONFIG_RTL8192CE) += rtl8192ce/
|
|
@ -0,0 +1,958 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/ip.h>
|
||||
#include "wifi.h"
|
||||
#include "rc.h"
|
||||
#include "base.h"
|
||||
#include "efuse.h"
|
||||
#include "cam.h"
|
||||
#include "ps.h"
|
||||
#include "regd.h"
|
||||
|
||||
/*
|
||||
*NOTICE!!!: This file will be very big, we hsould
|
||||
*keep it clear under follwing roles:
|
||||
*
|
||||
*This file include follwing part, so, if you add new
|
||||
*functions into this file, please check which part it
|
||||
*should includes. or check if you should add new part
|
||||
*for this file:
|
||||
*
|
||||
*1) mac80211 init functions
|
||||
*2) tx information functions
|
||||
*3) functions called by core.c
|
||||
*4) wq & timer callback functions
|
||||
*5) frame process functions
|
||||
*6) sysfs functions
|
||||
*7) ...
|
||||
*/
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* mac80211 init functions
|
||||
*
|
||||
*********************************************************/
|
||||
static struct ieee80211_channel rtl_channeltable[] = {
|
||||
{.center_freq = 2412, .hw_value = 1,},
|
||||
{.center_freq = 2417, .hw_value = 2,},
|
||||
{.center_freq = 2422, .hw_value = 3,},
|
||||
{.center_freq = 2427, .hw_value = 4,},
|
||||
{.center_freq = 2432, .hw_value = 5,},
|
||||
{.center_freq = 2437, .hw_value = 6,},
|
||||
{.center_freq = 2442, .hw_value = 7,},
|
||||
{.center_freq = 2447, .hw_value = 8,},
|
||||
{.center_freq = 2452, .hw_value = 9,},
|
||||
{.center_freq = 2457, .hw_value = 10,},
|
||||
{.center_freq = 2462, .hw_value = 11,},
|
||||
{.center_freq = 2467, .hw_value = 12,},
|
||||
{.center_freq = 2472, .hw_value = 13,},
|
||||
{.center_freq = 2484, .hw_value = 14,},
|
||||
};
|
||||
|
||||
static struct ieee80211_rate rtl_ratetable[] = {
|
||||
{.bitrate = 10, .hw_value = 0x00,},
|
||||
{.bitrate = 20, .hw_value = 0x01,},
|
||||
{.bitrate = 55, .hw_value = 0x02,},
|
||||
{.bitrate = 110, .hw_value = 0x03,},
|
||||
{.bitrate = 60, .hw_value = 0x04,},
|
||||
{.bitrate = 90, .hw_value = 0x05,},
|
||||
{.bitrate = 120, .hw_value = 0x06,},
|
||||
{.bitrate = 180, .hw_value = 0x07,},
|
||||
{.bitrate = 240, .hw_value = 0x08,},
|
||||
{.bitrate = 360, .hw_value = 0x09,},
|
||||
{.bitrate = 480, .hw_value = 0x0a,},
|
||||
{.bitrate = 540, .hw_value = 0x0b,},
|
||||
};
|
||||
|
||||
static const struct ieee80211_supported_band rtl_band_2ghz = {
|
||||
.band = IEEE80211_BAND_2GHZ,
|
||||
|
||||
.channels = rtl_channeltable,
|
||||
.n_channels = ARRAY_SIZE(rtl_channeltable),
|
||||
|
||||
.bitrates = rtl_ratetable,
|
||||
.n_bitrates = ARRAY_SIZE(rtl_ratetable),
|
||||
|
||||
.ht_cap = {0},
|
||||
};
|
||||
|
||||
static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta_ht_cap *ht_cap)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
|
||||
ht_cap->ht_supported = true;
|
||||
ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
|
||||
IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_SGI_20 |
|
||||
IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
/*
|
||||
*Maximum length of AMPDU that the STA can receive.
|
||||
*Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
|
||||
*/
|
||||
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
|
||||
/*Minimum MPDU start spacing , */
|
||||
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
|
||||
|
||||
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
|
||||
|
||||
/*
|
||||
*hw->wiphy->bands[IEEE80211_BAND_2GHZ]
|
||||
*base on ant_num
|
||||
*rx_mask: RX mask
|
||||
*if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
|
||||
*if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
|
||||
*if rx_ant >=3 rx_mask[2]=0xff;
|
||||
*if BW_40 rx_mask[4]=0x01;
|
||||
*highest supported RX rate
|
||||
*/
|
||||
if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
|
||||
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
|
||||
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
|
||||
} else if (get_rf_type(rtlphy) == RF_1T1R) {
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
|
||||
|
||||
ht_cap->mcs.rx_mask[0] = 0xFF;
|
||||
ht_cap->mcs.rx_mask[1] = 0x00;
|
||||
ht_cap->mcs.rx_mask[4] = 0x01;
|
||||
|
||||
ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
/* <1> use mac->bands as mem for hw->wiphy->bands */
|
||||
sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
|
||||
|
||||
/*
|
||||
* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
|
||||
* to default value(1T1R)
|
||||
*/
|
||||
memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
|
||||
sizeof(struct ieee80211_supported_band));
|
||||
|
||||
/* <3> init ht cap base on ant_num */
|
||||
_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
|
||||
|
||||
/* <4> set mac->sband to wiphy->sband */
|
||||
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
|
||||
|
||||
/* <5> set hw caps */
|
||||
hw->flags = IEEE80211_HW_SIGNAL_DBM |
|
||||
IEEE80211_HW_RX_INCLUDES_FCS |
|
||||
IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
|
||||
/*IEEE80211_HW_SUPPORTS_PS | */
|
||||
/*IEEE80211_HW_PS_NULLFUNC_STACK | */
|
||||
/*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
|
||||
IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
|
||||
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->rts_threshold = 2347;
|
||||
|
||||
hw->queues = AC_MAX;
|
||||
hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
|
||||
|
||||
/* TODO: Correct this value for our hw */
|
||||
/* TODO: define these hard code value */
|
||||
hw->channel_change_time = 100;
|
||||
hw->max_listen_interval = 5;
|
||||
hw->max_rate_tries = 4;
|
||||
/* hw->max_rates = 1; */
|
||||
|
||||
/* <6> mac address */
|
||||
if (is_valid_ether_addr(rtlefuse->dev_addr)) {
|
||||
SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
|
||||
} else {
|
||||
u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
|
||||
get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
|
||||
SET_IEEE80211_PERM_ADDR(hw, rtlmac);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
/* <1> timer */
|
||||
init_timer(&rtlpriv->works.watchdog_timer);
|
||||
setup_timer(&rtlpriv->works.watchdog_timer,
|
||||
rtl_watch_dog_timer_callback, (unsigned long)hw);
|
||||
|
||||
/* <2> work queue */
|
||||
rtlpriv->works.hw = hw;
|
||||
rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
|
||||
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
|
||||
(void *)rtl_watchdog_wq_callback);
|
||||
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
|
||||
(void *)rtl_ips_nic_off_wq_callback);
|
||||
|
||||
}
|
||||
|
||||
void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
del_timer_sync(&rtlpriv->works.watchdog_timer);
|
||||
|
||||
cancel_delayed_work(&rtlpriv->works.watchdog_wq);
|
||||
cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
|
||||
}
|
||||
|
||||
void rtl_init_rfkill(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
bool radio_state;
|
||||
bool blocked;
|
||||
u8 valid = 0;
|
||||
|
||||
/*set init state to rf on */
|
||||
rtlpriv->rfkill.rfkill_state = 1;
|
||||
|
||||
radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
|
||||
|
||||
if (valid) {
|
||||
RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
|
||||
(KERN_INFO "wireless switch is %s\n",
|
||||
rtlpriv->rfkill.rfkill_state ? "on" : "off"));
|
||||
|
||||
rtlpriv->rfkill.rfkill_state = radio_state;
|
||||
|
||||
blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
|
||||
wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
|
||||
}
|
||||
|
||||
wiphy_rfkill_start_polling(hw->wiphy);
|
||||
}
|
||||
|
||||
void rtl_deinit_rfkill(struct ieee80211_hw *hw)
|
||||
{
|
||||
wiphy_rfkill_stop_polling(hw->wiphy);
|
||||
}
|
||||
|
||||
int rtl_init_core(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
/* <1> init mac80211 */
|
||||
_rtl_init_mac80211(hw);
|
||||
rtlmac->hw = hw;
|
||||
|
||||
/* <2> rate control register */
|
||||
if (rtl_rate_control_register()) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("rtl: Unable to register rtl_rc,"
|
||||
"use default RC !!\n"));
|
||||
} else {
|
||||
hw->rate_control_algorithm = "rtl_rc";
|
||||
}
|
||||
|
||||
/*
|
||||
* <3> init CRDA must come after init
|
||||
* mac80211 hw in _rtl_init_mac80211.
|
||||
*/
|
||||
if (rtl_regd_init(hw, rtl_reg_notifier)) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
|
||||
return 1;
|
||||
} else {
|
||||
/* CRDA regd hint must after init CRDA */
|
||||
if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("regulatory_hint fail\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* <4> locks */
|
||||
mutex_init(&rtlpriv->locks.conf_mutex);
|
||||
spin_lock_init(&rtlpriv->locks.ips_lock);
|
||||
spin_lock_init(&rtlpriv->locks.irq_th_lock);
|
||||
spin_lock_init(&rtlpriv->locks.h2c_lock);
|
||||
spin_lock_init(&rtlpriv->locks.rf_ps_lock);
|
||||
spin_lock_init(&rtlpriv->locks.rf_lock);
|
||||
spin_lock_init(&rtlpriv->locks.lps_lock);
|
||||
|
||||
rtlmac->link_state = MAC80211_NOLINK;
|
||||
|
||||
/* <5> init deferred work */
|
||||
_rtl_init_deferred_work(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtl_deinit_core(struct ieee80211_hw *hw)
|
||||
{
|
||||
/*RC*/
|
||||
rtl_rate_control_unregister();
|
||||
}
|
||||
|
||||
void rtl_init_rx_config(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
|
||||
(u8 *) (&mac->rx_mgt_filter));
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
|
||||
(u8 *) (&mac->rx_ctrl_filter));
|
||||
rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
|
||||
(u8 *) (&mac->rx_data_filter));
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* tx information functions
|
||||
*
|
||||
*********************************************************/
|
||||
static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
tcb_desc->use_shortpreamble = false;
|
||||
|
||||
/* 1M can only use Long Preamble. 11B spec */
|
||||
if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
|
||||
return;
|
||||
else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
tcb_desc->use_shortpreamble = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void _rtl_query_shortgi(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
tcb_desc->use_shortgi = false;
|
||||
|
||||
if (!mac->ht_enable)
|
||||
return;
|
||||
|
||||
if (!mac->sgi_40 && !mac->sgi_20)
|
||||
return;
|
||||
|
||||
if ((mac->bw_40 == true) && mac->sgi_40)
|
||||
tcb_desc->use_shortgi = true;
|
||||
else if ((mac->bw_40 == false) && mac->sgi_20)
|
||||
tcb_desc->use_shortgi = true;
|
||||
|
||||
if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
|
||||
tcb_desc->use_shortgi = false;
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 rate_flag = info->control.rates[0].flags;
|
||||
|
||||
/* Common Settings */
|
||||
tcb_desc->b_rts_stbc = false;
|
||||
tcb_desc->b_cts_enable = false;
|
||||
tcb_desc->rts_sc = 0;
|
||||
tcb_desc->b_rts_bw = false;
|
||||
tcb_desc->b_rts_use_shortpreamble = false;
|
||||
tcb_desc->b_rts_use_shortgi = false;
|
||||
|
||||
if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
/* Use CTS-to-SELF in protection mode. */
|
||||
tcb_desc->b_rts_enable = true;
|
||||
tcb_desc->b_cts_enable = true;
|
||||
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
|
||||
} else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
/* Use RTS-CTS in protection mode. */
|
||||
tcb_desc->b_rts_enable = true;
|
||||
tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
|
||||
if (mac->opmode == NL80211_IFTYPE_STATION)
|
||||
tcb_desc->ratr_index = 0;
|
||||
else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
|
||||
if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
|
||||
tcb_desc->use_driver_rate = 1;
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rtlpriv->dm.b_useramask) {
|
||||
/* TODO we will differentiate adhoc and station futrue */
|
||||
tcb_desc->mac_id = 0;
|
||||
|
||||
if ((mac->mode == WIRELESS_MODE_N_24G) ||
|
||||
(mac->mode == WIRELESS_MODE_N_5G)) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
|
||||
} else if (mac->mode & WIRELESS_MODE_G) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
|
||||
} else if (mac->mode & WIRELESS_MODE_B) {
|
||||
tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
|
||||
struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
tcb_desc->b_packet_bw = false;
|
||||
|
||||
if (!mac->bw_40 || !mac->ht_enable)
|
||||
return;
|
||||
|
||||
if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
|
||||
return;
|
||||
|
||||
/*use legency rate, shall use 20MHz */
|
||||
if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
|
||||
return;
|
||||
|
||||
tcb_desc->b_packet_bw = true;
|
||||
}
|
||||
|
||||
static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
u8 hw_rate;
|
||||
|
||||
if (get_rf_type(rtlphy) == RF_2T2R)
|
||||
hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
|
||||
else
|
||||
hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
|
||||
|
||||
return hw_rate;
|
||||
}
|
||||
|
||||
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct ieee80211_rate *txrate;
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
|
||||
|
||||
if (ieee80211_is_data(fc)) {
|
||||
txrate = ieee80211_get_tx_rate(hw, info);
|
||||
tcb_desc->hw_rate = txrate->hw_value;
|
||||
|
||||
/*
|
||||
*we set data rate RTL_RC_CCK_RATE1M
|
||||
*in rtl_rc.c if skb is special data or
|
||||
*mgt which need low data rate.
|
||||
*/
|
||||
|
||||
/*
|
||||
*So tcb_desc->hw_rate is just used for
|
||||
*special data and mgt frames
|
||||
*/
|
||||
if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
|
||||
tcb_desc->use_driver_rate = true;
|
||||
tcb_desc->ratr_index = 7;
|
||||
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
|
||||
tcb_desc->disable_ratefallback = 1;
|
||||
} else {
|
||||
/*
|
||||
*because hw will nerver use hw_rate
|
||||
*when tcb_desc->use_driver_rate = false
|
||||
*so we never set highest N rate here,
|
||||
*and N rate will all be controled by FW
|
||||
*when tcb_desc->use_driver_rate = false
|
||||
*/
|
||||
if (rtlmac->ht_enable) {
|
||||
tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
|
||||
} else {
|
||||
if (rtlmac->mode == WIRELESS_MODE_B) {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
|
||||
} else {
|
||||
tcb_desc->hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
tcb_desc->b_multicast = 1;
|
||||
else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
tcb_desc->b_broadcast = 1;
|
||||
|
||||
_rtl_txrate_selectmode(hw, tcb_desc);
|
||||
_rtl_query_bandwidth_mode(hw, tcb_desc);
|
||||
_rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
|
||||
_rtl_query_shortgi(hw, tcb_desc, info);
|
||||
_rtl_query_protection_mode(hw, tcb_desc, info);
|
||||
} else {
|
||||
tcb_desc->use_driver_rate = true;
|
||||
tcb_desc->ratr_index = 7;
|
||||
tcb_desc->disable_ratefallback = 1;
|
||||
tcb_desc->mac_id = 0;
|
||||
|
||||
tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_get_tcb_desc);
|
||||
|
||||
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
if (ieee80211_is_auth(fc)) {
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
|
||||
rtl_ips_nic_on(hw);
|
||||
|
||||
mac->link_state = MAC80211_LINKING;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
|
||||
{
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
|
||||
u8 category;
|
||||
|
||||
if (!ieee80211_is_action(fc))
|
||||
return true;
|
||||
|
||||
category = *act;
|
||||
act++;
|
||||
switch (category) {
|
||||
case ACT_CAT_BA:
|
||||
switch (*act) {
|
||||
case ACT_ADDBAREQ:
|
||||
if (mac->act_scanning)
|
||||
return false;
|
||||
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("%s ACT_ADDBAREQ From :" MAC_FMT "\n",
|
||||
is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
case ACT_ADDBARSP:
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("%s ACT_ADDBARSP From :" MAC_FMT "\n",
|
||||
is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
case ACT_DELBA:
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("ACT_ADDBADEL From :" MAC_FMT "\n",
|
||||
MAC_ARG(hdr->addr2)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*should call before software enc*/
|
||||
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
u16 fc = le16_to_cpu(hdr->frame_control);
|
||||
u16 ether_type;
|
||||
u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
|
||||
const struct iphdr *ip;
|
||||
|
||||
if (!ieee80211_is_data(fc))
|
||||
goto end;
|
||||
|
||||
if (ieee80211_is_nullfunc(fc))
|
||||
return true;
|
||||
|
||||
ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
|
||||
SNAP_SIZE + PROTOC_TYPE_SIZE);
|
||||
ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
|
||||
ether_type = ntohs(ether_type);
|
||||
|
||||
if (ETH_P_IP == ether_type) {
|
||||
if (IPPROTO_UDP == ip->protocol) {
|
||||
struct udphdr *udp = (struct udphdr *)((u8 *) ip +
|
||||
(ip->ihl << 2));
|
||||
if (((((u8 *) udp)[1] == 68) &&
|
||||
(((u8 *) udp)[3] == 67)) ||
|
||||
((((u8 *) udp)[1] == 67) &&
|
||||
(((u8 *) udp)[3] == 68))) {
|
||||
/*
|
||||
* 68 : UDP BOOTP client
|
||||
* 67 : UDP BOOTP server
|
||||
*/
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
|
||||
DBG_DMESG, ("dhcp %s !!\n",
|
||||
(is_tx) ? "Tx" : "Rx"));
|
||||
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies =
|
||||
jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (ETH_P_ARP == ether_type) {
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies = jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (ETH_P_PAE == ether_type) {
|
||||
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
|
||||
("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
|
||||
|
||||
if (is_tx) {
|
||||
rtl_lps_leave(hw);
|
||||
ppsc->last_delaylps_stamp_jiffies = jiffies;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (0x86DD == ether_type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* functions called by core.c
|
||||
*
|
||||
*********************************************************/
|
||||
int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_tid_data *tid_data;
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
|
||||
("on ra = %pM tid = %d\n", ra, tid));
|
||||
|
||||
if (unlikely(tid >= MAX_TID_COUNT))
|
||||
return -EINVAL;
|
||||
|
||||
if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Start AGG when state is not RTL_AGG_OFF !\n"));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tid_data = &mac->tids[tid];
|
||||
*ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
|
||||
("HW queue is empty tid:%d\n", tid));
|
||||
tid_data->agg.agg_state = RTL_AGG_ON;
|
||||
|
||||
ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
|
||||
{
|
||||
int ssn = -1;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_tid_data *tid_data;
|
||||
|
||||
if (!ra) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(tid >= MAX_TID_COUNT))
|
||||
return -EINVAL;
|
||||
|
||||
if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("Stopping AGG while state not ON or starting\n"));
|
||||
|
||||
tid_data = &mac->tids[tid];
|
||||
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
|
||||
|
||||
mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
|
||||
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* wq & timer callback functions
|
||||
*
|
||||
*********************************************************/
|
||||
void rtl_watchdog_wq_callback(void *data)
|
||||
{
|
||||
struct rtl_works *rtlworks = container_of_dwork_rtl(data,
|
||||
struct rtl_works,
|
||||
watchdog_wq);
|
||||
struct ieee80211_hw *hw = rtlworks->hw;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
|
||||
bool b_busytraffic = false;
|
||||
bool b_higher_busytraffic = false;
|
||||
bool b_higher_busyrxtraffic = false;
|
||||
bool b_higher_busytxtraffic = false;
|
||||
|
||||
u8 idx = 0;
|
||||
u32 rx_cnt_inp4eriod = 0;
|
||||
u32 tx_cnt_inp4eriod = 0;
|
||||
u32 aver_rx_cnt_inperiod = 0;
|
||||
u32 aver_tx_cnt_inperiod = 0;
|
||||
|
||||
bool benter_ps = false;
|
||||
|
||||
if (is_hal_stop(rtlhal))
|
||||
return;
|
||||
|
||||
/* <1> Determine if action frame is allowed */
|
||||
if (mac->link_state > MAC80211_NOLINK) {
|
||||
if (mac->cnt_after_linked < 20)
|
||||
mac->cnt_after_linked++;
|
||||
} else {
|
||||
mac->cnt_after_linked = 0;
|
||||
}
|
||||
|
||||
/* <2> DM */
|
||||
rtlpriv->cfg->ops->dm_watchdog(hw);
|
||||
|
||||
/*
|
||||
*<3> to check if traffic busy, if
|
||||
* busytraffic we don't change channel
|
||||
*/
|
||||
if (mac->link_state >= MAC80211_LINKED) {
|
||||
|
||||
/* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
|
||||
for (idx = 0; idx <= 2; idx++) {
|
||||
rtlpriv->link_info.num_rx_in4period[idx] =
|
||||
rtlpriv->link_info.num_rx_in4period[idx + 1];
|
||||
rtlpriv->link_info.num_tx_in4period[idx] =
|
||||
rtlpriv->link_info.num_tx_in4period[idx + 1];
|
||||
}
|
||||
rtlpriv->link_info.num_rx_in4period[3] =
|
||||
rtlpriv->link_info.num_rx_inperiod;
|
||||
rtlpriv->link_info.num_tx_in4period[3] =
|
||||
rtlpriv->link_info.num_tx_inperiod;
|
||||
for (idx = 0; idx <= 3; idx++) {
|
||||
rx_cnt_inp4eriod +=
|
||||
rtlpriv->link_info.num_rx_in4period[idx];
|
||||
tx_cnt_inp4eriod +=
|
||||
rtlpriv->link_info.num_tx_in4period[idx];
|
||||
}
|
||||
aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
|
||||
aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
|
||||
|
||||
/* (2) check traffic busy */
|
||||
if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
|
||||
b_busytraffic = true;
|
||||
|
||||
/* Higher Tx/Rx data. */
|
||||
if (aver_rx_cnt_inperiod > 4000 ||
|
||||
aver_tx_cnt_inperiod > 4000) {
|
||||
b_higher_busytraffic = true;
|
||||
|
||||
/* Extremely high Rx data. */
|
||||
if (aver_rx_cnt_inperiod > 5000)
|
||||
b_higher_busyrxtraffic = true;
|
||||
else
|
||||
b_higher_busytxtraffic = false;
|
||||
}
|
||||
|
||||
if (((rtlpriv->link_info.num_rx_inperiod +
|
||||
rtlpriv->link_info.num_tx_inperiod) > 8) ||
|
||||
(rtlpriv->link_info.num_rx_inperiod > 2))
|
||||
benter_ps = false;
|
||||
else
|
||||
benter_ps = true;
|
||||
|
||||
/* LeisurePS only work in infra mode. */
|
||||
if (benter_ps)
|
||||
rtl_lps_enter(hw);
|
||||
else
|
||||
rtl_lps_leave(hw);
|
||||
}
|
||||
|
||||
rtlpriv->link_info.num_rx_inperiod = 0;
|
||||
rtlpriv->link_info.num_tx_inperiod = 0;
|
||||
|
||||
rtlpriv->link_info.b_busytraffic = b_busytraffic;
|
||||
rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
|
||||
rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
|
||||
|
||||
}
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data)
|
||||
{
|
||||
struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
queue_delayed_work(rtlpriv->works.rtl_wq,
|
||||
&rtlpriv->works.watchdog_wq, 0);
|
||||
|
||||
mod_timer(&rtlpriv->works.watchdog_timer,
|
||||
jiffies + MSECS(RTL_WATCH_DOG_TIME));
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* sysfs functions
|
||||
*
|
||||
*********************************************************/
|
||||
static ssize_t rtl_show_debug_level(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev_get_drvdata(d);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
|
||||
}
|
||||
|
||||
static ssize_t rtl_store_debug_level(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct ieee80211_hw *hw = dev_get_drvdata(d);
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buf, 0, &val);
|
||||
if (ret) {
|
||||
printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
|
||||
} else {
|
||||
rtlpriv->dbg.global_debuglevel = val;
|
||||
printk(KERN_DEBUG "debuglevel:%x\n",
|
||||
rtlpriv->dbg.global_debuglevel);
|
||||
}
|
||||
|
||||
return strnlen(buf, count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
|
||||
rtl_show_debug_level, rtl_store_debug_level);
|
||||
|
||||
static struct attribute *rtl_sysfs_entries[] = {
|
||||
|
||||
&dev_attr_debug_level.attr,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* "name" is folder name witch will be
|
||||
* put in device directory like :
|
||||
* sys/devices/pci0000:00/0000:00:1c.4/
|
||||
* 0000:06:00.0/rtl_sysfs
|
||||
*/
|
||||
struct attribute_group rtl_attribute_group = {
|
||||
.name = "rtlsysfs",
|
||||
.attrs = rtl_sysfs_entries,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
|
||||
MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
|
||||
MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
|
||||
|
||||
static int __init rtl_core_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rtl_core_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(rtl_core_module_init);
|
||||
module_exit(rtl_core_module_exit);
|
|
@ -0,0 +1,120 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_BASE_H__
|
||||
#define __RTL_BASE_H__
|
||||
|
||||
#define RTL_DUMMY_OFFSET 0
|
||||
#define RTL_DUMMY_UNIT 8
|
||||
#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
|
||||
#define RTL_TX_DESC_SIZE 32
|
||||
#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
|
||||
|
||||
#define HT_AMSDU_SIZE_4K 3839
|
||||
#define HT_AMSDU_SIZE_8K 7935
|
||||
|
||||
#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
|
||||
#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
|
||||
|
||||
#define RTL_RATE_COUNT_LEGACY 12
|
||||
#define RTL_CHANNEL_COUNT 14
|
||||
|
||||
#define FRAME_OFFSET_FRAME_CONTROL 0
|
||||
#define FRAME_OFFSET_DURATION 2
|
||||
#define FRAME_OFFSET_ADDRESS1 4
|
||||
#define FRAME_OFFSET_ADDRESS2 10
|
||||
#define FRAME_OFFSET_ADDRESS3 16
|
||||
#define FRAME_OFFSET_SEQUENCE 22
|
||||
#define FRAME_OFFSET_ADDRESS4 24
|
||||
|
||||
#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
|
||||
WRITEEF2BYTE(_hdr, _val)
|
||||
#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
|
||||
WRITEEF1BYTE(_hdr, _val)
|
||||
#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
|
||||
SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
|
||||
#define SET_80211_HDR_TO_DS(_hdr, _val) \
|
||||
SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
|
||||
|
||||
#define SET_80211_PS_POLL_AID(_hdr, _val) \
|
||||
WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
|
||||
#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
|
||||
CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
|
||||
#define SET_80211_PS_POLL_TA(_hdr, _val) \
|
||||
CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
|
||||
|
||||
#define SET_80211_HDR_DURATION(_hdr, _val) \
|
||||
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
|
||||
#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
|
||||
#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
|
||||
#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
|
||||
CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
|
||||
#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
|
||||
WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
|
||||
|
||||
#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
|
||||
WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
|
||||
#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
|
||||
WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
|
||||
#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
|
||||
WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
|
||||
#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
|
||||
READEF2BYTE(((u8 *)(__phdr)) + 34)
|
||||
#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
|
||||
WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
|
||||
#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
|
||||
SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
|
||||
(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
|
||||
|
||||
int rtl_init_core(struct ieee80211_hw *hw);
|
||||
void rtl_deinit_core(struct ieee80211_hw *hw);
|
||||
void rtl_init_rx_config(struct ieee80211_hw *hw);
|
||||
void rtl_init_rfkill(struct ieee80211_hw *hw);
|
||||
void rtl_deinit_rfkill(struct ieee80211_hw *hw);
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data);
|
||||
void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
|
||||
|
||||
bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
|
||||
bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
|
||||
|
||||
void rtl_watch_dog_timer_callback(unsigned long data);
|
||||
int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
|
||||
u16 tid, u16 *ssn);
|
||||
int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
|
||||
void rtl_watchdog_wq_callback(void *data);
|
||||
|
||||
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
|
||||
|
||||
extern struct attribute_group rtl_attribute_group;
|
||||
#endif
|
|
@ -0,0 +1,291 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
#include "cam.h"
|
||||
|
||||
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtlpriv->sec.use_defaultkey = false;
|
||||
rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
|
||||
rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
|
||||
memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
|
||||
memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
|
||||
rtlpriv->sec.pairwise_key = NULL;
|
||||
}
|
||||
|
||||
static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
|
||||
u8 *mac_addr, u8 *key_cont_128, u16 us_config)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 target_command;
|
||||
u32 target_content = 0;
|
||||
u8 entry_i;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
|
||||
key_cont_128[0], key_cont_128[1],
|
||||
key_cont_128[2], key_cont_128[3],
|
||||
key_cont_128[4], key_cont_128[5]));
|
||||
|
||||
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
|
||||
target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
|
||||
target_command = target_command | BIT(31) | BIT(16);
|
||||
|
||||
if (entry_i == 0) {
|
||||
target_content = (u32) (*(mac_addr + 0)) << 16 |
|
||||
(u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): "
|
||||
"WRITE %x: %x\n",
|
||||
rtlpriv->cfg->maps[WCAMI], target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("The Key ID is %d\n", entry_no));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): "
|
||||
"WRITE %x: %x\n",
|
||||
rtlpriv->cfg->maps[RWCAM], target_command));
|
||||
|
||||
} else if (entry_i == 1) {
|
||||
|
||||
target_content = (u32) (*(mac_addr + 5)) << 24 |
|
||||
(u32) (*(mac_addr + 4)) << 16 |
|
||||
(u32) (*(mac_addr + 3)) << 8 |
|
||||
(u32) (*(mac_addr + 2));
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A4: %x\n",
|
||||
target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A0: %x\n",
|
||||
target_command));
|
||||
|
||||
} else {
|
||||
|
||||
target_content =
|
||||
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
|
||||
24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
|
||||
<< 16 |
|
||||
(u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
|
||||
| (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
|
||||
target_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
|
||||
target_command);
|
||||
udelay(100);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A4: %x\n",
|
||||
target_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_program_entry(): WRITE A0: %x\n",
|
||||
target_command));
|
||||
}
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("after set key, usconfig:%x\n", us_config));
|
||||
}
|
||||
|
||||
u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content)
|
||||
{
|
||||
u32 us_config;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
|
||||
"ulUseDK=%x MacAddr" MAC_FMT "\n",
|
||||
ul_entry_idx, ul_key_id, ul_enc_alg,
|
||||
ul_default_key, MAC_ARG(mac_addr)));
|
||||
|
||||
if (ul_key_id == TOTAL_CAM_ENTRY) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
|
||||
("<=== ulKeyId exceed!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ul_default_key == 1) {
|
||||
us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
|
||||
} else {
|
||||
us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
|
||||
}
|
||||
|
||||
rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
|
||||
(u8 *) key_content, us_config);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_add_one_entry);
|
||||
|
||||
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
|
||||
u8 *mac_addr, u32 ul_key_id)
|
||||
{
|
||||
u32 ul_command;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
|
||||
|
||||
ul_command = ul_key_id * CAM_CONTENT_COUNT;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_delete_one_entry);
|
||||
|
||||
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
|
||||
{
|
||||
u32 ul_command;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
ul_command = BIT(31) | BIT(30);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_reset_all_entry);
|
||||
|
||||
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 ul_command;
|
||||
u32 ul_content;
|
||||
u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
|
||||
switch (rtlpriv->sec.pairwise_enc_algorithm) {
|
||||
case WEP40_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
|
||||
break;
|
||||
case WEP104_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
|
||||
break;
|
||||
case TKIP_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
|
||||
break;
|
||||
case AESCCMP_ENCRYPTION:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
break;
|
||||
default:
|
||||
ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
}
|
||||
|
||||
ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
|
||||
|
||||
ul_content |= BIT(15);
|
||||
ul_command = CAM_CONTENT_COUNT * uc_index;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_mark_invalid);
|
||||
|
||||
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
u32 ul_command;
|
||||
u32 ul_content;
|
||||
u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
u8 entry_i;
|
||||
|
||||
switch (rtlpriv->sec.pairwise_enc_algorithm) {
|
||||
case WEP40_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
|
||||
break;
|
||||
case WEP104_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
|
||||
break;
|
||||
case TKIP_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
|
||||
break;
|
||||
case AESCCMP_ENCRYPTION:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
break;
|
||||
default:
|
||||
ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
|
||||
}
|
||||
|
||||
for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
|
||||
|
||||
if (entry_i == 0) {
|
||||
ul_content =
|
||||
(uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
|
||||
ul_content |= BIT(15);
|
||||
|
||||
} else {
|
||||
ul_content = 0;
|
||||
}
|
||||
|
||||
ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
|
||||
ul_command = ul_command | BIT(31) | BIT(16);
|
||||
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
|
||||
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
("rtl_cam_empty_entry(): WRITE A4: %x\n",
|
||||
ul_content));
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
("rtl_cam_empty_entry(): WRITE A0: %x\n",
|
||||
ul_command));
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(rtl_cam_empty_entry);
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_CAM_H_
|
||||
#define __RTL_CAM_H_
|
||||
|
||||
#define TOTAL_CAM_ENTRY 32
|
||||
#define CAM_CONTENT_COUNT 8
|
||||
|
||||
#define CFG_DEFAULT_KEY BIT(5)
|
||||
#define CFG_VALID BIT(15)
|
||||
|
||||
#define PAIRWISE_KEYIDX 0
|
||||
#define CAM_PAIRWISE_KEY_POSITION 4
|
||||
|
||||
#define CAM_CONFIG_USEDK 1
|
||||
#define CAM_CONFIG_NO_USEDK 0
|
||||
|
||||
extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
|
||||
extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
|
||||
u32 ul_default_key, u8 *key_content);
|
||||
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 ul_key_id);
|
||||
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
|
||||
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
|
||||
void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_CORE_H__
|
||||
#define __RTL_CORE_H__
|
||||
|
||||
#define RTL_SUPPORTED_FILTERS \
|
||||
(FIF_PROMISC_IN_BSS | \
|
||||
FIF_ALLMULTI | FIF_CONTROL | \
|
||||
FIF_OTHER_BSS | \
|
||||
FIF_FCSFAIL | \
|
||||
FIF_BCN_PRBRESP_PROMISC)
|
||||
|
||||
#define RTL_SUPPORTED_CTRL_FILTER 0xFF
|
||||
|
||||
extern const struct ieee80211_ops rtl_ops;
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#include "wifi.h"
|
||||
|
||||
void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 i;
|
||||
|
||||
rtlpriv->dbg.global_debuglevel = DBG_EMERG;
|
||||
|
||||
rtlpriv->dbg.global_debugcomponents =
|
||||
COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
|
||||
COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
|
||||
COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
|
||||
COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
|
||||
COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
|
||||
COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN;
|
||||
|
||||
for (i = 0; i < DBGP_TYPE_MAX; i++)
|
||||
rtlpriv->dbg.dbgp_type[i] = 0;
|
||||
|
||||
/*Init Debug flag enable condition */
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* Tmis program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Tmis program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* tmis program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* Tme full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_DEBUG_H__
|
||||
#define __RTL_DEBUG_H__
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Debug level
|
||||
--------------------------------------------------------------*/
|
||||
/*
|
||||
*Fatal bug.
|
||||
*For example, Tx/Rx/IO locked up,
|
||||
*memory access violation,
|
||||
*resource allocation failed,
|
||||
*unexpected HW behavior, HW BUG
|
||||
*and so on.
|
||||
*/
|
||||
#define DBG_EMERG 0
|
||||
|
||||
/*
|
||||
*Abnormal, rare, or unexpeted cases.
|
||||
*For example, Packet/IO Ctl canceled,
|
||||
*device suprisely unremoved and so on.
|
||||
*/
|
||||
#define DBG_WARNING 2
|
||||
|
||||
/*
|
||||
*Normal case driver developer should
|
||||
*open, we can see link status like
|
||||
*assoc/AddBA/DHCP/adapter start and
|
||||
*so on basic and useful infromations.
|
||||
*/
|
||||
#define DBG_DMESG 3
|
||||
|
||||
/*
|
||||
*Normal case with useful information
|
||||
*about current SW or HW state.
|
||||
*For example, Tx/Rx descriptor to fill,
|
||||
*Tx/Rx descriptor completed status,
|
||||
*SW protocol state change, dynamic
|
||||
*mechanism state change and so on.
|
||||
*/
|
||||
#define DBG_LOUD 4
|
||||
|
||||
/*
|
||||
*Normal case with detail execution
|
||||
*flow or information.
|
||||
*/
|
||||
#define DBG_TRACE 5
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Define the rt_trace components
|
||||
--------------------------------------------------------------*/
|
||||
#define COMP_ERR BIT(0)
|
||||
#define COMP_FW BIT(1)
|
||||
#define COMP_INIT BIT(2) /*For init/deinit */
|
||||
#define COMP_RECV BIT(3) /*For Rx. */
|
||||
#define COMP_SEND BIT(4) /*For Tx. */
|
||||
#define COMP_MLME BIT(5) /*For MLME. */
|
||||
#define COMP_SCAN BIT(6) /*For Scan. */
|
||||
#define COMP_INTR BIT(7) /*For interrupt Related. */
|
||||
#define COMP_LED BIT(8) /*For LED. */
|
||||
#define COMP_SEC BIT(9) /*For sec. */
|
||||
#define COMP_BEACON BIT(10) /*For beacon. */
|
||||
#define COMP_RATE BIT(11) /*For rate. */
|
||||
#define COMP_RXDESC BIT(12) /*For rx desc. */
|
||||
#define COMP_DIG BIT(13) /*For DIG */
|
||||
#define COMP_TXAGC BIT(14) /*For Tx power */
|
||||
#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
|
||||
#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
|
||||
#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
|
||||
#define COMP_BB_POWERSAVING BIT(18)
|
||||
#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
|
||||
#define COMP_RF BIT(20) /*For RF. */
|
||||
#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
|
||||
#define COMP_RATR BIT(22)
|
||||
#define COMP_CMD BIT(23)
|
||||
#define COMP_EFUSE BIT(24)
|
||||
#define COMP_QOS BIT(25)
|
||||
#define COMP_MAC80211 BIT(26)
|
||||
#define COMP_REGD BIT(27)
|
||||
#define COMP_CHAN BIT(28)
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
Define the rt_print components
|
||||
--------------------------------------------------------------*/
|
||||
/* Define EEPROM and EFUSE check module bit*/
|
||||
#define EEPROM_W BIT(0)
|
||||
#define EFUSE_PG BIT(1)
|
||||
#define EFUSE_READ_ALL BIT(2)
|
||||
|
||||
/* Define init check for module bit*/
|
||||
#define INIT_EEPROM BIT(0)
|
||||
#define INIT_TxPower BIT(1)
|
||||
#define INIT_IQK BIT(2)
|
||||
#define INIT_RF BIT(3)
|
||||
|
||||
/* Define PHY-BB/RF/MAC check module bit */
|
||||
#define PHY_BBR BIT(0)
|
||||
#define PHY_BBW BIT(1)
|
||||
#define PHY_RFR BIT(2)
|
||||
#define PHY_RFW BIT(3)
|
||||
#define PHY_MACR BIT(4)
|
||||
#define PHY_MACW BIT(5)
|
||||
#define PHY_ALLR BIT(6)
|
||||
#define PHY_ALLW BIT(7)
|
||||
#define PHY_TXPWR BIT(8)
|
||||
#define PHY_PWRDIFF BIT(9)
|
||||
|
||||
enum dbgp_flag_e {
|
||||
FQOS = 0,
|
||||
FTX = 1,
|
||||
FRX = 2,
|
||||
FSEC = 3,
|
||||
FMGNT = 4,
|
||||
FMLME = 5,
|
||||
FRESOURCE = 6,
|
||||
FBEACON = 7,
|
||||
FISR = 8,
|
||||
FPHY = 9,
|
||||
FMP = 10,
|
||||
FEEPROM = 11,
|
||||
FPWR = 12,
|
||||
FDM = 13,
|
||||
FDBGCtrl = 14,
|
||||
FC2H = 15,
|
||||
FBT = 16,
|
||||
FINIT = 17,
|
||||
FIOCTL = 18,
|
||||
DBGP_TYPE_MAX
|
||||
};
|
||||
|
||||
#define RT_ASSERT(_exp, fmt) \
|
||||
do { \
|
||||
if (!(_exp)) { \
|
||||
printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
|
||||
__func__); \
|
||||
printk fmt; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RT_TRACE(rtlpriv, comp, level, fmt)\
|
||||
do { \
|
||||
if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
|
||||
((level) <= rtlpriv->dbg.global_debuglevel))) {\
|
||||
printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
|
||||
__func__, in_interrupt(), in_atomic()); \
|
||||
printk fmt; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \
|
||||
do { \
|
||||
if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
|
||||
printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
|
||||
printk printstr; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
|
||||
_hexdatalen) \
|
||||
do {\
|
||||
if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
|
||||
(_level <= rtlpriv->dbg.global_debuglevel))) { \
|
||||
int __i; \
|
||||
u8* ptr = (u8 *)_hexdata; \
|
||||
printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
|
||||
printk("In process \"%s\" (pid %i):", current->comm,\
|
||||
current->pid); \
|
||||
printk(_titlestring); \
|
||||
for (__i = 0; __i < (int)_hexdatalen; __i++) { \
|
||||
printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
|
||||
== 0) ? " " : " ");\
|
||||
if (((__i + 1) % 16) == 0) \
|
||||
printk("\n"); \
|
||||
} \
|
||||
printk(KERN_DEBUG "\n"); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define MAC_ARG(x) \
|
||||
((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2],\
|
||||
((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
|
||||
|
||||
void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,124 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_EFUSE_H_
|
||||
#define __RTL_EFUSE_H_
|
||||
|
||||
#define EFUSE_REAL_CONTENT_LEN 512
|
||||
#define EFUSE_MAP_LEN 128
|
||||
#define EFUSE_MAX_SECTION 16
|
||||
#define EFUSE_MAX_WORD_UNIT 4
|
||||
|
||||
#define EFUSE_INIT_MAP 0
|
||||
#define EFUSE_MODIFY_MAP 1
|
||||
|
||||
#define PG_STATE_HEADER 0x01
|
||||
#define PG_STATE_WORD_0 0x02
|
||||
#define PG_STATE_WORD_1 0x04
|
||||
#define PG_STATE_WORD_2 0x08
|
||||
#define PG_STATE_WORD_3 0x10
|
||||
#define PG_STATE_DATA 0x20
|
||||
|
||||
#define PG_SWBYTE_H 0x01
|
||||
#define PG_SWBYTE_L 0x02
|
||||
|
||||
#define _POWERON_DELAY_
|
||||
#define _PRE_EXECUTE_READ_CMD_
|
||||
|
||||
#define EFUSE_REPEAT_THRESHOLD_ 3
|
||||
|
||||
struct efuse_map {
|
||||
u8 offset;
|
||||
u8 word_start;
|
||||
u8 byte_start;
|
||||
u8 byte_cnts;
|
||||
};
|
||||
|
||||
struct pgpkt_struct {
|
||||
u8 offset;
|
||||
u8 word_en;
|
||||
u8 data[8];
|
||||
};
|
||||
|
||||
enum efuse_data_item {
|
||||
EFUSE_CHIP_ID = 0,
|
||||
EFUSE_LDO_SETTING,
|
||||
EFUSE_CLK_SETTING,
|
||||
EFUSE_SDIO_SETTING,
|
||||
EFUSE_CCCR,
|
||||
EFUSE_SDIO_MODE,
|
||||
EFUSE_OCR,
|
||||
EFUSE_F0CIS,
|
||||
EFUSE_F1CIS,
|
||||
EFUSE_MAC_ADDR,
|
||||
EFUSE_EEPROM_VER,
|
||||
EFUSE_CHAN_PLAN,
|
||||
EFUSE_TXPW_TAB
|
||||
};
|
||||
|
||||
enum {
|
||||
VOLTAGE_V25 = 0x03,
|
||||
LDOE25_SHIFT = 28,
|
||||
};
|
||||
|
||||
struct efuse_priv {
|
||||
u8 id[2];
|
||||
u8 ldo_setting[2];
|
||||
u8 clk_setting[2];
|
||||
u8 cccr;
|
||||
u8 sdio_mode;
|
||||
u8 ocr[3];
|
||||
u8 cis0[17];
|
||||
u8 cis1[48];
|
||||
u8 mac_addr[6];
|
||||
u8 eeprom_verno;
|
||||
u8 channel_plan;
|
||||
u8 tx_power_b[14];
|
||||
u8 tx_power_g[14];
|
||||
};
|
||||
|
||||
extern void efuse_initialize(struct ieee80211_hw *hw);
|
||||
extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
|
||||
extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
|
||||
extern void read_efuse(struct ieee80211_hw *hw, u16 _offset,
|
||||
u16 _size_byte, u8 *pbuf);
|
||||
extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
|
||||
u16 offset, u32 *value);
|
||||
extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
|
||||
u16 offset, u32 value);
|
||||
extern bool efuse_shadow_update(struct ieee80211_hw *hw);
|
||||
extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
|
||||
extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
|
||||
extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
|
||||
extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
|
||||
extern bool efuse_program_map(struct ieee80211_hw *hw,
|
||||
char *p_filename, u8 tabletype);
|
||||
extern void efuse_reset_loader(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,302 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* wlanfae <wlanfae@realtek.com>
|
||||
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
||||
* Hsinchu 300, Taiwan.
|
||||
*
|
||||
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __RTL_PCI_H__
|
||||
#define __RTL_PCI_H__
|
||||
|
||||
#include <linux/pci.h>
|
||||
/*
|
||||
1: MSDU packet queue,
|
||||
2: Rx Command Queue
|
||||
*/
|
||||
#define RTL_PCI_RX_MPDU_QUEUE 0
|
||||
#define RTL_PCI_RX_CMD_QUEUE 1
|
||||
#define RTL_PCI_MAX_RX_QUEUE 2
|
||||
|
||||
#define RTL_PCI_MAX_RX_COUNT 64
|
||||
#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
|
||||
|
||||
#define RT_TXDESC_NUM 128
|
||||
#define RT_TXDESC_NUM_BE_QUEUE 256
|
||||
|
||||
#define BK_QUEUE 0
|
||||
#define BE_QUEUE 1
|
||||
#define VI_QUEUE 2
|
||||
#define VO_QUEUE 3
|
||||
#define BEACON_QUEUE 4
|
||||
#define TXCMD_QUEUE 5
|
||||
#define MGNT_QUEUE 6
|
||||
#define HIGH_QUEUE 7
|
||||
#define HCCA_QUEUE 8
|
||||
|
||||
#define RTL_PCI_DEVICE(vend, dev, cfg) \
|
||||
.vendor = (vend), \
|
||||
.device = (dev), \
|
||||
.subvendor = PCI_ANY_ID, \
|
||||
.subdevice = PCI_ANY_ID,\
|
||||
.driver_data = (kernel_ulong_t)&(cfg)
|
||||
|
||||
#define INTEL_VENDOR_ID 0x8086
|
||||
#define SIS_VENDOR_ID 0x1039
|
||||
#define ATI_VENDOR_ID 0x1002
|
||||
#define ATI_DEVICE_ID 0x7914
|
||||
#define AMD_VENDOR_ID 0x1022
|
||||
|
||||
#define PCI_MAX_BRIDGE_NUMBER 255
|
||||
#define PCI_MAX_DEVICES 32
|
||||
#define PCI_MAX_FUNCTION 8
|
||||
|
||||
#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
|
||||
#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
|
||||
|
||||
#define PCI_CLASS_BRIDGE_DEV 0x06
|
||||
#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
|
||||
#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
|
||||
#define PCI_CAP_ID_EXP 0x10
|
||||
|
||||
#define U1DONTCARE 0xFF
|
||||
#define U2DONTCARE 0xFFFF
|
||||
#define U4DONTCARE 0xFFFFFFFF
|
||||
|
||||
#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
|
||||
#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
|
||||
#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
|
||||
#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
|
||||
#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
|
||||
#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
|
||||
#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
|
||||
#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
|
||||
#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
|
||||
#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
|
||||
#define RTL_PCI_700F_DID 0x700F
|
||||
#define RTL_PCI_701F_DID 0x701F
|
||||
#define RTL_PCI_DLINK_DID 0x3304
|
||||
#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
|
||||
#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
|
||||
#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
|
||||
#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
|
||||
#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
|
||||
#define RTL_PCI_8192DE_DID 0x092D /*8192ce */
|
||||
#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
|
||||
|
||||
/*8192 support 16 pages of IO registers*/
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
|
||||
#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
|
||||
|
||||
#define RTL_PCI_REVISION_ID_8190PCI 0x00
|
||||
#define RTL_PCI_REVISION_ID_8192PCIE 0x01
|
||||
#define RTL_PCI_REVISION_ID_8192SE 0x10
|
||||
#define RTL_PCI_REVISION_ID_8192CE 0x1
|
||||
#define RTL_PCI_REVISION_ID_8192DE 0x0
|
||||
|
||||
#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
|
||||
|
||||
enum pci_bridge_vendor {
|
||||
PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
|
||||
PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
|
||||
PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
|
||||
PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
|
||||
PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
|
||||
PCI_BRIDGE_VENDOR_MAX,
|
||||
};
|
||||
|
||||
struct rtl_rx_desc {
|
||||
u32 dword[8];
|
||||
} __packed;
|
||||
|
||||
struct rtl_tx_desc {
|
||||
u32 dword[16];
|
||||
} __packed;
|
||||
|
||||
struct rtl_tx_cmd_desc {
|
||||
u32 dword[16];
|
||||
} __packed;
|
||||
|
||||
struct rtl8192_tx_ring {
|
||||
struct rtl_tx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int idx;
|
||||
unsigned int entries;
|
||||
struct sk_buff_head queue;
|
||||
};
|
||||
|
||||
struct rtl8192_rx_ring {
|
||||
struct rtl_rx_desc *desc;
|
||||
dma_addr_t dma;
|
||||
unsigned int idx;
|
||||
struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
|
||||
};
|
||||
|
||||
struct rtl_pci {
|
||||
struct pci_dev *pdev;
|
||||
|
||||
bool driver_is_goingto_unload;
|
||||
bool up_first_time;
|
||||
bool being_init_adapter;
|
||||
bool irq_enabled;
|
||||
|
||||
/*Tx */
|
||||
struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
|
||||
int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
|
||||
u32 transmit_config;
|
||||
|
||||
/*Rx */
|
||||
struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
|
||||
int rxringcount;
|
||||
u16 rxbuffersize;
|
||||
u32 receive_config;
|
||||
|
||||
/*irq */
|
||||
u8 irq_alloc;
|
||||
u32 irq_mask[2];
|
||||
|
||||
/*Bcn control register setting */
|
||||
u32 reg_bcn_ctrl_val;
|
||||
|
||||
/*ASPM*/ u8 const_pci_aspm;
|
||||
u8 const_amdpci_aspm;
|
||||
u8 const_hwsw_rfoff_d3;
|
||||
u8 const_support_pciaspm;
|
||||
/*pci-e bridge */
|
||||
u8 const_hostpci_aspm_setting;
|
||||
/*pci-e device */
|
||||
u8 const_devicepci_aspm_setting;
|
||||
/*If it supports ASPM, Offset[560h] = 0x40,
|
||||
otherwise Offset[560h] = 0x00. */
|
||||
bool b_support_aspm;
|
||||
bool b_support_backdoor;
|
||||
|
||||
/*QOS & EDCA */
|
||||
enum acm_method acm_method;
|
||||
};
|
||||
|
||||
struct mp_adapter {
|
||||
u8 linkctrl_reg;
|
||||
|
||||
u8 busnumber;
|
||||
u8 devnumber;
|
||||
u8 funcnumber;
|
||||
|
||||
u8 pcibridge_busnum;
|
||||
u8 pcibridge_devnum;
|
||||
u8 pcibridge_funcnum;
|
||||
|
||||
u8 pcibridge_vendor;
|
||||
u16 pcibridge_vendorid;
|
||||
u16 pcibridge_deviceid;
|
||||
|
||||
u32 pcicfg_addrport;
|
||||
u8 num4bytes;
|
||||
|
||||
u8 pcibridge_pciehdr_offset;
|
||||
u8 pcibridge_linkctrlreg;
|
||||
|
||||
bool amd_l1_patch;
|
||||
};
|
||||
|
||||
struct rtl_pci_priv {
|
||||
struct rtl_pci dev;
|
||||
struct mp_adapter ndis_adapter;
|
||||
struct rtl_led_ctl ledctl;
|
||||
};
|
||||
|
||||
#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
|
||||
#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
|
||||
|
||||
int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
|
||||
|
||||
extern struct rtl_intf_ops rtl_pci_ops;
|
||||
|
||||
int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id);
|
||||
void rtl_pci_disconnect(struct pci_dev *pdev);
|
||||
int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
|
||||
int rtl_pci_resume(struct pci_dev *pdev);
|
||||
|
||||
static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
|
||||
{
|
||||
return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
|
||||
{
|
||||
writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write16_async(struct rtl_priv *rtlpriv,
|
||||
u32 addr, u16 val)
|
||||
{
|
||||
writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void pci_write32_async(struct rtl_priv *rtlpriv,
|
||||
u32 addr, u32 val)
|
||||
{
|
||||
writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
|
||||
{
|
||||
outl(val, port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
|
||||
{
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
|
||||
{
|
||||
*pval = inb(port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
|
||||
{
|
||||
*pval = inw(port);
|
||||
}
|
||||
|
||||
static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
|
||||
{
|
||||
*pval = inl(port);
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue