Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
This commit is contained in:
commit
5470b462c3
@ -8500,7 +8500,7 @@ F: drivers/usb/gadget/*uvc*.c
|
||||
F: drivers/usb/gadget/webcam.c
|
||||
|
||||
USB WIRELESS RNDIS DRIVER (rndis_wlan)
|
||||
M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
M: Jussi Kivilinna <jussi.kivilinna@iki.fi>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/rndis_wlan.c
|
||||
|
@ -104,7 +104,13 @@ void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
|
||||
if (i)
|
||||
bcma_err(core->bus, "PLL enable timeout\n");
|
||||
} else {
|
||||
bcma_warn(core->bus, "Disabling PLL not supported yet!\n");
|
||||
/*
|
||||
* Mask the PLL but don't wait for it to be disabled. PLL may be
|
||||
* shared between cores and will be still up if there is another
|
||||
* core using it.
|
||||
*/
|
||||
bcma_mask32(core, BCMA_CLKCTLST, ~req);
|
||||
bcma_read32(core, BCMA_CLKCTLST);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
|
||||
|
@ -120,6 +120,11 @@ static int bcma_register_cores(struct bcma_bus *bus)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only first GMAC core on BCM4706 is connected and working */
|
||||
if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
|
||||
core->core_unit > 0)
|
||||
continue;
|
||||
|
||||
core->dev.release = bcma_release_core_dev;
|
||||
core->dev.bus = &bcma_bus_type;
|
||||
dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
|
||||
|
@ -1523,7 +1523,8 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah);
|
||||
/* EEPROM access functions */
|
||||
int ath5k_eeprom_init(struct ath5k_hw *ah);
|
||||
void ath5k_eeprom_detach(struct ath5k_hw *ah);
|
||||
|
||||
int ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel);
|
||||
|
||||
/* Protocol Control Unit Functions */
|
||||
/* Helpers */
|
||||
|
@ -1779,7 +1779,8 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
|
||||
}
|
||||
|
||||
int
|
||||
ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
|
||||
ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
switch (channel->hw_value) {
|
||||
case AR5K_MODE_11A:
|
||||
@ -1789,6 +1790,7 @@ ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
|
||||
case AR5K_MODE_11B:
|
||||
return AR5K_EEPROM_MODE_11B;
|
||||
default:
|
||||
return -1;
|
||||
ATH5K_WARN(ah, "channel is not A/B/G!");
|
||||
return AR5K_EEPROM_MODE_11A;
|
||||
}
|
||||
}
|
||||
|
@ -493,6 +493,3 @@ struct ath5k_eeprom_info {
|
||||
/* Antenna raw switch tables */
|
||||
u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
|
||||
};
|
||||
|
||||
int
|
||||
ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
|
||||
|
@ -1612,11 +1612,7 @@ ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
|
||||
|
||||
ah->ah_cal_mask |= AR5K_CALIBRATION_NF;
|
||||
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
|
||||
if (WARN_ON(ee_mode < 0)) {
|
||||
ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
|
||||
return;
|
||||
}
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(ah, ah->ah_current_channel);
|
||||
|
||||
/* completed NF calibration, test threshold */
|
||||
nf = ath5k_hw_read_measured_noise_floor(ah);
|
||||
@ -2317,12 +2313,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
|
||||
|
||||
def_ant = ah->ah_def_ant;
|
||||
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(channel);
|
||||
if (ee_mode < 0) {
|
||||
ATH5K_ERR(ah,
|
||||
"invalid channel: %d\n", channel->center_freq);
|
||||
return;
|
||||
}
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
|
||||
|
||||
switch (ant_mode) {
|
||||
case AR5K_ANTMODE_DEFAULT:
|
||||
@ -3622,12 +3613,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(channel);
|
||||
if (ee_mode < 0) {
|
||||
ATH5K_ERR(ah,
|
||||
"invalid channel: %d\n", channel->center_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
|
||||
|
||||
/* Initialize TX power table */
|
||||
switch (ah->ah_radio) {
|
||||
|
@ -984,9 +984,7 @@ ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
|
||||
if (ah->ah_version == AR5K_AR5210)
|
||||
return;
|
||||
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(channel);
|
||||
if (WARN_ON(ee_mode < 0))
|
||||
return;
|
||||
ee_mode = ath5k_eeprom_mode_from_channel(ah, channel);
|
||||
|
||||
/* Adjust power delta for channel 14 */
|
||||
if (channel->center_freq == 2484)
|
||||
|
@ -30,6 +30,15 @@ config ATH6KL_DEBUG
|
||||
---help---
|
||||
Enables debug support
|
||||
|
||||
config ATH6KL_TRACING
|
||||
bool "Atheros ath6kl tracing support"
|
||||
depends on ATH6KL
|
||||
depends on EVENT_TRACING
|
||||
---help---
|
||||
Select this to ath6kl use tracing infrastructure.
|
||||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
config ATH6KL_REGDOMAIN
|
||||
bool "Atheros ath6kl regdomain support"
|
||||
depends on ATH6KL
|
||||
|
@ -35,10 +35,15 @@ ath6kl_core-y += txrx.o
|
||||
ath6kl_core-y += wmi.o
|
||||
ath6kl_core-y += core.o
|
||||
ath6kl_core-y += recovery.o
|
||||
|
||||
ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o
|
||||
|
||||
obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
|
||||
ath6kl_sdio-y += sdio.o
|
||||
|
||||
obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
|
||||
ath6kl_usb-y += usb.o
|
||||
|
||||
# for tracing framework to find trace.h
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
@ -402,7 +402,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
|
||||
if (type == NL80211_IFTYPE_STATION ||
|
||||
type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
|
||||
for (i = 0; i < ar->vif_max; i++) {
|
||||
if ((ar->avail_idx_map >> i) & BIT(0)) {
|
||||
if ((ar->avail_idx_map) & BIT(i)) {
|
||||
*if_idx = i;
|
||||
return true;
|
||||
}
|
||||
@ -412,7 +412,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
|
||||
if (type == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
type == NL80211_IFTYPE_P2P_GO) {
|
||||
for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
|
||||
if ((ar->avail_idx_map >> i) & BIT(0)) {
|
||||
if ((ar->avail_idx_map) & BIT(i)) {
|
||||
*if_idx = i;
|
||||
return true;
|
||||
}
|
||||
@ -1535,7 +1535,9 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
|
||||
|
||||
ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
|
||||
|
||||
rtnl_lock();
|
||||
ath6kl_cfg80211_vif_cleanup(vif);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2990,13 +2992,15 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
if (vif->nw_type != AP_NETWORK)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Use this only for authorizing/unauthorizing a station */
|
||||
if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
|
||||
return -EOPNOTSUPP;
|
||||
err = cfg80211_check_station_change(wiphy, params,
|
||||
CFG80211_STA_AP_MLME_CLIENT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
|
||||
return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
|
||||
@ -3659,7 +3663,6 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
|
||||
vif->sme_state = SME_DISCONNECTED;
|
||||
set_bit(WLAN_ENABLED, &vif->flags);
|
||||
ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
|
||||
set_bit(NETDEV_REGISTERED, &vif->flags);
|
||||
|
||||
if (type == NL80211_IFTYPE_ADHOC)
|
||||
ar->ibss_if_active = true;
|
||||
|
@ -560,7 +560,6 @@ enum ath6kl_vif_state {
|
||||
WMM_ENABLED,
|
||||
NETQ_STOPPED,
|
||||
DTIM_EXPIRED,
|
||||
NETDEV_REGISTERED,
|
||||
CLEAR_BSSFILTER_ON_BEACON,
|
||||
DTIM_PERIOD_AVAIL,
|
||||
WLAN_ENABLED,
|
||||
@ -936,8 +935,6 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
|
||||
u8 win_sz);
|
||||
void ath6kl_wakeup_event(void *dev);
|
||||
|
||||
void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
|
||||
bool wait_fot_compltn, bool cold_reset);
|
||||
void ath6kl_init_control_info(struct ath6kl_vif *vif);
|
||||
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
|
||||
void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
|
||||
|
@ -56,6 +56,60 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_printk);
|
||||
|
||||
int ath6kl_info(const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
ret = ath6kl_printk(KERN_INFO, "%pV", &vaf);
|
||||
trace_ath6kl_log_info(&vaf);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_info);
|
||||
|
||||
int ath6kl_err(const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
ret = ath6kl_printk(KERN_ERR, "%pV", &vaf);
|
||||
trace_ath6kl_log_err(&vaf);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_err);
|
||||
|
||||
int ath6kl_warn(const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf);
|
||||
trace_ath6kl_log_warn(&vaf);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_warn);
|
||||
|
||||
#ifdef CONFIG_ATH6KL_DEBUG
|
||||
|
||||
void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
|
||||
@ -63,15 +117,15 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
|
||||
if (!(debug_mask & mask))
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
|
||||
ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
|
||||
if (debug_mask & mask)
|
||||
ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
|
||||
|
||||
trace_ath6kl_log_dbg(mask, &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@ -87,6 +141,10 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
|
||||
|
||||
print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
|
||||
}
|
||||
|
||||
/* tracing code doesn't like null strings :/ */
|
||||
trace_ath6kl_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
|
||||
buf, len);
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_dbg_dump);
|
||||
|
||||
@ -1752,8 +1810,10 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
|
||||
debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
|
||||
&fops_tgt_stats);
|
||||
|
||||
debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
|
||||
&fops_credit_dist_stats);
|
||||
if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO)
|
||||
debugfs_create_file("credit_dist_stats", S_IRUSR,
|
||||
ar->debugfs_phy, ar,
|
||||
&fops_credit_dist_stats);
|
||||
|
||||
debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
|
||||
ar->debugfs_phy, ar, &fops_endpoint_stats);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define DEBUG_H
|
||||
|
||||
#include "hif.h"
|
||||
#include "trace.h"
|
||||
|
||||
enum ATH6K_DEBUG_MASK {
|
||||
ATH6KL_DBG_CREDIT = BIT(0),
|
||||
@ -51,13 +52,9 @@ enum ATH6K_DEBUG_MASK {
|
||||
extern unsigned int debug_mask;
|
||||
extern __printf(2, 3)
|
||||
int ath6kl_printk(const char *level, const char *fmt, ...);
|
||||
|
||||
#define ath6kl_info(fmt, ...) \
|
||||
ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
|
||||
#define ath6kl_err(fmt, ...) \
|
||||
ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
|
||||
#define ath6kl_warn(fmt, ...) \
|
||||
ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
|
||||
extern __printf(1, 2) int ath6kl_info(const char *fmt, ...);
|
||||
extern __printf(1, 2) int ath6kl_err(const char *fmt, ...);
|
||||
extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...);
|
||||
|
||||
enum ath6kl_war {
|
||||
ATH6KL_WAR_INVALID_RATE,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "target.h"
|
||||
#include "hif-ops.h"
|
||||
#include "debug.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define MAILBOX_FOR_BLOCK_SIZE 1
|
||||
|
||||
@ -436,6 +437,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
|
||||
|
||||
ath6kl_dump_registers(dev, &dev->irq_proc_reg,
|
||||
&dev->irq_en_reg);
|
||||
trace_ath6kl_sdio_irq(&dev->irq_en_reg,
|
||||
sizeof(dev->irq_en_reg));
|
||||
|
||||
/* Update only those registers that are enabled */
|
||||
host_int_status = dev->irq_proc_reg.host_int_status &
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "hif.h"
|
||||
#include "debug.h"
|
||||
#include "hif-ops.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
|
||||
@ -537,6 +539,8 @@ static int ath6kl_htc_tx_issue(struct htc_target *target,
|
||||
packet->buf, padded_len,
|
||||
HIF_WR_ASYNC_BLOCK_INC, packet);
|
||||
|
||||
trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -757,7 +761,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
|
||||
{
|
||||
struct htc_target *target = endpoint->target;
|
||||
struct hif_scatter_req *scat_req = NULL;
|
||||
int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
|
||||
int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0, i;
|
||||
struct htc_packet *packet;
|
||||
int status;
|
||||
u32 txb_mask;
|
||||
u8 ac = WMM_NUM_AC;
|
||||
@ -832,6 +837,13 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc tx scatter bytes %d entries %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
|
||||
for (i = 0; i < scat_req->scat_entries; i++) {
|
||||
packet = scat_req->scat_list[i].packet;
|
||||
trace_ath6kl_htc_tx(packet->status, packet->endpoint,
|
||||
packet->buf, packet->act_len);
|
||||
}
|
||||
|
||||
ath6kl_hif_submit_scat_req(target->dev, scat_req, false);
|
||||
|
||||
if (status)
|
||||
@ -1903,6 +1915,7 @@ static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx complete ep %d packet 0x%p\n",
|
||||
endpoint->eid, packet);
|
||||
|
||||
endpoint->ep_cb.rx(endpoint->target, packet);
|
||||
}
|
||||
|
||||
@ -2011,6 +2024,9 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
|
||||
list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
|
||||
ep = &target->endpoint[packet->endpoint];
|
||||
|
||||
trace_ath6kl_htc_rx(packet->status, packet->endpoint,
|
||||
packet->buf, packet->act_len);
|
||||
|
||||
/* process header for each of the recv packet */
|
||||
status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
|
||||
n_lk_ahd);
|
||||
@ -2291,6 +2307,9 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
|
||||
if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
|
||||
goto fail_ctrl_rx;
|
||||
|
||||
trace_ath6kl_htc_rx(packet->status, packet->endpoint,
|
||||
packet->buf, packet->act_len);
|
||||
|
||||
/* process receive header */
|
||||
packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
|
||||
|
||||
|
@ -988,8 +988,6 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
|
||||
|
||||
htc_hdr = (struct htc_frame_hdr *) netdata;
|
||||
|
||||
ep = &target->endpoint[htc_hdr->eid];
|
||||
|
||||
if (htc_hdr->eid >= ENDPOINT_MAX) {
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"HTC Rx: invalid EndpointID=%d\n",
|
||||
@ -997,6 +995,7 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb,
|
||||
status = -EINVAL;
|
||||
goto free_skb;
|
||||
}
|
||||
ep = &target->endpoint[htc_hdr->eid];
|
||||
|
||||
payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
|
||||
|
||||
@ -1168,8 +1167,8 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "%s: Timeout!\n", __func__);
|
||||
return -ECOMM;
|
||||
ath6kl_warn("htc pipe control receive timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1582,16 +1581,16 @@ static int ath6kl_htc_pipe_wait_target(struct htc_target *target)
|
||||
return status;
|
||||
|
||||
if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) {
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg len:%d!\n",
|
||||
target->pipe.ctrl_response_len);
|
||||
ath6kl_warn("invalid htc pipe ready msg len: %d\n",
|
||||
target->pipe.ctrl_response_len);
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf;
|
||||
|
||||
if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) {
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg : 0x%X !\n",
|
||||
ready_msg->ver2_0_info.msg_id);
|
||||
ath6kl_warn("invalid htc pipe ready msg: 0x%x\n",
|
||||
ready_msg->ver2_0_info.msg_id);
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
|
@ -201,8 +201,8 @@ struct sk_buff *ath6kl_buf_alloc(int size)
|
||||
u16 reserved;
|
||||
|
||||
/* Add chacheline space at front and back of buffer */
|
||||
reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
|
||||
sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
|
||||
reserved = roundup((2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
|
||||
sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES, 4);
|
||||
skb = dev_alloc_skb(size + reserved);
|
||||
|
||||
if (skb)
|
||||
@ -1549,10 +1549,89 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const struct fw_capa_str_map {
|
||||
int id;
|
||||
const char *name;
|
||||
} fw_capa_map[] = {
|
||||
{ ATH6KL_FW_CAPABILITY_HOST_P2P, "host-p2p" },
|
||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN, "sched-scan" },
|
||||
{ ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, "sta-p2pdev-duplex" },
|
||||
{ ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, "inactivity-timeout" },
|
||||
{ ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, "rsn-cap-override" },
|
||||
{ ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, "wow-mc-filter" },
|
||||
{ ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, "bmiss-enhance" },
|
||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, "sscan-match-list" },
|
||||
{ ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, "rssi-scan-thold" },
|
||||
{ ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, "custom-mac-addr" },
|
||||
{ ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, "tx-err-notify" },
|
||||
{ ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
|
||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
|
||||
{ ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
|
||||
};
|
||||
|
||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fw_capa_map); i++) {
|
||||
if (fw_capa_map[i].id == id)
|
||||
return fw_capa_map[i].name;
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len)
|
||||
{
|
||||
u8 *data = (u8 *) ar->fw_capabilities;
|
||||
size_t trunc_len, len = 0;
|
||||
int i, index, bit;
|
||||
char *trunc = "...";
|
||||
|
||||
for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
|
||||
index = i / 8;
|
||||
bit = i % 8;
|
||||
|
||||
if (index >= sizeof(ar->fw_capabilities) * 4)
|
||||
break;
|
||||
|
||||
if (buf_len - len < 4) {
|
||||
ath6kl_warn("firmware capability buffer too small!\n");
|
||||
|
||||
/* add "..." to the end of string */
|
||||
trunc_len = strlen(trunc) + 1;
|
||||
strncpy(buf + buf_len - trunc_len, trunc, trunc_len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[index] & (1 << bit)) {
|
||||
len += scnprintf(buf + len, buf_len - len, "%s,",
|
||||
ath6kl_init_get_fw_capa_name(i));
|
||||
}
|
||||
}
|
||||
|
||||
/* overwrite the last comma */
|
||||
if (len > 0)
|
||||
len--;
|
||||
|
||||
buf[len] = '\0';
|
||||
}
|
||||
|
||||
static int ath6kl_init_hw_reset(struct ath6kl *ar)
|
||||
{
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "cold resetting the device");
|
||||
|
||||
return ath6kl_diag_write32(ar, RESET_CONTROL_ADDRESS,
|
||||
cpu_to_le32(RESET_CONTROL_COLD_RST));
|
||||
}
|
||||
|
||||
static int __ath6kl_init_hw_start(struct ath6kl *ar)
|
||||
{
|
||||
long timeleft;
|
||||
int ret, i;
|
||||
char buf[200];
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
|
||||
|
||||
@ -1569,24 +1648,35 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
|
||||
goto err_power_off;
|
||||
|
||||
/* Do we need to finish the BMI phase */
|
||||
/* FIXME: return error from ath6kl_bmi_done() */
|
||||
if (ath6kl_bmi_done(ar)) {
|
||||
ret = -EIO;
|
||||
ret = ath6kl_bmi_done(ar);
|
||||
if (ret)
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* The reason we have to wait for the target here is that the
|
||||
* driver layer has to init BMI in order to set the host block
|
||||
* size.
|
||||
*/
|
||||
if (ath6kl_htc_wait_target(ar->htc_target)) {
|
||||
ret = -EIO;
|
||||
ret = ath6kl_htc_wait_target(ar->htc_target);
|
||||
|
||||
if (ret == -ETIMEDOUT) {
|
||||
/*
|
||||
* Most likely USB target is in odd state after reboot and
|
||||
* needs a reset. A cold reset makes the whole device
|
||||
* disappear from USB bus and initialisation starts from
|
||||
* beginning.
|
||||
*/
|
||||
ath6kl_warn("htc wait target timed out, resetting device\n");
|
||||
ath6kl_init_hw_reset(ar);
|
||||
goto err_power_off;
|
||||
} else if (ret) {
|
||||
ath6kl_err("htc wait target failed: %d\n", ret);
|
||||
goto err_power_off;
|
||||
}
|
||||
|
||||
if (ath6kl_init_service_ep(ar)) {
|
||||
ret = -EIO;
|
||||
ret = ath6kl_init_service_ep(ar);
|
||||
if (ret) {
|
||||
ath6kl_err("Endpoint service initilisation failed: %d\n", ret);
|
||||
goto err_cleanup_scatter;
|
||||
}
|
||||
|
||||
@ -1617,6 +1707,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
|
||||
ar->wiphy->fw_version,
|
||||
ar->fw_api,
|
||||
test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
|
||||
ath6kl_init_get_fwcaps(ar, buf, sizeof(buf));
|
||||
ath6kl_info("firmware supports: %s\n", buf);
|
||||
}
|
||||
|
||||
if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
|
||||
@ -1765,9 +1857,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
|
||||
* Try to reset the device if we can. The driver may have been
|
||||
* configure NOT to reset the target during a debug session.
|
||||
*/
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC,
|
||||
"attempting to reset target on instance destroy\n");
|
||||
ath6kl_reset_device(ar, ar->target_type, true, true);
|
||||
ath6kl_init_hw_reset(ar);
|
||||
|
||||
up(&ar->sem);
|
||||
}
|
||||
|
@ -345,39 +345,6 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FIXME: move to a better place, target.h? */
|
||||
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
|
||||
|
||||
void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
|
||||
bool wait_fot_compltn, bool cold_reset)
|
||||
{
|
||||
int status = 0;
|
||||
u32 address;
|
||||
__le32 data;
|
||||
|
||||
if (target_type != TARGET_TYPE_AR6003 &&
|
||||
target_type != TARGET_TYPE_AR6004)
|
||||
return;
|
||||
|
||||
data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
|
||||
cpu_to_le32(RESET_CONTROL_MBOX_RST);
|
||||
|
||||
switch (target_type) {
|
||||
case TARGET_TYPE_AR6003:
|
||||
address = AR6003_RESET_CONTROL_ADDRESS;
|
||||
break;
|
||||
case TARGET_TYPE_AR6004:
|
||||
address = AR6004_RESET_CONTROL_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
status = ath6kl_diag_write32(ar, address, data);
|
||||
|
||||
if (status)
|
||||
ath6kl_err("failed to reset target\n");
|
||||
}
|
||||
|
||||
static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
|
||||
{
|
||||
u8 index;
|
||||
@ -1327,9 +1294,11 @@ void init_netdev(struct net_device *dev)
|
||||
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
|
||||
|
||||
dev->needed_headroom = ETH_HLEN;
|
||||
dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
|
||||
sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
|
||||
+ WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
|
||||
dev->needed_headroom += roundup(sizeof(struct ath6kl_llc_snap_hdr) +
|
||||
sizeof(struct wmi_data_hdr) +
|
||||
HTC_HDR_LENGTH +
|
||||
WMI_MAX_TX_META_SZ +
|
||||
ATH6KL_HTC_ALIGN_BYTES, 4);
|
||||
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "target.h"
|
||||
#include "debug.h"
|
||||
#include "cfg80211.h"
|
||||
#include "trace.h"
|
||||
|
||||
struct ath6kl_sdio {
|
||||
struct sdio_func *func;
|
||||
@ -179,6 +180,8 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
|
||||
request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len);
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
|
||||
|
||||
trace_ath6kl_sdio(addr, request, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -309,6 +312,13 @@ static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
|
||||
mmc_set_data_timeout(&data, ar_sdio->func->card);
|
||||
|
||||
trace_ath6kl_sdio_scat(scat_req->addr,
|
||||
scat_req->req,
|
||||
scat_req->len,
|
||||
scat_req->scat_entries,
|
||||
scat_req->scat_list);
|
||||
|
||||
/* synchronous call to process request */
|
||||
mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
|
||||
|
||||
@ -1123,10 +1133,12 @@ static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
|
||||
ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
|
||||
HIF_WR_SYNC_BYTE_INC);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath6kl_err("unable to send the bmi data to the device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define AR6004_BOARD_DATA_SZ 6144
|
||||
#define AR6004_BOARD_EXT_DATA_SZ 0
|
||||
|
||||
#define RESET_CONTROL_ADDRESS 0x00000000
|
||||
#define RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define RESET_CONTROL_COLD_RST 0x00000100
|
||||
#define RESET_CONTROL_MBOX_RST 0x00000004
|
||||
|
||||
|
23
drivers/net/wireless/ath/ath6kl/trace.c
Normal file
23
drivers/net/wireless/ath/ath6kl/trace.c
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
|
||||
EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio);
|
||||
EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio_scat);
|
332
drivers/net/wireless/ath/ath6kl/trace.h
Normal file
332
drivers/net/wireless/ath/ath6kl/trace.h
Normal file
@ -0,0 +1,332 @@
|
||||
#if !defined(_ATH6KL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/tracepoint.h>
|
||||
#include "wmi.h"
|
||||
#include "hif.h"
|
||||
|
||||
#if !defined(_ATH6KL_TRACE_H)
|
||||
static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len)
|
||||
{
|
||||
struct wmi_cmd_hdr *hdr = buf;
|
||||
|
||||
if (buf_len < sizeof(*hdr))
|
||||
return 0;
|
||||
|
||||
return le16_to_cpu(hdr->cmd_id);
|
||||
}
|
||||
#endif /* __ATH6KL_TRACE_H */
|
||||
|
||||
#define _ATH6KL_TRACE_H
|
||||
|
||||
/* create empty functions when tracing is disabled */
|
||||
#if !defined(CONFIG_ATH6KL_TRACING)
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(...)
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(evt_class, name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#endif /* !CONFIG_ATH6KL_TRACING || __CHECKER__ */
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM ath6kl
|
||||
|
||||
TRACE_EVENT(ath6kl_wmi_cmd,
|
||||
TP_PROTO(void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, id)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->id = ath6kl_get_wmi_id(buf, buf_len);
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"id %d len %zd",
|
||||
__entry->id, __entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_wmi_event,
|
||||
TP_PROTO(void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, id)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->id = ath6kl_get_wmi_id(buf, buf_len);
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"id %d len %zd",
|
||||
__entry->id, __entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_sdio,
|
||||
TP_PROTO(unsigned int addr, int flags,
|
||||
void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(addr, flags, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, tx)
|
||||
__field(unsigned int, addr)
|
||||
__field(int, flags)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->addr = addr;
|
||||
__entry->flags = flags;
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
|
||||
if (flags & HIF_WRITE)
|
||||
__entry->tx = 1;
|
||||
else
|
||||
__entry->tx = 0;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s addr 0x%x flags 0x%x len %zd\n",
|
||||
__entry->tx ? "tx" : "rx",
|
||||
__entry->addr,
|
||||
__entry->flags,
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_sdio_scat,
|
||||
TP_PROTO(unsigned int addr, int flags, unsigned int total_len,
|
||||
unsigned int entries, struct hif_scatter_item *list),
|
||||
|
||||
TP_ARGS(addr, flags, total_len, entries, list),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, tx)
|
||||
__field(unsigned int, addr)
|
||||
__field(int, flags)
|
||||
__field(unsigned int, entries)
|
||||
__field(size_t, total_len)
|
||||
__dynamic_array(unsigned int, len_array, entries)
|
||||
__dynamic_array(u8, data, total_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
unsigned int *len_array;
|
||||
int i, offset = 0;
|
||||
size_t len;
|
||||
|
||||
__entry->addr = addr;
|
||||
__entry->flags = flags;
|
||||
__entry->entries = entries;
|
||||
__entry->total_len = total_len;
|
||||
|
||||
if (flags & HIF_WRITE)
|
||||
__entry->tx = 1;
|
||||
else
|
||||
__entry->tx = 0;
|
||||
|
||||
len_array = __get_dynamic_array(len_array);
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
len = list[i].len;
|
||||
|
||||
memcpy((u8 *) __get_dynamic_array(data) + offset,
|
||||
list[i].buf, len);
|
||||
|
||||
len_array[i] = len;
|
||||
offset += len;
|
||||
}
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s addr 0x%x flags 0x%x entries %d total_len %zd\n",
|
||||
__entry->tx ? "tx" : "rx",
|
||||
__entry->addr,
|
||||
__entry->flags,
|
||||
__entry->entries,
|
||||
__entry->total_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_sdio_irq,
|
||||
TP_PROTO(void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"irq len %zd\n", __entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_htc_rx,
|
||||
TP_PROTO(int status, int endpoint, void *buf,
|
||||
size_t buf_len),
|
||||
|
||||
TP_ARGS(status, endpoint, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(int, status)
|
||||
__field(int, endpoint)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->status = status;
|
||||
__entry->endpoint = endpoint;
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"status %d endpoint %d len %zd\n",
|
||||
__entry->status,
|
||||
__entry->endpoint,
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_htc_tx,
|
||||
TP_PROTO(int status, int endpoint, void *buf,
|
||||
size_t buf_len),
|
||||
|
||||
TP_ARGS(status, endpoint, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(int, status)
|
||||
__field(int, endpoint)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->status = status;
|
||||
__entry->endpoint = endpoint;
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"status %d endpoint %d len %zd\n",
|
||||
__entry->status,
|
||||
__entry->endpoint,
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
#define ATH6KL_MSG_MAX 200
|
||||
|
||||
DECLARE_EVENT_CLASS(ath6kl_log_event,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf),
|
||||
TP_STRUCT__entry(
|
||||
__dynamic_array(char, msg, ATH6KL_MSG_MAX)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
ATH6KL_MSG_MAX,
|
||||
vaf->fmt,
|
||||
*vaf->va) >= ATH6KL_MSG_MAX);
|
||||
),
|
||||
TP_printk("%s", __get_str(msg))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath6kl_log_event, ath6kl_log_err,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath6kl_log_event, ath6kl_log_warn,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath6kl_log_event, ath6kl_log_info,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_log_dbg,
|
||||
TP_PROTO(unsigned int level, struct va_format *vaf),
|
||||
TP_ARGS(level, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, level)
|
||||
__dynamic_array(char, msg, ATH6KL_MSG_MAX)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->level = level;
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
ATH6KL_MSG_MAX,
|
||||
vaf->fmt,
|
||||
*vaf->va) >= ATH6KL_MSG_MAX);
|
||||
),
|
||||
TP_printk("%s", __get_str(msg))
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath6kl_log_dbg_dump,
|
||||
TP_PROTO(const char *msg, const char *prefix,
|
||||
const void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(msg, prefix, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(msg, msg)
|
||||
__string(prefix, prefix)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(msg, msg);
|
||||
__assign_str(prefix, prefix);
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s/%s\n", __get_str(prefix), __get_str(msg)
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/
|
||||
|
||||
/* we don't want to use include/trace/events */
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE trace
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
@ -20,6 +20,7 @@
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "htc-ops.h"
|
||||
#include "trace.h"
|
||||
|
||||
/*
|
||||
* tid - tid_mux0..tid_mux3
|
||||
@ -288,6 +289,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
||||
int status = 0;
|
||||
struct ath6kl_cookie *cookie = NULL;
|
||||
|
||||
trace_ath6kl_wmi_cmd(skb->data, skb->len);
|
||||
|
||||
if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
|
||||
dev_kfree_skb(skb);
|
||||
return -EACCES;
|
||||
@ -1324,7 +1327,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
__func__, ar, ept, skb, packet->buf,
|
||||
packet->act_len, status);
|
||||
|
||||
if (status || !(skb->data + HTC_HDR_LENGTH)) {
|
||||
if (status || packet->act_len < HTC_HDR_LENGTH) {
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
@ -856,11 +856,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
|
||||
int ret;
|
||||
|
||||
if (size > 0) {
|
||||
buf = kmalloc(size, GFP_KERNEL);
|
||||
buf = kmemdup(data, size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(buf, data, size);
|
||||
}
|
||||
|
||||
/* note: if successful returns number of bytes transfered */
|
||||
@ -872,8 +870,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
|
||||
size, 1000);
|
||||
|
||||
if (ret < 0) {
|
||||
ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
|
||||
__func__, ret);
|
||||
ath6kl_warn("Failed to submit usb control message: %d\n", ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
@ -903,8 +902,9 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
|
||||
size, 2 * HZ);
|
||||
|
||||
if (ret < 0) {
|
||||
ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
|
||||
__func__, ret);
|
||||
ath6kl_warn("Failed to read usb control message: %d\n", ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy((u8 *) data, buf, size);
|
||||
@ -961,8 +961,10 @@ static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
|
||||
ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
|
||||
ar_usb->diag_resp_buffer, &resp_len);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath6kl_warn("diag read32 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
|
||||
ar_usb->diag_resp_buffer;
|
||||
@ -976,6 +978,7 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
|
||||
{
|
||||
struct ath6kl_usb *ar_usb = ar->hif_priv;
|
||||
struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
|
||||
int ret;
|
||||
|
||||
cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
|
||||
|
||||
@ -984,12 +987,17 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
|
||||
cmd->address = cpu_to_le32(address);
|
||||
cmd->value = data;
|
||||
|
||||
return ath6kl_usb_ctrl_msg_exchange(ar_usb,
|
||||
ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
|
||||
(u8 *) cmd,
|
||||
sizeof(*cmd),
|
||||
0, NULL, NULL);
|
||||
ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
|
||||
ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
|
||||
(u8 *) cmd,
|
||||
sizeof(*cmd),
|
||||
0, NULL, NULL);
|
||||
if (ret) {
|
||||
ath6kl_warn("diag_write32 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
@ -1001,7 +1009,7 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
ret = ath6kl_usb_submit_ctrl_in(ar_usb,
|
||||
ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
|
||||
0, 0, buf, len);
|
||||
if (ret != 0) {
|
||||
if (ret) {
|
||||
ath6kl_err("Unable to read the bmi data from the device: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
@ -1019,7 +1027,7 @@ static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
ret = ath6kl_usb_submit_ctrl_out(ar_usb,
|
||||
ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
|
||||
0, 0, buf, len);
|
||||
if (ret != 0) {
|
||||
if (ret) {
|
||||
ath6kl_err("unable to send the bmi data to the device: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "testmode.h"
|
||||
#include "trace.h"
|
||||
#include "../regd.h"
|
||||
#include "../regd_common.h"
|
||||
|
||||
@ -2028,6 +2029,9 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
if (WARN_ON(band >= ATH6KL_NUM_BANDS))
|
||||
break;
|
||||
|
||||
ratemask = rates[band];
|
||||
supp_rates = sc->supp_rates[band].rates;
|
||||
num_rates = 0;
|
||||
@ -4086,6 +4090,8 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
trace_ath6kl_wmi_event(skb->data, skb->len);
|
||||
|
||||
return ath6kl_wmi_proc_events(wmi, skb);
|
||||
}
|
||||
|
||||
|
@ -3606,6 +3606,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
|
||||
|
||||
if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
|
||||
value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
|
||||
REG_RMW_FIELD(ah, switch_chain_reg[0],
|
||||
AR_SWITCH_TABLE_ALL, value);
|
||||
}
|
||||
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if ((ah->rxchainmask & BIT(chain)) ||
|
||||
(ah->txchainmask & BIT(chain))) {
|
||||
@ -3772,6 +3778,17 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
AR_PHY_EXT_ATTEN_CTL_2,
|
||||
};
|
||||
|
||||
if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) {
|
||||
value = ar9003_hw_atten_chain_get(ah, 1, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[0],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
|
||||
|
||||
value = ar9003_hw_atten_chain_get_margin(ah, 1, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[0],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
|
||||
value);
|
||||
}
|
||||
|
||||
/* Test value. if 0 then attenuation is unused. Don't load anything. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (ah->txchainmask & BIT(i)) {
|
||||
|
@ -37,28 +37,28 @@ static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18253ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
|
||||
{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
|
||||
{0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
|
||||
{0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
|
||||
{0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81},
|
||||
{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
|
||||
{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
|
||||
{0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
|
||||
{0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
|
||||
{0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2},
|
||||
{0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
|
||||
{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
|
||||
{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
|
||||
{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e},
|
||||
{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
|
||||
{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
|
||||
{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
|
||||
{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
|
||||
{0x00009e3c, 0xcf946222, 0xcf946222, 0xcfd5c782, 0xcfd5c282},
|
||||
{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
|
||||
{0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
|
||||
{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
|
||||
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
|
||||
@ -82,9 +82,9 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
|
||||
{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
|
||||
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a3a4, 0x00000010, 0x00000010, 0x00000000, 0x00000000},
|
||||
{0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000},
|
||||
{0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
|
||||
{0x0000a3ac, 0xaaaaaa00, 0xaaaaaa30, 0xaaaaaa00, 0xaaaaaa00},
|
||||
{0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00},
|
||||
{0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
|
||||
{0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
|
||||
{0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
|
||||
@ -363,14 +363,14 @@ static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18213ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18212ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
|
||||
@ -775,7 +775,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = {
|
||||
{0x00009fc0, 0x803e4788},
|
||||
{0x00009fc4, 0x0001efb5},
|
||||
{0x00009fcc, 0x40000014},
|
||||
{0x00009fd0, 0x01193b93},
|
||||
{0x00009fd0, 0x0a193b93},
|
||||
{0x0000a20c, 0x00000000},
|
||||
{0x0000a220, 0x00000000},
|
||||
{0x0000a224, 0x00000000},
|
||||
@ -850,7 +850,7 @@ static const u32 ar9462_2p0_baseband_core[][2] = {
|
||||
{0x0000a7cc, 0x00000000},
|
||||
{0x0000a7d0, 0x00000000},
|
||||
{0x0000a7d4, 0x00000004},
|
||||
{0x0000a7dc, 0x00000001},
|
||||
{0x0000a7dc, 0x00000000},
|
||||
{0x0000a7f0, 0x80000000},
|
||||
{0x0000a8d0, 0x004b6a8e},
|
||||
{0x0000a8d4, 0x00000820},
|
||||
@ -886,7 +886,7 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
|
||||
{0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
|
||||
@ -906,20 +906,20 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
|
||||
{0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
|
||||
{0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
|
||||
{0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83},
|
||||
{0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84},
|
||||
{0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
|
||||
{0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
|
||||
{0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
|
||||
{0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
|
||||
{0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
|
||||
{0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
|
||||
{0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
|
||||
{0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
|
||||
{0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
|
||||
{0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
@ -1053,7 +1053,6 @@ static const u32 ar9462_2p0_mac_core[][2] = {
|
||||
{0x00008044, 0x00000000},
|
||||
{0x00008048, 0x00000000},
|
||||
{0x0000804c, 0xffffffff},
|
||||
{0x00008050, 0xffffffff},
|
||||
{0x00008054, 0x00000000},
|
||||
{0x00008058, 0x00000000},
|
||||
{0x0000805c, 0x000fc78f},
|
||||
@ -1117,9 +1116,9 @@ static const u32 ar9462_2p0_mac_core[][2] = {
|
||||
{0x000081f8, 0x00000000},
|
||||
{0x000081fc, 0x00000000},
|
||||
{0x00008240, 0x00100000},
|
||||
{0x00008244, 0x0010f424},
|
||||
{0x00008244, 0x0010f400},
|
||||
{0x00008248, 0x00000800},
|
||||
{0x0000824c, 0x0001e848},
|
||||
{0x0000824c, 0x0001e800},
|
||||
{0x00008250, 0x00000000},
|
||||
{0x00008254, 0x00000000},
|
||||
{0x00008258, 0x00000000},
|
||||
|
@ -369,7 +369,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
struct ieee80211_channel *c = chan->chan;
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
|
||||
chan->channelFlags &= (~CHANNEL_CW_INT);
|
||||
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"NF did not complete in calibration window\n");
|
||||
@ -384,7 +383,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"noise floor failed detected; detected %d, threshold %d\n",
|
||||
nf, nfThresh);
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
}
|
||||
|
||||
if (!caldata) {
|
||||
@ -410,7 +408,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
|
||||
int i, j;
|
||||
|
||||
ah->caldata->channel = chan->channel;
|
||||
ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT;
|
||||
ah->caldata->channelFlags = chan->channelFlags;
|
||||
ah->caldata->chanmode = chan->chanmode;
|
||||
h = ah->caldata->nfCalHist;
|
||||
default_nf = ath9k_hw_get_default_nf(ah, chan);
|
||||
|
@ -40,7 +40,7 @@
|
||||
x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
|
||||
} while (0)
|
||||
#define ATH_EP_RND(x, mul) \
|
||||
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
|
||||
(((x) + ((mul)/2)) / (mul))
|
||||
|
||||
int ath9k_cmn_padpos(__le16 frame_control);
|
||||
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
|
||||
|
@ -537,6 +537,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
PR("AMPDUs Completed:", a_completed);
|
||||
PR("AMPDUs Retried: ", a_retries);
|
||||
PR("AMPDUs XRetried: ", a_xretries);
|
||||
PR("TXERR Filtered: ", txerr_filtered);
|
||||
PR("FIFO Underrun: ", fifo_underrun);
|
||||
PR("TXOP Exceeded: ", xtxop);
|
||||
PR("TXTIMER Expiry: ", timer_exp);
|
||||
@ -756,6 +757,8 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
TX_STAT_INC(qnum, completed);
|
||||
}
|
||||
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
TX_STAT_INC(qnum, txerr_filtered);
|
||||
if (ts->ts_status & ATH9K_TXERR_FIFO)
|
||||
TX_STAT_INC(qnum, fifo_underrun);
|
||||
if (ts->ts_status & ATH9K_TXERR_XTXOP)
|
||||
@ -1909,6 +1912,7 @@ static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
|
||||
AMKSTR(d_tx_desc_cfg_err),
|
||||
AMKSTR(d_tx_data_underrun),
|
||||
AMKSTR(d_tx_delim_underrun),
|
||||
"d_rx_crc_err",
|
||||
"d_rx_decrypt_crc_err",
|
||||
"d_rx_phy_err",
|
||||
"d_rx_mic_err",
|
||||
@ -1989,6 +1993,7 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
|
||||
AWDATA(data_underrun);
|
||||
AWDATA(delim_underrun);
|
||||
|
||||
AWDATA_RX(crc_err);
|
||||
AWDATA_RX(decrypt_crc_err);
|
||||
AWDATA_RX(phy_err);
|
||||
AWDATA_RX(mic_err);
|
||||
|
@ -142,6 +142,7 @@ struct ath_interrupt_stats {
|
||||
* @a_completed: Total AMPDUs completed
|
||||
* @a_retries: No. of AMPDUs retried (SW)
|
||||
* @a_xretries: No. of AMPDUs dropped due to xretries
|
||||
* @txerr_filtered: No. of frames with TXERR_FILT flag set.
|
||||
* @fifo_underrun: FIFO underrun occurrences
|
||||
Valid only for:
|
||||
- non-aggregate condition.
|
||||
@ -168,6 +169,7 @@ struct ath_tx_stats {
|
||||
u32 a_completed;
|
||||
u32 a_retries;
|
||||
u32 a_xretries;
|
||||
u32 txerr_filtered;
|
||||
u32 fifo_underrun;
|
||||
u32 xtxop;
|
||||
u32 timer_exp;
|
||||
|
@ -1669,6 +1669,104 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_check_alive);
|
||||
|
||||
static void ath9k_hw_init_mfp(struct ath_hw *ah)
|
||||
{
|
||||
/* Setup MFP options for CCMP */
|
||||
if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
/* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
|
||||
* frames when constructing CCMP AAD. */
|
||||
REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
|
||||
0xc7ff);
|
||||
ah->sw_mgmt_crypto = false;
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
/* Disable hardware crypto for management frames */
|
||||
REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
|
||||
AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
|
||||
REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
|
||||
AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
|
||||
ah->sw_mgmt_crypto = true;
|
||||
} else {
|
||||
ah->sw_mgmt_crypto = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_reset_opmode(struct ath_hw *ah,
|
||||
u32 macStaId1, u32 saveDefAntenna)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
|
||||
REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
|
||||
| macStaId1
|
||||
| AR_STA_ID1_RTS_USE_DEF
|
||||
| (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
|
||||
| ah->sta_id1_defaults);
|
||||
ath_hw_setbssidmask(common);
|
||||
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
|
||||
ath9k_hw_write_associd(ah);
|
||||
REG_WRITE(ah, AR_ISR, ~0);
|
||||
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
ath9k_hw_set_operating_mode(ah, ah->opmode);
|
||||
}
|
||||
|
||||
static void ath9k_hw_init_queues(struct ath_hw *ah)
|
||||
{
|
||||
int i;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
for (i = 0; i < AR_NUM_DCU; i++)
|
||||
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
ah->intr_txqs = 0;
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
|
||||
ath9k_hw_resettxqueue(ah, i);
|
||||
}
|
||||
|
||||
/*
|
||||
* For big endian systems turn on swapping for descriptors
|
||||
*/
|
||||
static void ath9k_hw_init_desc(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (AR_SREV_9100(ah)) {
|
||||
u32 mask;
|
||||
mask = REG_READ(ah, AR_CFG);
|
||||
if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
|
||||
ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n",
|
||||
mask);
|
||||
} else {
|
||||
mask = INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
|
||||
REG_WRITE(ah, AR_CFG, mask);
|
||||
ath_dbg(common, RESET, "Setting CFG 0x%x\n",
|
||||
REG_READ(ah, AR_CFG));
|
||||
}
|
||||
} else {
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB) {
|
||||
/* Configure AR9271 target WLAN */
|
||||
if (AR_SREV_9271(ah))
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
|
||||
else
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
}
|
||||
#ifdef __BIG_ENDIAN
|
||||
else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
|
||||
AR_SREV_9550(ah))
|
||||
REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
|
||||
else
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast channel change:
|
||||
* (Change synthesizer based on channel freq without resetting chip)
|
||||
@ -1746,7 +1844,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u32 saveDefAntenna;
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
int i, r;
|
||||
int r;
|
||||
bool start_mci_reset = false;
|
||||
bool save_fullsleep = ah->chip_fullsleep;
|
||||
|
||||
@ -1763,10 +1861,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
ath9k_hw_getnf(ah, ah->curchan);
|
||||
|
||||
ah->caldata = caldata;
|
||||
if (caldata &&
|
||||
(chan->channel != caldata->channel ||
|
||||
(chan->channelFlags & ~CHANNEL_CW_INT) !=
|
||||
(caldata->channelFlags & ~CHANNEL_CW_INT))) {
|
||||
if (caldata && (chan->channel != caldata->channel ||
|
||||
chan->channelFlags != caldata->channelFlags)) {
|
||||
/* Operating channel changed, reset channel calibration data */
|
||||
memset(caldata, 0, sizeof(*caldata));
|
||||
ath9k_init_nfcal_hist_buffer(ah, chan);
|
||||
@ -1853,22 +1949,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
ath9k_hw_settsf64(ah, tsf);
|
||||
}
|
||||
|
||||
/* Setup MFP options for CCMP */
|
||||
if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
/* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
|
||||
* frames when constructing CCMP AAD. */
|
||||
REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
|
||||
0xc7ff);
|
||||
ah->sw_mgmt_crypto = false;
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
/* Disable hardware crypto for management frames */
|
||||
REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
|
||||
AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
|
||||
REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
|
||||
AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
|
||||
ah->sw_mgmt_crypto = true;
|
||||
} else
|
||||
ah->sw_mgmt_crypto = true;
|
||||
ath9k_hw_init_mfp(ah);
|
||||
|
||||
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
|
||||
ath9k_hw_set_delta_slope(ah, chan);
|
||||
@ -1876,24 +1957,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
ath9k_hw_spur_mitigate_freq(ah, chan);
|
||||
ah->eep_ops->set_board_values(ah, chan);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
|
||||
REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
|
||||
| macStaId1
|
||||
| AR_STA_ID1_RTS_USE_DEF
|
||||
| (ah->config.
|
||||
ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
|
||||
| ah->sta_id1_defaults);
|
||||
ath_hw_setbssidmask(common);
|
||||
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
|
||||
ath9k_hw_write_associd(ah);
|
||||
REG_WRITE(ah, AR_ISR, ~0);
|
||||
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
ath9k_hw_set_operating_mode(ah, ah->opmode);
|
||||
ath9k_hw_reset_opmode(ah, macStaId1, saveDefAntenna);
|
||||
|
||||
r = ath9k_hw_rf_set_freq(ah, chan);
|
||||
if (r)
|
||||
@ -1901,17 +1965,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
ath9k_hw_set_clockrate(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
for (i = 0; i < AR_NUM_DCU; i++)
|
||||
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
ah->intr_txqs = 0;
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
|
||||
ath9k_hw_resettxqueue(ah, i);
|
||||
|
||||
ath9k_hw_init_queues(ah);
|
||||
ath9k_hw_init_interrupt_masks(ah, ah->opmode);
|
||||
ath9k_hw_ani_cache_ini_regs(ah);
|
||||
ath9k_hw_init_qos(ah);
|
||||
@ -1966,38 +2020,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
/*
|
||||
* For big endian systems turn on swapping for descriptors
|
||||
*/
|
||||
if (AR_SREV_9100(ah)) {
|
||||
u32 mask;
|
||||
mask = REG_READ(ah, AR_CFG);
|
||||
if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
|
||||
ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n",
|
||||
mask);
|
||||
} else {
|
||||
mask =
|
||||
INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
|
||||
REG_WRITE(ah, AR_CFG, mask);
|
||||
ath_dbg(common, RESET, "Setting CFG 0x%x\n",
|
||||
REG_READ(ah, AR_CFG));
|
||||
}
|
||||
} else {
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB) {
|
||||
/* Configure AR9271 target WLAN */
|
||||
if (AR_SREV_9271(ah))
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
|
||||
else
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
}
|
||||
#ifdef __BIG_ENDIAN
|
||||
else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
|
||||
AR_SREV_9550(ah))
|
||||
REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
|
||||
else
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
#endif
|
||||
}
|
||||
ath9k_hw_init_desc(ah);
|
||||
|
||||
if (ath9k_hw_btcoex_is_enabled(ah))
|
||||
ath9k_hw_btcoex_enable(ah);
|
||||
@ -2010,7 +2033,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
ar9003_hw_bb_watchdog_config(ah);
|
||||
|
||||
ar9003_hw_disable_phy_restart(ah);
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,6 @@ enum ath9k_int {
|
||||
ATH9K_INT_NOCARD = 0xffffffff
|
||||
};
|
||||
|
||||
#define CHANNEL_CW_INT 0x00002
|
||||
#define CHANNEL_CCK 0x00020
|
||||
#define CHANNEL_OFDM 0x00040
|
||||
#define CHANNEL_2GHZ 0x00080
|
||||
|
@ -387,8 +387,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
|
||||
u8 tid;
|
||||
|
||||
if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
|
||||
txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
|
||||
(!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
|
||||
txinfo->flags & IEEE80211_TX_CTL_INJECTED)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
|
||||
|
||||
SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR,
|
||||
txc->s.ampdu_settings, factor);
|
||||
|
||||
for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
|
||||
txrate = &info->control.rates[i];
|
||||
if (txrate->idx >= 0) {
|
||||
txc->s.ri[i] =
|
||||
CARL9170_TX_SUPER_RI_AMPDU;
|
||||
|
||||
if (WARN_ON(!(txrate->flags &
|
||||
IEEE80211_TX_RC_MCS))) {
|
||||
/*
|
||||
* Not sure if it's even possible
|
||||
* to aggregate non-ht rates with
|
||||
* this HW.
|
||||
*/
|
||||
goto err_out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
txrate->idx = 0;
|
||||
txrate->count = ar->hw->max_rate_tries;
|
||||
}
|
||||
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
|
||||
* taken from mac_control. For all fallback rate, the firmware
|
||||
* updates the mac_control flags from the rate info field.
|
||||
*/
|
||||
for (i = 1; i < CARL9170_TX_MAX_RATES; i++) {
|
||||
for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
|
||||
__le32 phy_set;
|
||||
txrate = &info->control.rates[i];
|
||||
if (txrate->idx < 0)
|
||||
break;
|
||||
|
||||
phy_set = carl9170_tx_physet(ar, info, txrate);
|
||||
if (i == 0) {
|
||||
/* first rate - part of the hw's frame header */
|
||||
txc->f.phy_control = phy_set;
|
||||
|
||||
if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS)
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
|
||||
if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
|
||||
else if (carl9170_tx_cts_check(ar, txrate))
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
|
||||
|
||||
} else {
|
||||
/* fallback rates are stored in the firmware's
|
||||
* retry rate set array.
|
||||
*/
|
||||
txc->s.rr[i - 1] = phy_set;
|
||||
}
|
||||
|
||||
SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
|
||||
txrate->count);
|
||||
|
||||
@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
|
||||
txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
|
||||
CARL9170_TX_SUPER_RI_ERP_PROT_S);
|
||||
|
||||
txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate);
|
||||
if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS))
|
||||
txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
|
||||
}
|
||||
|
||||
txrate = &info->control.rates[0];
|
||||
SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count);
|
||||
|
||||
if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
|
||||
else if (carl9170_tx_cts_check(ar, txrate))
|
||||
mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
|
||||
|
||||
txc->s.len = cpu_to_le16(skb->len);
|
||||
txc->f.length = cpu_to_le16(len + FCS_LEN);
|
||||
txc->f.mac_control = mac_tmp;
|
||||
txc->f.phy_control = carl9170_tx_physet(ar, info, txrate);
|
||||
|
||||
arinfo = (void *)info->rate_driver_data;
|
||||
arinfo->timeout = jiffies;
|
||||
@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *ar)
|
||||
}
|
||||
|
||||
static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
|
||||
struct ieee80211_sta *sta, struct sk_buff *skb)
|
||||
struct ieee80211_sta *sta, struct sk_buff *skb,
|
||||
struct ieee80211_tx_info *txinfo)
|
||||
{
|
||||
struct _carl9170_tx_superframe *super = (void *) skb->data;
|
||||
struct carl9170_sta_info *sta_info;
|
||||
struct carl9170_sta_tid *agg;
|
||||
struct sk_buff *iter;
|
||||
@ -1450,7 +1437,7 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
|
||||
|
||||
err_unlock_rcu:
|
||||
rcu_read_unlock();
|
||||
super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
|
||||
txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
||||
carl9170_tx_status(ar, skb, false);
|
||||
ar->tx_dropped++;
|
||||
return false;
|
||||
@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw *hw,
|
||||
* sta == NULL checks are redundant in this
|
||||
* special case.
|
||||
*/
|
||||
run = carl9170_tx_ampdu_queue(ar, sta, skb);
|
||||
run = carl9170_tx_ampdu_queue(ar, sta, skb, info);
|
||||
if (run)
|
||||
carl9170_tx_ampdu(ar);
|
||||
|
||||
|
@ -9,5 +9,7 @@ wil6210-objs += wmi.o
|
||||
wil6210-objs += interrupt.o
|
||||
wil6210-objs += txrx.o
|
||||
|
||||
subdir-ccflags-y += -Werror
|
||||
ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
|
||||
subdir-ccflags-y += -Werror
|
||||
endif
|
||||
subdir-ccflags-y += -D__CHECK_ENDIAN__
|
||||
|
@ -14,16 +14,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include "wil6210.h"
|
||||
#include "wmi.h"
|
||||
|
||||
@ -292,7 +282,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
||||
|
||||
/* WMI_CONNECT_CMD */
|
||||
memset(&conn, 0, sizeof(conn));
|
||||
switch (bss->capability & 0x03) {
|
||||
switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
|
||||
case WLAN_CAPABILITY_DMG_TYPE_AP:
|
||||
conn.network_type = WMI_NETTYPE_INFRA;
|
||||
break;
|
||||
@ -437,17 +427,18 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = wmi_set_channel(wil, channel->hw_value);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* MAC address - pre-requisite for other commands */
|
||||
wmi_set_mac_address(wil, ndev->dev_addr);
|
||||
|
||||
/* IE's */
|
||||
/* bcon 'head IE's are not relevant for 60g band */
|
||||
wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
|
||||
bcon->beacon_ies);
|
||||
/*
|
||||
* FW do not form regular beacon, so bcon IE's are not set
|
||||
* For the DMG bcon, when it will be supported, bcon IE's will
|
||||
* be reused; add something like:
|
||||
* wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
|
||||
* bcon->beacon_ies);
|
||||
*/
|
||||
wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
|
||||
bcon->proberesp_ies);
|
||||
wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
|
||||
@ -455,7 +446,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
|
||||
wil->secure_pcp = info->privacy;
|
||||
|
||||
rc = wmi_set_bcon(wil, info->beacon_interval, wmi_nettype);
|
||||
rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
|
||||
channel->hw_value);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -472,11 +464,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
|
||||
{
|
||||
int rc = 0;
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
struct wireless_dev *wdev = ndev->ieee80211_ptr;
|
||||
u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
|
||||
|
||||
/* To stop beaconing, set BI to 0 */
|
||||
rc = wmi_set_bcon(wil, 0, wmi_nettype);
|
||||
rc = wmi_pcp_stop(wil);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
#ifndef WIL_DBG_HEXDUMP_H_
|
||||
#define WIL_DBG_HEXDUMP_H_
|
||||
|
||||
#include <linux/printk.h>
|
||||
#include <linux/dynamic_debug.h>
|
||||
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii)
|
||||
|
||||
#else /* defined(CONFIG_DYNAMIC_DEBUG) */
|
||||
#define wil_print_hex_dump_debug(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii)
|
||||
#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
|
||||
|
||||
#endif /* WIL_DBG_HEXDUMP_H_ */
|
@ -312,14 +312,6 @@ static const struct file_operations fops_memread = {
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
static int wil_default_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (inode->i_private)
|
||||
file->private_data = inode->i_private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
@ -361,7 +353,7 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
|
||||
|
||||
static const struct file_operations fops_ioblob = {
|
||||
.read = wil_read_file_ioblob,
|
||||
.open = wil_default_open,
|
||||
.open = simple_open,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
@ -396,7 +388,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
|
||||
|
||||
static const struct file_operations fops_reset = {
|
||||
.write = wil_write_file_reset,
|
||||
.open = wil_default_open,
|
||||
.open = simple_open,
|
||||
};
|
||||
/*---------Tx descriptor------------*/
|
||||
|
||||
@ -526,7 +518,50 @@ static ssize_t wil_write_file_ssid(struct file *file, const char __user *buf,
|
||||
static const struct file_operations fops_ssid = {
|
||||
.read = wil_read_file_ssid,
|
||||
.write = wil_write_file_ssid,
|
||||
.open = wil_default_open,
|
||||
.open = simple_open,
|
||||
};
|
||||
|
||||
/*---------temp------------*/
|
||||
static void print_temp(struct seq_file *s, const char *prefix, u32 t)
|
||||
{
|
||||
switch (t) {
|
||||
case 0:
|
||||
case ~(u32)0:
|
||||
seq_printf(s, "%s N/A\n", prefix);
|
||||
break;
|
||||
default:
|
||||
seq_printf(s, "%s %d.%03d\n", prefix, t / 1000, t % 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int wil_temp_debugfs_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
u32 t_m, t_r;
|
||||
|
||||
int rc = wmi_get_temperature(wil, &t_m, &t_r);
|
||||
if (rc) {
|
||||
seq_printf(s, "Failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
print_temp(s, "MAC temperature :", t_m);
|
||||
print_temp(s, "Radio temperature :", t_r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_temp_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, wil_temp_debugfs_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_temp = {
|
||||
.open = wil_temp_seq_open,
|
||||
.release = single_release,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
/*----------------*/
|
||||
@ -563,6 +598,7 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
|
||||
debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
|
||||
|
||||
debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset);
|
||||
debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp);
|
||||
|
||||
wil->rgf_blob.data = (void * __force)wil->csr + 0;
|
||||
wil->rgf_blob.size = 0xa000;
|
||||
|
@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
|
||||
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
|
||||
}
|
||||
|
||||
static void wil_cache_mbox_regs(struct wil6210_priv *wil)
|
||||
{
|
||||
/* make shadow copy of registers that should not change on run time */
|
||||
wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
|
||||
sizeof(struct wil6210_mbox_ctl));
|
||||
wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
|
||||
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
|
||||
}
|
||||
|
||||
static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
|
||||
{
|
||||
struct wil6210_priv *wil = cookie;
|
||||
@ -257,14 +266,19 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
|
||||
wil6210_mask_irq_misc(wil);
|
||||
|
||||
if (isr & ISR_MISC_FW_ERROR) {
|
||||
wil_dbg_irq(wil, "IRQ: Firmware error\n");
|
||||
wil_err(wil, "Firmware error detected\n");
|
||||
clear_bit(wil_status_fwready, &wil->status);
|
||||
wil_notify_fw_error(wil);
|
||||
isr &= ~ISR_MISC_FW_ERROR;
|
||||
/*
|
||||
* do not clear @isr here - we do 2-nd part in thread
|
||||
* there, user space get notified, and it should be done
|
||||
* in non-atomic context
|
||||
*/
|
||||
}
|
||||
|
||||
if (isr & ISR_MISC_FW_READY) {
|
||||
wil_dbg_irq(wil, "IRQ: FW ready\n");
|
||||
wil_cache_mbox_regs(wil);
|
||||
set_bit(wil_status_reset_done, &wil->status);
|
||||
/**
|
||||
* Actual FW ready indicated by the
|
||||
* WMI_FW_READY_EVENTID
|
||||
@ -289,6 +303,11 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
|
||||
|
||||
wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
|
||||
|
||||
if (isr & ISR_MISC_FW_ERROR) {
|
||||
wil_notify_fw_error(wil);
|
||||
isr &= ~ISR_MISC_FW_ERROR;
|
||||
}
|
||||
|
||||
if (isr & ISR_MISC_MBOX_EVT) {
|
||||
wil_dbg_irq(wil, "MBOX event\n");
|
||||
wmi_recv_cmd(wil);
|
||||
|
@ -14,12 +14,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
@ -109,13 +103,24 @@ static void wil_connect_timer_fn(ulong x)
|
||||
schedule_work(&wil->disconnect_worker);
|
||||
}
|
||||
|
||||
static void wil_cache_mbox_regs(struct wil6210_priv *wil)
|
||||
static void wil_connect_worker(struct work_struct *work)
|
||||
{
|
||||
/* make shadow copy of registers that should not change on run time */
|
||||
wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
|
||||
sizeof(struct wil6210_mbox_ctl));
|
||||
wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
|
||||
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
|
||||
int rc;
|
||||
struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
|
||||
connect_worker);
|
||||
int cid = wil->pending_connect_cid;
|
||||
|
||||
if (cid < 0) {
|
||||
wil_err(wil, "No connection pending\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);
|
||||
|
||||
rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0);
|
||||
wil->pending_connect_cid = -1;
|
||||
if (rc == 0)
|
||||
wil_link_on(wil);
|
||||
}
|
||||
|
||||
int wil_priv_init(struct wil6210_priv *wil)
|
||||
@ -130,7 +135,7 @@ int wil_priv_init(struct wil6210_priv *wil)
|
||||
wil->pending_connect_cid = -1;
|
||||
setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
|
||||
|
||||
INIT_WORK(&wil->wmi_connect_worker, wmi_connect_worker);
|
||||
INIT_WORK(&wil->connect_worker, wil_connect_worker);
|
||||
INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
|
||||
INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
|
||||
|
||||
@ -147,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
wil_cache_mbox_regs(wil);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -185,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil)
|
||||
W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
|
||||
W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
|
||||
|
||||
msleep(100);
|
||||
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
|
||||
|
||||
msleep(100);
|
||||
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
|
||||
@ -203,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil)
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
|
||||
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
|
||||
|
||||
msleep(2000);
|
||||
|
||||
W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
|
||||
|
||||
msleep(2000);
|
||||
|
||||
wil_dbg_misc(wil, "Reset completed\n");
|
||||
|
||||
#undef W
|
||||
@ -265,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil)
|
||||
wil->pending_connect_cid = -1;
|
||||
INIT_COMPLETION(wil->wmi_ready);
|
||||
|
||||
wil_cache_mbox_regs(wil);
|
||||
|
||||
/* TODO: release MAC reset */
|
||||
wil6210_enable_irq(wil);
|
||||
|
||||
@ -352,9 +343,9 @@ static int __wil_up(struct wil6210_priv *wil)
|
||||
wil_err(wil, "SSID not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
|
||||
if (channel)
|
||||
wmi_set_channel(wil, channel->hw_value);
|
||||
rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
|
||||
if (rc)
|
||||
return rc;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -364,9 +355,12 @@ static int __wil_up(struct wil6210_priv *wil)
|
||||
wmi_set_mac_address(wil, ndev->dev_addr);
|
||||
|
||||
/* Set up beaconing if required. */
|
||||
rc = wmi_set_bcon(wil, bi, wmi_nettype);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (bi > 0) {
|
||||
rc = wmi_pcp_start(wil, bi, wmi_nettype,
|
||||
(channel ? channel->hw_value : 0));
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Rx VRING. After MAC and beacon */
|
||||
wil_rx_init(wil);
|
||||
|
@ -14,10 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "wil6210.h"
|
||||
|
||||
|
@ -14,10 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
@ -14,10 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@ -558,7 +555,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
||||
if (rc)
|
||||
goto out_free;
|
||||
|
||||
if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) {
|
||||
if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) {
|
||||
wil_err(wil, "Tx config failed, status 0x%02x\n",
|
||||
reply.cmd.status);
|
||||
rc = -EINVAL;
|
||||
|
@ -21,8 +21,6 @@
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include "dbg_hexdump.h"
|
||||
|
||||
#define WIL_NAME "wil6210"
|
||||
|
||||
/**
|
||||
@ -188,6 +186,7 @@ enum { /* for wil6210_priv.status */
|
||||
wil_status_fwready = 0,
|
||||
wil_status_fwconnected,
|
||||
wil_status_dontscan,
|
||||
wil_status_reset_done,
|
||||
wil_status_irqen, /* FIXME: interrupts enabled - for debug */
|
||||
};
|
||||
|
||||
@ -210,6 +209,8 @@ struct wil6210_priv {
|
||||
struct wireless_dev *wdev;
|
||||
void __iomem *csr;
|
||||
ulong status;
|
||||
u32 fw_version;
|
||||
u8 n_mids; /* number of additional MIDs as reported by FW */
|
||||
/* profile */
|
||||
u32 monitor_flags;
|
||||
u32 secure_pcp; /* create secure PCP? */
|
||||
@ -227,7 +228,7 @@ struct wil6210_priv {
|
||||
struct workqueue_struct *wmi_wq; /* for deferred calls */
|
||||
struct work_struct wmi_event_worker;
|
||||
struct workqueue_struct *wmi_wq_conn; /* for connect worker */
|
||||
struct work_struct wmi_connect_worker;
|
||||
struct work_struct connect_worker;
|
||||
struct work_struct disconnect_worker;
|
||||
struct timer_list connect_timer;
|
||||
int pending_connect_cid;
|
||||
@ -277,13 +278,13 @@ struct wil6210_priv {
|
||||
|
||||
#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\
|
||||
print_hex_dump_debug("DBG[TXRX]" prefix_str,\
|
||||
prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii)
|
||||
|
||||
#define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii) \
|
||||
wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\
|
||||
print_hex_dump_debug("DBG[ WMI]" prefix_str,\
|
||||
prefix_type, rowsize, \
|
||||
groupsize, buf, len, ascii)
|
||||
|
||||
@ -313,7 +314,6 @@ int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len);
|
||||
void wmi_recv_cmd(struct wil6210_priv *wil);
|
||||
int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
|
||||
u16 reply_id, void *reply, u8 reply_size, int to_msec);
|
||||
void wmi_connect_worker(struct work_struct *work);
|
||||
void wmi_event_worker(struct work_struct *work);
|
||||
void wmi_event_flush(struct wil6210_priv *wil);
|
||||
int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid);
|
||||
@ -328,6 +328,8 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
|
||||
int wmi_echo(struct wil6210_priv *wil);
|
||||
int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
|
||||
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
|
||||
int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
|
||||
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
|
||||
|
||||
int wil6210_init_irq(struct wil6210_priv *wil, int irq);
|
||||
void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
|
||||
@ -341,7 +343,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev);
|
||||
void wil_wdev_free(struct wil6210_priv *wil);
|
||||
|
||||
int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
|
||||
int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype);
|
||||
int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan);
|
||||
int wmi_pcp_stop(struct wil6210_priv *wil);
|
||||
void wil6210_disconnect(struct wil6210_priv *wil, void *bssid);
|
||||
|
||||
int wil_rx_init(struct wil6210_priv *wil);
|
||||
|
@ -14,9 +14,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
@ -272,16 +269,18 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct wireless_dev *wdev = wil->wdev;
|
||||
struct wmi_ready_event *evt = d;
|
||||
u32 ver = le32_to_cpu(evt->sw_version);
|
||||
wil->fw_version = le32_to_cpu(evt->sw_version);
|
||||
wil->n_mids = evt->numof_additional_mids;
|
||||
|
||||
wil_dbg_wmi(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac);
|
||||
wil_dbg_wmi(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
|
||||
evt->mac, wil->n_mids);
|
||||
|
||||
if (!is_valid_ether_addr(ndev->dev_addr)) {
|
||||
memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
|
||||
memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
|
||||
}
|
||||
snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
|
||||
"%d", ver);
|
||||
"%d", wil->fw_version);
|
||||
}
|
||||
|
||||
static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
|
||||
@ -324,17 +323,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
|
||||
if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
|
||||
struct cfg80211_bss *bss;
|
||||
u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
|
||||
u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
|
||||
u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
|
||||
const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
|
||||
size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
|
||||
u.beacon.variable);
|
||||
wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
|
||||
|
||||
bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
|
||||
tsf, cap, bi, ie_buf, ie_len,
|
||||
signal, GFP_KERNEL);
|
||||
bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
|
||||
d_len, signal, GFP_KERNEL);
|
||||
if (bss) {
|
||||
wil_dbg_wmi(wil, "Added BSS %pM\n",
|
||||
rx_mgmt_frame->bssid);
|
||||
@ -342,6 +333,9 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
} else {
|
||||
wil_err(wil, "cfg80211_inform_bss() failed\n");
|
||||
}
|
||||
} else {
|
||||
cfg80211_rx_mgmt(wil->wdev, freq, signal,
|
||||
(void *)rx_mgmt_frame, d_len, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +437,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
memcpy(wil->dst_addr[0], evt->bssid, ETH_ALEN);
|
||||
|
||||
wil->pending_connect_cid = evt->cid;
|
||||
queue_work(wil->wmi_wq_conn, &wil->wmi_connect_worker);
|
||||
queue_work(wil->wmi_wq_conn, &wil->connect_worker);
|
||||
}
|
||||
|
||||
static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
|
||||
@ -528,6 +522,37 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
|
||||
}
|
||||
}
|
||||
|
||||
static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
{
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct wmi_data_port_open_event *evt = d;
|
||||
|
||||
wil_dbg_wmi(wil, "Link UP for CID %d\n", evt->cid);
|
||||
|
||||
netif_carrier_on(ndev);
|
||||
}
|
||||
|
||||
static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
{
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct wmi_wbe_link_down_event *evt = d;
|
||||
|
||||
wil_dbg_wmi(wil, "Link DOWN for CID %d, reason %d\n",
|
||||
evt->cid, le32_to_cpu(evt->reason));
|
||||
|
||||
netif_carrier_off(ndev);
|
||||
}
|
||||
|
||||
static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
|
||||
int len)
|
||||
{
|
||||
struct wmi_vring_ba_status_event *evt = d;
|
||||
|
||||
wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
|
||||
evt->ringid, evt->status ? "N/A" : "OK", evt->agg_wsize,
|
||||
__le16_to_cpu(evt->ba_timeout));
|
||||
}
|
||||
|
||||
static const struct {
|
||||
int eventid;
|
||||
void (*handler)(struct wil6210_priv *wil, int eventid,
|
||||
@ -541,6 +566,9 @@ static const struct {
|
||||
{WMI_DISCONNECT_EVENTID, wmi_evt_disconnect},
|
||||
{WMI_NOTIFY_REQ_DONE_EVENTID, wmi_evt_notify},
|
||||
{WMI_EAPOL_RX_EVENTID, wmi_evt_eapol_rx},
|
||||
{WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup},
|
||||
{WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown},
|
||||
{WMI_BA_STATUS_EVENTID, wmi_evt_ba_status},
|
||||
};
|
||||
|
||||
/*
|
||||
@ -559,6 +587,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
|
||||
void __iomem *src;
|
||||
ulong flags;
|
||||
|
||||
if (!test_bit(wil_status_reset_done, &wil->status)) {
|
||||
wil_err(wil, "Reset not completed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
u16 len;
|
||||
|
||||
@ -683,18 +716,39 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
|
||||
return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
int wmi_set_bcon(struct wil6210_priv *wil, int bi, u8 wmi_nettype)
|
||||
int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
|
||||
{
|
||||
struct wmi_bcon_ctrl_cmd cmd = {
|
||||
int rc;
|
||||
|
||||
struct wmi_pcp_start_cmd cmd = {
|
||||
.bcon_interval = cpu_to_le16(bi),
|
||||
.network_type = wmi_nettype,
|
||||
.disable_sec_offload = 1,
|
||||
.channel = chan,
|
||||
};
|
||||
struct {
|
||||
struct wil6210_mbox_hdr_wmi wmi;
|
||||
struct wmi_pcp_started_event evt;
|
||||
} __packed reply;
|
||||
|
||||
if (!wil->secure_pcp)
|
||||
cmd.disable_sec = 1;
|
||||
|
||||
return wmi_send(wil, WMI_BCON_CTRL_CMDID, &cmd, sizeof(cmd));
|
||||
rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd),
|
||||
WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 100);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (reply.evt.status != WMI_FW_STATUS_SUCCESS)
|
||||
rc = -EINVAL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_pcp_stop(struct wil6210_priv *wil)
|
||||
{
|
||||
return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0,
|
||||
WMI_PCP_STOPPED_EVENTID, NULL, 0, 20);
|
||||
}
|
||||
|
||||
int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid)
|
||||
@ -765,6 +819,16 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmi_p2p_cfg(struct wil6210_priv *wil, int channel)
|
||||
{
|
||||
struct wmi_p2p_cfg_cmd cmd = {
|
||||
.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD,
|
||||
.channel = channel - 1,
|
||||
};
|
||||
|
||||
return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_eapol_tx_cmd *cmd;
|
||||
@ -843,7 +907,7 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
|
||||
/* BUG: FW API define ieLen as u8. Will fix FW */
|
||||
cmd->ie_len = cpu_to_le16(ie_len);
|
||||
memcpy(cmd->ie_info, ie, ie_len);
|
||||
rc = wmi_send(wil, WMI_SET_APPIE_CMDID, &cmd, len);
|
||||
rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len);
|
||||
kfree(cmd);
|
||||
|
||||
return rc;
|
||||
@ -898,6 +962,31 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
|
||||
{
|
||||
int rc;
|
||||
struct wmi_temp_sense_cmd cmd = {
|
||||
.measure_marlon_m_en = cpu_to_le32(!!t_m),
|
||||
.measure_marlon_r_en = cpu_to_le32(!!t_r),
|
||||
};
|
||||
struct {
|
||||
struct wil6210_mbox_hdr_wmi wmi;
|
||||
struct wmi_temp_sense_done_event evt;
|
||||
} __packed reply;
|
||||
|
||||
rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd),
|
||||
WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (t_m)
|
||||
*t_m = le32_to_cpu(reply.evt.marlon_m_t1000);
|
||||
if (t_r)
|
||||
*t_r = le32_to_cpu(reply.evt.marlon_r_t1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wmi_event_flush(struct wil6210_priv *wil)
|
||||
{
|
||||
struct pending_wmi_event *evt, *t;
|
||||
@ -997,24 +1086,3 @@ void wmi_event_worker(struct work_struct *work)
|
||||
kfree(evt);
|
||||
}
|
||||
}
|
||||
|
||||
void wmi_connect_worker(struct work_struct *work)
|
||||
{
|
||||
int rc;
|
||||
struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
|
||||
wmi_connect_worker);
|
||||
|
||||
if (wil->pending_connect_cid < 0) {
|
||||
wil_err(wil, "No connection pending\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wil_dbg_wmi(wil, "Configure for connection CID %d\n",
|
||||
wil->pending_connect_cid);
|
||||
|
||||
rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
|
||||
wil->pending_connect_cid, 0);
|
||||
wil->pending_connect_cid = -1;
|
||||
if (rc == 0)
|
||||
wil_link_on(wil);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
enum wmi_command_id {
|
||||
WMI_CONNECT_CMDID = 0x0001,
|
||||
WMI_DISCONNECT_CMDID = 0x0003,
|
||||
WMI_DISCONNECT_STA_CMDID = 0x0004,
|
||||
WMI_START_SCAN_CMDID = 0x0007,
|
||||
WMI_SET_BSS_FILTER_CMDID = 0x0009,
|
||||
WMI_SET_PROBED_SSID_CMDID = 0x000a,
|
||||
@ -44,7 +45,6 @@ enum wmi_command_id {
|
||||
WMI_ADD_CIPHER_KEY_CMDID = 0x0016,
|
||||
WMI_DELETE_CIPHER_KEY_CMDID = 0x0017,
|
||||
WMI_SET_APPIE_CMDID = 0x003f,
|
||||
WMI_GET_APPIE_CMDID = 0x0040,
|
||||
WMI_SET_WSC_STATUS_CMDID = 0x0041,
|
||||
WMI_PXMT_RANGE_CFG_CMDID = 0x0042,
|
||||
WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043,
|
||||
@ -55,11 +55,11 @@ enum wmi_command_id {
|
||||
WMI_DEEP_ECHO_CMDID = 0x0804,
|
||||
WMI_CONFIG_MAC_CMDID = 0x0805,
|
||||
WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806,
|
||||
WMI_ADD_STATION_CMDID = 0x0807,
|
||||
WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808,
|
||||
WMI_PHY_GET_STATISTICS_CMDID = 0x0809,
|
||||
WMI_FS_TUNE_CMDID = 0x080a,
|
||||
WMI_CORR_MEASURE_CMDID = 0x080b,
|
||||
WMI_READ_RSSI_CMDID = 0x080c,
|
||||
WMI_TEMP_SENSE_CMDID = 0x080e,
|
||||
WMI_DC_CALIB_CMDID = 0x080f,
|
||||
WMI_SEND_TONE_CMDID = 0x0810,
|
||||
@ -75,9 +75,9 @@ enum wmi_command_id {
|
||||
MAC_IO_STATIC_PARAMS_CMDID = 0x081b,
|
||||
MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081c,
|
||||
WMI_SILENT_RSSI_CALIB_CMDID = 0x081d,
|
||||
WMI_RF_RX_TEST_CMDID = 0x081e,
|
||||
WMI_CFG_RX_CHAIN_CMDID = 0x0820,
|
||||
WMI_VRING_CFG_CMDID = 0x0821,
|
||||
WMI_RX_ON_CMDID = 0x0822,
|
||||
WMI_VRING_BA_EN_CMDID = 0x0823,
|
||||
WMI_VRING_BA_DIS_CMDID = 0x0824,
|
||||
WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
|
||||
@ -87,7 +87,6 @@ enum wmi_command_id {
|
||||
WMI_SET_PCP_CHANNEL_CMDID = 0x0829,
|
||||
WMI_GET_PCP_CHANNEL_CMDID = 0x082a,
|
||||
WMI_SW_TX_REQ_CMDID = 0x082b,
|
||||
WMI_RX_OFF_CMDID = 0x082c,
|
||||
WMI_READ_MAC_RXQ_CMDID = 0x0830,
|
||||
WMI_READ_MAC_TXQ_CMDID = 0x0831,
|
||||
WMI_WRITE_MAC_RXQ_CMDID = 0x0832,
|
||||
@ -112,6 +111,18 @@ enum wmi_command_id {
|
||||
WMI_FLASH_READ_CMDID = 0x0902,
|
||||
WMI_FLASH_WRITE_CMDID = 0x0903,
|
||||
WMI_SECURITY_UNIT_TEST_CMDID = 0x0904,
|
||||
/*P2P*/
|
||||
WMI_P2P_CFG_CMDID = 0x0910,
|
||||
WMI_PORT_ALLOCATE_CMDID = 0x0911,
|
||||
WMI_PORT_DELETE_CMDID = 0x0912,
|
||||
WMI_POWER_MGMT_CFG_CMDID = 0x0913,
|
||||
WMI_START_LISTEN_CMDID = 0x0914,
|
||||
WMI_START_SEARCH_CMDID = 0x0915,
|
||||
WMI_DISCOVERY_START_CMDID = 0x0916,
|
||||
WMI_DISCOVERY_STOP_CMDID = 0x0917,
|
||||
WMI_PCP_START_CMDID = 0x0918,
|
||||
WMI_PCP_STOP_CMDID = 0x0919,
|
||||
WMI_GET_PCP_FACTOR_CMDID = 0x091b,
|
||||
|
||||
WMI_SET_MAC_ADDRESS_CMDID = 0xf003,
|
||||
WMI_ABORT_SCAN_CMDID = 0xf007,
|
||||
@ -131,18 +142,6 @@ enum wmi_command_id {
|
||||
* Commands data structures
|
||||
*/
|
||||
|
||||
/*
|
||||
* Frame Types
|
||||
*/
|
||||
enum wmi_mgmt_frame_type {
|
||||
WMI_FRAME_BEACON = 0,
|
||||
WMI_FRAME_PROBE_REQ = 1,
|
||||
WMI_FRAME_PROBE_RESP = 2,
|
||||
WMI_FRAME_ASSOC_REQ = 3,
|
||||
WMI_FRAME_ASSOC_RESP = 4,
|
||||
WMI_NUM_MGMT_FRAME,
|
||||
};
|
||||
|
||||
/*
|
||||
* WMI_CONNECT_CMDID
|
||||
*/
|
||||
@ -184,7 +183,7 @@ enum wmi_crypto_type {
|
||||
enum wmi_connect_ctrl_flag_bits {
|
||||
WMI_CONNECT_ASSOC_POLICY_USER = 0x0001,
|
||||
WMI_CONNECT_SEND_REASSOC = 0x0002,
|
||||
WMI_CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
|
||||
WMI_CONNECT_IGNORE_WPA_GROUP_CIPHER = 0x0004,
|
||||
WMI_CONNECT_PROFILE_MATCH_DONE = 0x0008,
|
||||
WMI_CONNECT_IGNORE_AAC_BEACON = 0x0010,
|
||||
WMI_CONNECT_CSA_FOLLOW_BSS = 0x0020,
|
||||
@ -212,6 +211,13 @@ struct wmi_connect_cmd {
|
||||
u8 reserved1[2];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_DISCONNECT_STA_CMDID
|
||||
*/
|
||||
struct wmi_disconnect_sta_cmd {
|
||||
u8 dst_mac[WMI_MAC_LEN];
|
||||
__le16 disconnect_reason;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_RECONNECT_CMDID
|
||||
@ -289,10 +295,12 @@ struct wmi_delete_cipher_key_cmd {
|
||||
enum wmi_scan_type {
|
||||
WMI_LONG_SCAN = 0,
|
||||
WMI_SHORT_SCAN = 1,
|
||||
WMI_PBC_SCAN = 2,
|
||||
};
|
||||
|
||||
struct wmi_start_scan_cmd {
|
||||
u8 reserved[8];
|
||||
|
||||
__le32 home_dwell_time; /* Max duration in the home channel(ms) */
|
||||
__le32 force_scan_interval; /* Time interval between scans (ms)*/
|
||||
u8 scan_type; /* wmi_scan_type */
|
||||
@ -309,7 +317,7 @@ struct wmi_start_scan_cmd {
|
||||
/*
|
||||
* WMI_SET_PROBED_SSID_CMDID
|
||||
*/
|
||||
#define MAX_PROBED_SSID_INDEX (15)
|
||||
#define MAX_PROBED_SSID_INDEX (3)
|
||||
|
||||
enum wmi_ssid_flag {
|
||||
WMI_SSID_FLAG_DISABLE = 0, /* disables entry */
|
||||
@ -328,6 +336,20 @@ struct wmi_probed_ssid_cmd {
|
||||
* WMI_SET_APPIE_CMDID
|
||||
* Add Application specified IE to a management frame
|
||||
*/
|
||||
#define WMI_MAX_IE_LEN (1024)
|
||||
|
||||
/*
|
||||
* Frame Types
|
||||
*/
|
||||
enum wmi_mgmt_frame_type {
|
||||
WMI_FRAME_BEACON = 0,
|
||||
WMI_FRAME_PROBE_REQ = 1,
|
||||
WMI_FRAME_PROBE_RESP = 2,
|
||||
WMI_FRAME_ASSOC_REQ = 3,
|
||||
WMI_FRAME_ASSOC_RESP = 4,
|
||||
WMI_NUM_MGMT_FRAME,
|
||||
};
|
||||
|
||||
struct wmi_set_appie_cmd {
|
||||
u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
|
||||
u8 reserved;
|
||||
@ -335,13 +357,18 @@ struct wmi_set_appie_cmd {
|
||||
u8 ie_info[0];
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_IE_LEN (1024)
|
||||
|
||||
/*
|
||||
* WMI_PXMT_RANGE_CFG_CMDID
|
||||
*/
|
||||
struct wmi_pxmt_range_cfg_cmd {
|
||||
u8 dst_mac[WMI_MAC_LEN];
|
||||
__le16 range;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PXMT_SNR2_RANGE_CFG_CMDID
|
||||
*/
|
||||
struct wmi_pxmt_snr2_range_cfg_cmd {
|
||||
s8 snr2range_arr[WMI_PROX_RANGE_NUM-1];
|
||||
} __packed;
|
||||
@ -359,6 +386,23 @@ struct wmi_rf_mgmt_cmd {
|
||||
__le32 rf_mgmt_type;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI_RF_RX_TEST_CMDID
|
||||
*/
|
||||
struct wmi_rf_rx_test_cmd {
|
||||
__le32 sector;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_CORR_MEASURE_CMDID
|
||||
*/
|
||||
struct wmi_corr_measure_cmd {
|
||||
s32 freq_mhz;
|
||||
__le32 length_samples;
|
||||
__le32 iterations;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_SET_SSID_CMDID
|
||||
*/
|
||||
@ -388,6 +432,74 @@ struct wmi_bcon_ctrl_cmd {
|
||||
u8 disable_sec;
|
||||
} __packed;
|
||||
|
||||
|
||||
/******* P2P ***********/
|
||||
|
||||
/*
|
||||
* WMI_PORT_ALLOCATE_CMDID
|
||||
*/
|
||||
enum wmi_port_role {
|
||||
WMI_PORT_STA = 0,
|
||||
WMI_PORT_PCP = 1,
|
||||
WMI_PORT_AP = 2,
|
||||
WMI_PORT_P2P_DEV = 3,
|
||||
WMI_PORT_P2P_CLIENT = 4,
|
||||
WMI_PORT_P2P_GO = 5,
|
||||
};
|
||||
|
||||
struct wmi_port_allocate_cmd {
|
||||
u8 mac[WMI_MAC_LEN];
|
||||
u8 port_role;
|
||||
u8 midid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PORT_DELETE_CMDID
|
||||
*/
|
||||
struct wmi_delete_port_cmd {
|
||||
u8 mid;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_P2P_CFG_CMDID
|
||||
*/
|
||||
enum wmi_discovery_mode {
|
||||
WMI_DISCOVERY_MODE_NON_OFFLOAD = 0,
|
||||
WMI_DISCOVERY_MODE_OFFLOAD = 1,
|
||||
};
|
||||
|
||||
struct wmi_p2p_cfg_cmd {
|
||||
u8 discovery_mode; /* wmi_discovery_mode */
|
||||
u8 channel;
|
||||
__le16 bcon_interval; /* base to listen/search duration calculation */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_POWER_MGMT_CFG_CMDID
|
||||
*/
|
||||
enum wmi_power_source_type {
|
||||
WMI_POWER_SOURCE_BATTERY = 0,
|
||||
WMI_POWER_SOURCE_OTHER = 1,
|
||||
};
|
||||
|
||||
struct wmi_power_mgmt_cfg_cmd {
|
||||
u8 power_source; /* wmi_power_source_type */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PCP_START_CMDID
|
||||
*/
|
||||
struct wmi_pcp_start_cmd {
|
||||
__le16 bcon_interval;
|
||||
u8 reserved0[10];
|
||||
u8 network_type;
|
||||
u8 channel;
|
||||
u8 disable_sec_offload;
|
||||
u8 disable_sec;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_SW_TX_REQ_CMDID
|
||||
*/
|
||||
@ -435,16 +547,17 @@ enum wmi_vring_cfg_schd_params_priority {
|
||||
WMI_SCH_PRIO_HIGH = 1,
|
||||
};
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
|
||||
struct wmi_vring_cfg {
|
||||
struct wmi_sw_ring_cfg tx_sw_ring;
|
||||
u8 ringid; /* 0-23 vrings */
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 encap_trans_type;
|
||||
@ -501,8 +614,14 @@ struct wmi_vring_ba_dis_cmd {
|
||||
*/
|
||||
struct wmi_notify_req_cmd {
|
||||
u8 cid;
|
||||
u8 reserved[3];
|
||||
u8 year;
|
||||
u8 month;
|
||||
u8 day;
|
||||
__le32 interval_usec;
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u8 second;
|
||||
u8 miliseconds;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -548,6 +667,11 @@ enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type {
|
||||
WMI_NWIFI_RX_TRANS_MODE_PBSS2STA = 2,
|
||||
};
|
||||
|
||||
enum wmi_cfg_rx_chain_cmd_reorder_type {
|
||||
WMI_RX_HW_REORDER = 0,
|
||||
WMI_RX_SW_REORDER = 1,
|
||||
};
|
||||
|
||||
struct wmi_cfg_rx_chain_cmd {
|
||||
__le32 action;
|
||||
struct wmi_sw_ring_cfg rx_sw_ring;
|
||||
@ -596,7 +720,8 @@ struct wmi_cfg_rx_chain_cmd {
|
||||
__le16 wb_thrsh;
|
||||
__le32 itr_value;
|
||||
__le16 host_thrsh;
|
||||
u8 reserved[2];
|
||||
u8 reorder_type;
|
||||
u8 reserved;
|
||||
struct wmi_sniffer_cfg sniffer_cfg;
|
||||
} __packed;
|
||||
|
||||
@ -604,15 +729,7 @@ struct wmi_cfg_rx_chain_cmd {
|
||||
* WMI_RCP_ADDBA_RESP_CMDID
|
||||
*/
|
||||
struct wmi_rcp_addba_resp_cmd {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 dialog_token;
|
||||
__le16 status_code;
|
||||
__le16 ba_param_set; /* ieee80211_ba_parameterset field to send */
|
||||
@ -623,15 +740,7 @@ struct wmi_rcp_addba_resp_cmd {
|
||||
* WMI_RCP_DELBA_CMDID
|
||||
*/
|
||||
struct wmi_rcp_delba_cmd {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 reserved;
|
||||
__le16 reason;
|
||||
} __packed;
|
||||
@ -640,15 +749,7 @@ struct wmi_rcp_delba_cmd {
|
||||
* WMI_RCP_ADDBA_REQ_CMDID
|
||||
*/
|
||||
struct wmi_rcp_addba_req_cmd {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 dialog_token;
|
||||
/* ieee80211_ba_parameterset field as it received */
|
||||
__le16 ba_param_set;
|
||||
@ -665,7 +766,6 @@ struct wmi_set_mac_address_cmd {
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI_EAPOL_TX_CMDID
|
||||
*/
|
||||
@ -691,6 +791,17 @@ struct wmi_echo_cmd {
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_TEMP_SENSE_CMDID
|
||||
*
|
||||
* Measure MAC and radio temperatures
|
||||
*/
|
||||
struct wmi_temp_sense_cmd {
|
||||
__le32 measure_marlon_m_en;
|
||||
__le32 measure_marlon_r_en;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI Events
|
||||
*/
|
||||
@ -699,7 +810,6 @@ struct wmi_echo_cmd {
|
||||
* List of Events (target to host)
|
||||
*/
|
||||
enum wmi_event_id {
|
||||
WMI_IMM_RSP_EVENTID = 0x0000,
|
||||
WMI_READY_EVENTID = 0x1001,
|
||||
WMI_CONNECT_EVENTID = 0x1002,
|
||||
WMI_DISCONNECT_EVENTID = 0x1003,
|
||||
@ -709,13 +819,9 @@ enum wmi_event_id {
|
||||
WMI_FW_READY_EVENTID = 0x1801,
|
||||
WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200,
|
||||
WMI_ECHO_RSP_EVENTID = 0x1803,
|
||||
WMI_CONFIG_MAC_DONE_EVENTID = 0x1805,
|
||||
WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806,
|
||||
WMI_ADD_STATION_DONE_EVENTID = 0x1807,
|
||||
WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808,
|
||||
WMI_PHY_GET_STATISTICS_EVENTID = 0x1809,
|
||||
WMI_FS_TUNE_DONE_EVENTID = 0x180a,
|
||||
WMI_CORR_MEASURE_DONE_EVENTID = 0x180b,
|
||||
WMI_CORR_MEASURE_EVENTID = 0x180b,
|
||||
WMI_READ_RSSI_EVENTID = 0x180c,
|
||||
WMI_TEMP_SENSE_DONE_EVENTID = 0x180e,
|
||||
WMI_DC_CALIB_DONE_EVENTID = 0x180f,
|
||||
WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
|
||||
@ -727,10 +833,9 @@ enum wmi_event_id {
|
||||
WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
|
||||
WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a,
|
||||
WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181d,
|
||||
|
||||
WMI_RF_RX_TEST_DONE_EVENTID = 0x181e,
|
||||
WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
|
||||
WMI_VRING_CFG_DONE_EVENTID = 0x1821,
|
||||
WMI_RX_ON_DONE_EVENTID = 0x1822,
|
||||
WMI_BA_STATUS_EVENTID = 0x1823,
|
||||
WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
|
||||
WMI_ADDBA_RESP_SENT_EVENTID = 0x1825,
|
||||
@ -738,7 +843,6 @@ enum wmi_event_id {
|
||||
WMI_GET_SSID_EVENTID = 0x1828,
|
||||
WMI_GET_PCP_CHANNEL_EVENTID = 0x182a,
|
||||
WMI_SW_TX_COMPLETE_EVENTID = 0x182b,
|
||||
WMI_RX_OFF_DONE_EVENTID = 0x182c,
|
||||
|
||||
WMI_READ_MAC_RXQ_EVENTID = 0x1830,
|
||||
WMI_READ_MAC_TXQ_EVENTID = 0x1831,
|
||||
@ -765,7 +869,16 @@ enum wmi_event_id {
|
||||
WMI_UNIT_TEST_EVENTID = 0x1900,
|
||||
WMI_FLASH_READ_DONE_EVENTID = 0x1902,
|
||||
WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
|
||||
|
||||
/*P2P*/
|
||||
WMI_PORT_ALLOCATED_EVENTID = 0x1911,
|
||||
WMI_PORT_DELETED_EVENTID = 0x1912,
|
||||
WMI_LISTEN_STARTED_EVENTID = 0x1914,
|
||||
WMI_SEARCH_STARTED_EVENTID = 0x1915,
|
||||
WMI_DISCOVERY_STARTED_EVENTID = 0x1916,
|
||||
WMI_DISCOVERY_STOPPED_EVENTID = 0x1917,
|
||||
WMI_PCP_STARTED_EVENTID = 0x1918,
|
||||
WMI_PCP_STOPPED_EVENTID = 0x1919,
|
||||
WMI_PCP_FACTOR_EVENTID = 0x191a,
|
||||
WMI_SET_CHANNEL_EVENTID = 0x9000,
|
||||
WMI_ASSOC_REQ_EVENTID = 0x9001,
|
||||
WMI_EAPOL_RX_EVENTID = 0x9002,
|
||||
@ -777,6 +890,12 @@ enum wmi_event_id {
|
||||
* Events data structures
|
||||
*/
|
||||
|
||||
|
||||
enum wmi_fw_status {
|
||||
WMI_FW_STATUS_SUCCESS,
|
||||
WMI_FW_STATUS_FAILURE,
|
||||
};
|
||||
|
||||
/*
|
||||
* WMI_RF_MGMT_STATUS_EVENTID
|
||||
*/
|
||||
@ -857,7 +976,7 @@ struct wmi_ready_event {
|
||||
__le32 abi_version;
|
||||
u8 mac[WMI_MAC_LEN];
|
||||
u8 phy_capability; /* enum wmi_phy_capability */
|
||||
u8 reserved;
|
||||
u8 numof_additional_mids;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -876,6 +995,8 @@ struct wmi_notify_req_done_event {
|
||||
__le16 other_rx_sector;
|
||||
__le16 other_tx_sector;
|
||||
__le16 range;
|
||||
u8 sqi;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -951,27 +1072,15 @@ struct wmi_vring_ba_status_event {
|
||||
* WMI_DELBA_EVENTID
|
||||
*/
|
||||
struct wmi_delba_event {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 from_initiator;
|
||||
__le16 reason;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI_VRING_CFG_DONE_EVENTID
|
||||
*/
|
||||
enum wmi_vring_cfg_done_event_status {
|
||||
WMI_VRING_CFG_SUCCESS = 0,
|
||||
WMI_VRING_CFG_FAILURE = 1,
|
||||
};
|
||||
|
||||
struct wmi_vring_cfg_done_event {
|
||||
u8 ringid;
|
||||
u8 status;
|
||||
@ -982,21 +1091,8 @@ struct wmi_vring_cfg_done_event {
|
||||
/*
|
||||
* WMI_ADDBA_RESP_SENT_EVENTID
|
||||
*/
|
||||
enum wmi_rcp_addba_resp_sent_event_status {
|
||||
WMI_ADDBA_SUCCESS = 0,
|
||||
WMI_ADDBA_FAIL = 1,
|
||||
};
|
||||
|
||||
struct wmi_rcp_addba_resp_sent_event {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 reserved;
|
||||
__le16 status;
|
||||
} __packed;
|
||||
@ -1005,15 +1101,7 @@ struct wmi_rcp_addba_resp_sent_event {
|
||||
* WMI_RCP_ADDBA_REQ_EVENTID
|
||||
*/
|
||||
struct wmi_rcp_addba_req_event {
|
||||
|
||||
#define CIDXTID_CID_POS (0)
|
||||
#define CIDXTID_CID_LEN (4)
|
||||
#define CIDXTID_CID_MSK (0xF)
|
||||
#define CIDXTID_TID_POS (4)
|
||||
#define CIDXTID_TID_LEN (4)
|
||||
#define CIDXTID_TID_MSK (0xF0)
|
||||
u8 cidxtid;
|
||||
|
||||
u8 dialog_token;
|
||||
__le16 ba_param_set; /* ieee80211_ba_parameterset as it received */
|
||||
__le16 ba_timeout;
|
||||
@ -1055,6 +1143,7 @@ struct wmi_data_port_open_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI_GET_PCP_CHANNEL_EVENTID
|
||||
*/
|
||||
@ -1063,6 +1152,54 @@ struct wmi_get_pcp_channel_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* WMI_PORT_ALLOCATED_EVENTID
|
||||
*/
|
||||
struct wmi_port_allocated_event {
|
||||
u8 status; /* wmi_fw_status */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PORT_DELETED_EVENTID
|
||||
*/
|
||||
struct wmi_port_deleted_event {
|
||||
u8 status; /* wmi_fw_status */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_LISTEN_STARTED_EVENTID
|
||||
*/
|
||||
struct wmi_listen_started_event {
|
||||
u8 status; /* wmi_fw_status */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_SEARCH_STARTED_EVENTID
|
||||
*/
|
||||
struct wmi_search_started_event {
|
||||
u8 status; /* wmi_fw_status */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PCP_STARTED_EVENTID
|
||||
*/
|
||||
struct wmi_pcp_started_event {
|
||||
u8 status; /* wmi_fw_status */
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_PCP_FACTOR_EVENTID
|
||||
*/
|
||||
struct wmi_pcp_factor_event {
|
||||
__le32 pcp_factor;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_SW_TX_COMPLETE_EVENTID
|
||||
*/
|
||||
@ -1077,6 +1214,23 @@ struct wmi_sw_tx_complete_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_CORR_MEASURE_EVENTID
|
||||
*/
|
||||
struct wmi_corr_measure_event {
|
||||
s32 i;
|
||||
s32 q;
|
||||
s32 image_i;
|
||||
s32 image_q;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_READ_RSSI_EVENTID
|
||||
*/
|
||||
struct wmi_read_rssi_event {
|
||||
__le32 ina_rssi_adc_dbm;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_GET_SSID_EVENTID
|
||||
*/
|
||||
@ -1091,7 +1245,8 @@ struct wmi_get_ssid_event {
|
||||
struct wmi_rx_mgmt_info {
|
||||
u8 mcs;
|
||||
s8 snr;
|
||||
__le16 range;
|
||||
u8 range;
|
||||
u8 sqi;
|
||||
__le16 stype;
|
||||
__le16 status;
|
||||
__le32 len;
|
||||
@ -1113,4 +1268,14 @@ struct wmi_echo_event {
|
||||
__le32 echoed_value;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* WMI_TEMP_SENSE_DONE_EVENTID
|
||||
*
|
||||
* Measure MAC and radio temperatures
|
||||
*/
|
||||
struct wmi_temp_sense_done_event {
|
||||
__le32 marlon_m_t1000;
|
||||
__le32 marlon_r_t1000;
|
||||
} __packed;
|
||||
|
||||
#endif /* __WILOCITY_WMI_H__ */
|
||||
|
@ -131,7 +131,7 @@ config B43_PHY_LP
|
||||
|
||||
config B43_PHY_HT
|
||||
bool "Support for HT-PHY (high throughput) devices"
|
||||
depends on B43
|
||||
depends on B43 && B43_BCMA
|
||||
---help---
|
||||
Support for the HT-PHY.
|
||||
|
||||
@ -166,8 +166,8 @@ config B43_DEBUG
|
||||
Broadcom 43xx debugging.
|
||||
|
||||
This adds additional runtime sanity checks and statistics to the driver.
|
||||
These checks and statistics might me expensive and hurt runtime performance
|
||||
of your system.
|
||||
These checks and statistics might be expensive and hurt the runtime
|
||||
performance of your system.
|
||||
This also adds the b43 debugfs interface.
|
||||
|
||||
Do not enable this, unless you are debugging the driver.
|
||||
|
@ -473,6 +473,12 @@ enum {
|
||||
#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */
|
||||
#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */
|
||||
|
||||
/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */
|
||||
#define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100
|
||||
#define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200
|
||||
#define B43_BCMA_CLKCTLST_80211_PLL_ST 0x01000000
|
||||
#define B43_BCMA_CLKCTLST_PHY_PLL_ST 0x02000000
|
||||
|
||||
/* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */
|
||||
#define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */
|
||||
#define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */
|
||||
|
@ -1189,10 +1189,15 @@ static void b43_bcma_phy_reset(struct b43_wldev *dev)
|
||||
|
||||
static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
|
||||
{
|
||||
u32 req = B43_BCMA_CLKCTLST_80211_PLL_REQ |
|
||||
B43_BCMA_CLKCTLST_PHY_PLL_REQ;
|
||||
u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST |
|
||||
B43_BCMA_CLKCTLST_PHY_PLL_ST;
|
||||
|
||||
b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
|
||||
bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
|
||||
b43_bcma_phy_reset(dev);
|
||||
bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true);
|
||||
bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -154,45 +154,9 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Various PHY ops
|
||||
* RF
|
||||
**************************************************/
|
||||
|
||||
static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i, j;
|
||||
u16 base[] = { 0x40, 0x60, 0x80 };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++) {
|
||||
for (j = 0; j < 4; j++)
|
||||
b43_phy_write(dev, B43_PHY_EXTG(base[i] + j), 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++)
|
||||
b43_phy_write(dev, B43_PHY_EXTG(base[i] + 0xc), 0);
|
||||
}
|
||||
|
||||
/* Some unknown AFE (Analog Frondned) op */
|
||||
static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
const u16 ctl_regs[3][2] = {
|
||||
{ B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
|
||||
{ B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
|
||||
{ B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
|
||||
};
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* TODO: verify masks&sets */
|
||||
b43_phy_set(dev, ctl_regs[i][1], 0x4);
|
||||
b43_phy_set(dev, ctl_regs[i][0], 0x4);
|
||||
b43_phy_mask(dev, ctl_regs[i][1], ~0x1);
|
||||
b43_phy_set(dev, ctl_regs[i][0], 0x1);
|
||||
b43_httab_write(dev, B43_HTTAB16(8, 5 + (i * 0x10)), 0);
|
||||
b43_phy_mask(dev, ctl_regs[i][0], ~0x4);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
|
||||
{
|
||||
u8 i;
|
||||
@ -214,6 +178,96 @@ static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
|
||||
b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
|
||||
}
|
||||
|
||||
static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable)
|
||||
{
|
||||
struct b43_phy_ht *htphy = dev->phy.ht;
|
||||
static const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1,
|
||||
B43_PHY_HT_RF_CTL_INT_C2,
|
||||
B43_PHY_HT_RF_CTL_INT_C3 };
|
||||
int i;
|
||||
|
||||
if (enable) {
|
||||
for (i = 0; i < 3; i++)
|
||||
b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]);
|
||||
} else {
|
||||
for (i = 0; i < 3; i++)
|
||||
htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]);
|
||||
/* TODO: Does 5GHz band use different value (not 0x0400)? */
|
||||
for (i = 0; i < 3; i++)
|
||||
b43_phy_write(dev, regs[i], 0x0400);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Various PHY ops
|
||||
**************************************************/
|
||||
|
||||
static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val)
|
||||
{
|
||||
u16 tmp;
|
||||
u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN |
|
||||
B43_PHY_HT_CLASS_CTL_OFDM_EN |
|
||||
B43_PHY_HT_CLASS_CTL_WAITED_EN;
|
||||
|
||||
tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL);
|
||||
tmp &= allowed;
|
||||
tmp &= ~mask;
|
||||
tmp |= (val & mask);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void b43_phy_ht_reset_cca(struct b43_wldev *dev)
|
||||
{
|
||||
u16 bbcfg;
|
||||
|
||||
b43_phy_force_clock(dev, true);
|
||||
bbcfg = b43_phy_read(dev, B43_PHY_HT_BBCFG);
|
||||
b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg | B43_PHY_HT_BBCFG_RSTCCA);
|
||||
udelay(1);
|
||||
b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg & ~B43_PHY_HT_BBCFG_RSTCCA);
|
||||
b43_phy_force_clock(dev, false);
|
||||
|
||||
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
|
||||
}
|
||||
|
||||
static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i, j;
|
||||
u16 base[] = { 0x40, 0x60, 0x80 };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++) {
|
||||
for (j = 0; j < 4; j++)
|
||||
b43_phy_write(dev, B43_PHY_EXTG(base[i] + j), 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++)
|
||||
b43_phy_write(dev, B43_PHY_EXTG(base[i] + 0xc), 0);
|
||||
}
|
||||
|
||||
/* Some unknown AFE (Analog Frondned) op */
|
||||
static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
static const u16 ctl_regs[3][2] = {
|
||||
{ B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 },
|
||||
{ B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 },
|
||||
{ B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3},
|
||||
};
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* TODO: verify masks&sets */
|
||||
b43_phy_set(dev, ctl_regs[i][1], 0x4);
|
||||
b43_phy_set(dev, ctl_regs[i][0], 0x4);
|
||||
b43_phy_mask(dev, ctl_regs[i][1], ~0x1);
|
||||
b43_phy_set(dev, ctl_regs[i][0], 0x1);
|
||||
b43_httab_write(dev, B43_HTTAB16(8, 5 + (i * 0x10)), 0);
|
||||
b43_phy_mask(dev, ctl_regs[i][0], ~0x4);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
|
||||
{
|
||||
clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES);
|
||||
@ -240,33 +294,189 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Channel switching ops.
|
||||
* Samples
|
||||
**************************************************/
|
||||
|
||||
static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
|
||||
const struct b43_phy_ht_channeltab_e_phy *e,
|
||||
struct ieee80211_channel *new_channel)
|
||||
static void b43_phy_ht_stop_playback(struct b43_wldev *dev)
|
||||
{
|
||||
bool old_band_5ghz;
|
||||
u8 i;
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
u16 tmp;
|
||||
int i;
|
||||
|
||||
old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
|
||||
if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
|
||||
/* TODO */
|
||||
} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
|
||||
/* TODO */
|
||||
tmp = b43_phy_read(dev, B43_PHY_HT_SAMP_STAT);
|
||||
if (tmp & 0x1)
|
||||
b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, B43_PHY_HT_SAMP_CMD_STOP);
|
||||
else if (tmp & 0x2)
|
||||
b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, 0x7FFF);
|
||||
|
||||
b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0x0004);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (phy_ht->bb_mult_save[i] >= 0) {
|
||||
b43_httab_write(dev, B43_HTTAB16(13, 0x63 + i * 4),
|
||||
phy_ht->bb_mult_save[i]);
|
||||
b43_httab_write(dev, B43_HTTAB16(13, 0x67 + i * 4),
|
||||
phy_ht->bb_mult_save[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u16 b43_phy_ht_load_samples(struct b43_wldev *dev)
|
||||
{
|
||||
int i;
|
||||
u16 len = 20 << 3;
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, 0x4400);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, 0);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* TODO: some ops on PHY regs 0x0B0 and 0xC0A */
|
||||
static void b43_phy_ht_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
|
||||
u16 wait)
|
||||
{
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
u16 save_seq_mode;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (phy_ht->bb_mult_save[i] < 0)
|
||||
phy_ht->bb_mult_save[i] = b43_httab_read(dev, B43_HTTAB16(13, 0x63 + i * 4));
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_SAMP_DEP_CNT, samps - 1);
|
||||
if (loops != 0xFFFF)
|
||||
loops--;
|
||||
b43_phy_write(dev, B43_PHY_HT_SAMP_LOOP_CNT, loops);
|
||||
b43_phy_write(dev, B43_PHY_HT_SAMP_WAIT_CNT, wait);
|
||||
|
||||
save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
|
||||
b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE,
|
||||
B43_PHY_HT_RF_SEQ_MODE_CA_OVER);
|
||||
|
||||
/* TODO: find out mask bits! Do we need more function arguments? */
|
||||
b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
|
||||
b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
|
||||
b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, ~0);
|
||||
b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, 0x1);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & 1)) {
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
udelay(10);
|
||||
}
|
||||
if (i)
|
||||
b43err(dev->wl, "run samples timeout\n");
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
|
||||
}
|
||||
|
||||
static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
|
||||
{
|
||||
u16 samp;
|
||||
|
||||
samp = b43_phy_ht_load_samples(dev);
|
||||
b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* RSSI
|
||||
**************************************************/
|
||||
|
||||
static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
|
||||
u8 rssi_type)
|
||||
{
|
||||
static const u16 ctl_regs[3][2] = {
|
||||
{ B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
|
||||
{ B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
|
||||
{ B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
|
||||
};
|
||||
static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };
|
||||
int core;
|
||||
|
||||
if (core_sel == 0) {
|
||||
b43err(dev->wl, "RSSI selection for core off not implemented yet\n");
|
||||
} else {
|
||||
for (core = 0; core < 3; core++) {
|
||||
/* Check if caller requested a one specific core */
|
||||
if ((core_sel == 1 && core != 0) ||
|
||||
(core_sel == 2 && core != 1) ||
|
||||
(core_sel == 3 && core != 2))
|
||||
continue;
|
||||
|
||||
switch (rssi_type) {
|
||||
case 4:
|
||||
b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8);
|
||||
b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10);
|
||||
b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9);
|
||||
b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10);
|
||||
|
||||
b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1);
|
||||
b43_radio_write(dev, radio_r[core] | 0x159,
|
||||
0x11);
|
||||
break;
|
||||
default:
|
||||
b43err(dev->wl, "RSSI selection for type %d not implemented yet\n",
|
||||
rssi_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
|
||||
u8 nsamp)
|
||||
{
|
||||
u16 phy_regs_values[12];
|
||||
static const u16 phy_regs_to_save[] = {
|
||||
B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
|
||||
0x848, 0x841,
|
||||
B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
|
||||
0x868, 0x861,
|
||||
B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
|
||||
0x888, 0x881,
|
||||
};
|
||||
u16 tmp[3];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]);
|
||||
|
||||
b43_phy_ht_rssi_select(dev, 5, type);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
buf[i] = 0;
|
||||
|
||||
for (i = 0; i < nsamp; i++) {
|
||||
tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1);
|
||||
tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2);
|
||||
tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3);
|
||||
|
||||
buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2;
|
||||
buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2;
|
||||
buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2;
|
||||
buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2;
|
||||
buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2;
|
||||
buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Tx/Rx
|
||||
**************************************************/
|
||||
|
||||
static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO: separated function? */
|
||||
for (i = 0; i < 3; i++) {
|
||||
u16 mask;
|
||||
u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
|
||||
@ -283,6 +493,256 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
|
||||
b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
|
||||
tmp & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
|
||||
{
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF |
|
||||
B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN |
|
||||
B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN;
|
||||
static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1,
|
||||
B43_PHY_HT_TXPCTL_CMD_C2,
|
||||
B43_PHY_HT_TXPCTL_CMD_C3 };
|
||||
int i;
|
||||
|
||||
if (!enable) {
|
||||
if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) {
|
||||
/* We disable enabled TX pwr ctl, save it's state */
|
||||
/*
|
||||
* TODO: find the registers. On N-PHY they were 0x1ed
|
||||
* and 0x1ee, we need 3 such a registers for HT-PHY
|
||||
*/
|
||||
}
|
||||
b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits);
|
||||
} else {
|
||||
b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits);
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
for (i = 0; i < 3; i++)
|
||||
b43_phy_write(dev, cmd_regs[i], 0x32);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (phy_ht->tx_pwr_idx[i] <=
|
||||
B43_PHY_HT_TXPCTL_CMD_C1_INIT)
|
||||
b43_phy_write(dev, cmd_regs[i],
|
||||
phy_ht->tx_pwr_idx[i]);
|
||||
}
|
||||
|
||||
phy_ht->tx_pwr_ctl = enable;
|
||||
}
|
||||
|
||||
static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
s32 rssi_buf[6];
|
||||
|
||||
/* TODO */
|
||||
|
||||
b43_phy_ht_tx_tone(dev);
|
||||
udelay(20);
|
||||
b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1);
|
||||
b43_phy_ht_stop_playback(dev);
|
||||
b43_phy_ht_reset_cca(dev);
|
||||
|
||||
phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff;
|
||||
phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff;
|
||||
phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff;
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
u8 *idle = phy_ht->idle_tssi;
|
||||
u8 target[3];
|
||||
s16 a1[3], b0[3], b1[3];
|
||||
|
||||
u16 freq = dev->phy.channel_freq;
|
||||
int i, c;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
for (c = 0; c < 3; c++) {
|
||||
target[c] = sprom->core_pwr_info[c].maxpwr_2g;
|
||||
a1[c] = sprom->core_pwr_info[c].pa_2g[0];
|
||||
b0[c] = sprom->core_pwr_info[c].pa_2g[1];
|
||||
b1[c] = sprom->core_pwr_info[c].pa_2g[2];
|
||||
}
|
||||
} else if (freq >= 4900 && freq < 5100) {
|
||||
for (c = 0; c < 3; c++) {
|
||||
target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
|
||||
a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
|
||||
b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
|
||||
b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
|
||||
}
|
||||
} else if (freq >= 5100 && freq < 5500) {
|
||||
for (c = 0; c < 3; c++) {
|
||||
target[c] = sprom->core_pwr_info[c].maxpwr_5g;
|
||||
a1[c] = sprom->core_pwr_info[c].pa_5g[0];
|
||||
b0[c] = sprom->core_pwr_info[c].pa_5g[1];
|
||||
b1[c] = sprom->core_pwr_info[c].pa_5g[2];
|
||||
}
|
||||
} else if (freq >= 5500) {
|
||||
for (c = 0; c < 3; c++) {
|
||||
target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
|
||||
a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
|
||||
b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
|
||||
b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
|
||||
}
|
||||
} else {
|
||||
target[0] = target[1] = target[2] = 52;
|
||||
a1[0] = a1[1] = a1[2] = -424;
|
||||
b0[0] = b0[1] = b0[2] = 5612;
|
||||
b1[0] = b1[1] = b1[2] = -1393;
|
||||
}
|
||||
|
||||
b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN);
|
||||
b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1,
|
||||
~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF);
|
||||
|
||||
/* TODO: Does it depend on sprom->fem.ghz2.tssipos? */
|
||||
b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000);
|
||||
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1,
|
||||
~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2,
|
||||
~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3,
|
||||
~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19);
|
||||
|
||||
b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
|
||||
B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF);
|
||||
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
|
||||
~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1,
|
||||
idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
|
||||
~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2,
|
||||
idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2,
|
||||
~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3,
|
||||
idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT);
|
||||
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID,
|
||||
0xf0);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2,
|
||||
0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT);
|
||||
#if 0
|
||||
/* TODO: what to mask/set? */
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0)
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0)
|
||||
#endif
|
||||
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
|
||||
~B43_PHY_HT_TXPCTL_TARG_PWR_C1,
|
||||
target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
|
||||
~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF,
|
||||
target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2,
|
||||
~B43_PHY_HT_TXPCTL_TARG_PWR2_C3,
|
||||
target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT);
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
s32 num, den, pwr;
|
||||
u32 regval[64];
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
num = 8 * (16 * b0[c] + b1[c] * i);
|
||||
den = 32768 + a1[c] * i;
|
||||
pwr = max((4 * num + den / 2) / den, -8);
|
||||
regval[i] = pwr;
|
||||
}
|
||||
b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Channel switching ops.
|
||||
**************************************************/
|
||||
|
||||
static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
|
||||
struct ieee80211_channel *new_channel)
|
||||
{
|
||||
struct bcma_device *core = dev->dev->bdev;
|
||||
int spuravoid = 0;
|
||||
u16 tmp;
|
||||
|
||||
/* Check for 13 and 14 is just a guess, we don't have enough logs. */
|
||||
if (new_channel->hw_value == 13 || new_channel->hw_value == 14)
|
||||
spuravoid = 1;
|
||||
bcma_core_pll_ctl(core, B43_BCMA_CLKCTLST_PHY_PLL_REQ, 0, false);
|
||||
bcma_pmu_spuravoid_pllupdate(&core->bus->drv_cc, spuravoid);
|
||||
bcma_core_pll_ctl(core,
|
||||
B43_BCMA_CLKCTLST_80211_PLL_REQ |
|
||||
B43_BCMA_CLKCTLST_PHY_PLL_REQ,
|
||||
B43_BCMA_CLKCTLST_80211_PLL_ST |
|
||||
B43_BCMA_CLKCTLST_PHY_PLL_ST, false);
|
||||
|
||||
/* Values has been taken from wlc_bmac_switch_macfreq comments */
|
||||
switch (spuravoid) {
|
||||
case 2: /* 126MHz */
|
||||
tmp = 0x2082;
|
||||
break;
|
||||
case 1: /* 123MHz */
|
||||
tmp = 0x5341;
|
||||
break;
|
||||
default: /* 120MHz */
|
||||
tmp = 0x8889;
|
||||
}
|
||||
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
|
||||
/* TODO: reset PLL */
|
||||
|
||||
if (spuravoid)
|
||||
b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX);
|
||||
else
|
||||
b43_phy_mask(dev, B43_PHY_HT_BBCFG,
|
||||
~B43_PHY_HT_BBCFG_RSTRX & 0xFFFF);
|
||||
|
||||
b43_phy_ht_reset_cca(dev);
|
||||
}
|
||||
|
||||
static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
|
||||
const struct b43_phy_ht_channeltab_e_phy *e,
|
||||
struct ieee80211_channel *new_channel)
|
||||
{
|
||||
bool old_band_5ghz;
|
||||
|
||||
old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
|
||||
if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
|
||||
/* TODO */
|
||||
} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
|
||||
b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);
|
||||
|
||||
if (new_channel->hw_value == 14) {
|
||||
b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN, 0);
|
||||
b43_phy_set(dev, B43_PHY_HT_TEST, 0x0800);
|
||||
} else {
|
||||
b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN,
|
||||
B43_PHY_HT_CLASS_CTL_OFDM_EN);
|
||||
if (new_channel->band == IEEE80211_BAND_2GHZ)
|
||||
b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840);
|
||||
}
|
||||
|
||||
if (1) /* TODO: On N it's for early devices only, what about HT? */
|
||||
b43_phy_ht_tx_power_fix(dev);
|
||||
|
||||
b43_phy_ht_spur_avoid(dev, new_channel);
|
||||
|
||||
b43_phy_write(dev, 0x017e, 0x3830);
|
||||
}
|
||||
@ -337,14 +797,29 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_ht *phy_ht = phy->ht;
|
||||
int i;
|
||||
|
||||
memset(phy_ht, 0, sizeof(*phy_ht));
|
||||
|
||||
phy_ht->tx_pwr_ctl = true;
|
||||
for (i = 0; i < 3; i++)
|
||||
phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
phy_ht->bb_mult_save[i] = -1;
|
||||
}
|
||||
|
||||
static int b43_phy_ht_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_ht *phy_ht = dev->phy.ht;
|
||||
u16 tmp;
|
||||
u16 clip_state[3];
|
||||
bool saved_tx_pwr_ctl;
|
||||
|
||||
if (dev->dev->bus_type != B43_BUS_BCMA) {
|
||||
b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
b43_phy_ht_tables_init(dev);
|
||||
|
||||
@ -357,9 +832,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
|
||||
|
||||
b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);
|
||||
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0);
|
||||
|
||||
b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
|
||||
b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
|
||||
@ -371,8 +846,11 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
|
||||
if (0) /* TODO: condition */
|
||||
; /* TODO: PHY op on reg 0x217 */
|
||||
|
||||
b43_phy_read(dev, 0xb0); /* TODO: what for? */
|
||||
b43_phy_set(dev, 0xb0, 0x1);
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
|
||||
b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, 0);
|
||||
else
|
||||
b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN,
|
||||
B43_PHY_HT_CLASS_CTL_CCK_EN);
|
||||
|
||||
b43_phy_set(dev, 0xb1, 0x91);
|
||||
b43_phy_write(dev, 0x32f, 0x0003);
|
||||
@ -448,12 +926,13 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
|
||||
|
||||
b43_mac_phy_clock_set(dev, true);
|
||||
|
||||
b43_phy_ht_pa_override(dev, false);
|
||||
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
|
||||
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
|
||||
|
||||
/* TODO: PHY op on reg 0xb0 */
|
||||
b43_phy_ht_pa_override(dev, true);
|
||||
|
||||
/* TODO: Should we restore it? Or store it in global PHY info? */
|
||||
b43_phy_ht_classifier(dev, 0, 0);
|
||||
b43_phy_ht_read_clip_detection(dev, clip_state);
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
@ -462,6 +941,13 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
|
||||
b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
|
||||
B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);
|
||||
|
||||
saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl;
|
||||
b43_phy_ht_tx_power_fix(dev);
|
||||
b43_phy_ht_tx_power_ctl(dev, false);
|
||||
b43_phy_ht_tx_power_ctl_idle_tssi(dev);
|
||||
b43_phy_ht_tx_power_ctl_setup(dev);
|
||||
b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -506,19 +992,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
|
||||
static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
|
||||
{
|
||||
if (on) {
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000);
|
||||
} else {
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff);
|
||||
b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,18 +12,60 @@
|
||||
#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */
|
||||
#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */
|
||||
#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */
|
||||
#define B43_PHY_HT_CLASS_CTL 0x0B0 /* Classifier control */
|
||||
#define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */
|
||||
#define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */
|
||||
#define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */
|
||||
#define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */
|
||||
#define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */
|
||||
#define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */
|
||||
#define B43_PHY_HT_SAMP_LOOP_CNT 0x0C4 /* Sample loop count */
|
||||
#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */
|
||||
#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */
|
||||
#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
|
||||
#define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */
|
||||
#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */
|
||||
#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */
|
||||
#define B43_PHY_HT_BW1 0x1CE
|
||||
#define B43_PHY_HT_BW2 0x1CF
|
||||
#define B43_PHY_HT_BW3 0x1D0
|
||||
#define B43_PHY_HT_BW4 0x1D1
|
||||
#define B43_PHY_HT_BW5 0x1D2
|
||||
#define B43_PHY_HT_BW6 0x1D3
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C1 0x1E7 /* TX power control command */
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C1_INIT 0x007F /* Init */
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
|
||||
#define B43_PHY_HT_TXPCTL_N 0x1E8 /* TX power control N num */
|
||||
#define B43_PHY_HT_TXPCTL_N_TSSID 0x00FF /* N TSSI delay */
|
||||
#define B43_PHY_HT_TXPCTL_N_TSSID_SHIFT 0
|
||||
#define B43_PHY_HT_TXPCTL_N_NPTIL2 0x0700 /* N PT integer log2 */
|
||||
#define B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT 8
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI 0x1E9 /* TX power control idle TSSI */
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1 0x003F
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT 0
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2 0x3F00
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT 8
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF 0x8000 /* Raw TSSI offset bin format */
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR 0x1EA /* TX power control target power */
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR_C1 0x00FF /* Power 0 */
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
|
||||
#define B43_PHY_HT_RSSI_C1 0x219
|
||||
#define B43_PHY_HT_RSSI_C2 0x21A
|
||||
#define B43_PHY_HT_RSSI_C3 0x21B
|
||||
|
||||
#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
|
||||
#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
|
||||
#define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E)
|
||||
|
||||
#define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000)
|
||||
#define B43_PHY_HT_RF_SEQ_MODE_CA_OVER 0x0001 /* Core active override */
|
||||
#define B43_PHY_HT_RF_SEQ_MODE_TR_OVER 0x0002 /* Trigger override */
|
||||
#define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003)
|
||||
#define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */
|
||||
#define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */
|
||||
@ -36,12 +78,27 @@
|
||||
|
||||
#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)
|
||||
|
||||
#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110)
|
||||
#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111)
|
||||
#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114)
|
||||
#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115)
|
||||
#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118)
|
||||
#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119)
|
||||
#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c)
|
||||
#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c)
|
||||
#define B43_PHY_HT_RF_CTL_INT_C3 B43_PHY_EXTG(0x08c)
|
||||
|
||||
#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
|
||||
#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
|
||||
#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
|
||||
#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115)
|
||||
#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
|
||||
#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)
|
||||
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
|
||||
#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI2 B43_PHY_EXTG(0x165) /* TX power control idle TSSI */
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3 0x003F
|
||||
#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT 0
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF
|
||||
#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0
|
||||
|
||||
#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
|
||||
|
||||
|
||||
/* Values for PHY registers used on channel switching */
|
||||
@ -56,6 +113,14 @@ struct b43_phy_ht_channeltab_e_phy {
|
||||
|
||||
|
||||
struct b43_phy_ht {
|
||||
u16 rf_ctl_int_save[3];
|
||||
|
||||
bool tx_pwr_ctl;
|
||||
u8 tx_pwr_idx[3];
|
||||
|
||||
s32 bb_mult_save[3];
|
||||
|
||||
u8 idle_tssi[3];
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,8 +12,9 @@ config BRCMSMAC
|
||||
select CORDIC
|
||||
---help---
|
||||
This module adds support for PCIe wireless adapters based on Broadcom
|
||||
IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
|
||||
be called brcmsmac.ko.
|
||||
IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
|
||||
be available if you select BCMA_DRIVER_GPIO. If you choose to build a
|
||||
module, the driver will be called brcmsmac.ko.
|
||||
|
||||
config BRCMFMAC
|
||||
tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
|
||||
|
@ -26,6 +26,7 @@ brcmfmac-objs += \
|
||||
wl_cfg80211.o \
|
||||
fwil.o \
|
||||
fweh.o \
|
||||
fwsignal.o \
|
||||
p2p.o \
|
||||
dhd_cdc.o \
|
||||
dhd_common.o \
|
||||
@ -39,3 +40,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
|
||||
usb.o
|
||||
brcmfmac-$(CONFIG_BRCMDBG) += \
|
||||
dhd_dbg.o
|
||||
brcmfmac-$(CONFIG_BRCM_TRACING) += \
|
||||
tracepoint.o
|
||||
|
@ -501,6 +501,7 @@ struct brcmf_dcmd {
|
||||
/* Forward decls for struct brcmf_pub (see below) */
|
||||
struct brcmf_proto; /* device communication protocol info */
|
||||
struct brcmf_cfg80211_dev; /* cfg80211 device info */
|
||||
struct brcmf_fws_info; /* firmware signalling info */
|
||||
|
||||
/* Common structure for module and instance linkage */
|
||||
struct brcmf_pub {
|
||||
@ -527,6 +528,10 @@ struct brcmf_pub {
|
||||
unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
|
||||
|
||||
struct brcmf_fweh_info fweh;
|
||||
|
||||
bool fw_signals;
|
||||
struct brcmf_fws_info *fws;
|
||||
spinlock_t fws_spinlock;
|
||||
#ifdef DEBUG
|
||||
struct dentry *dbgfs_dir;
|
||||
#endif
|
||||
@ -582,7 +587,7 @@ extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len);
|
||||
|
||||
/* Remove any protocol-specific data header. */
|
||||
extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
|
||||
extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *rxp);
|
||||
|
||||
extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
|
@ -134,7 +134,7 @@ extern void brcmf_dev_reset(struct device *dev);
|
||||
/* Indication from bus module to change flow-control state */
|
||||
extern void brcmf_txflowblock(struct device *dev, bool state);
|
||||
|
||||
/* Notify tx completion */
|
||||
/* Notify the bus has transferred the tx packet to firmware */
|
||||
extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
|
||||
bool success);
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "dhd.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "fwsignal.h"
|
||||
#include "dhd_dbg.h"
|
||||
|
||||
struct brcmf_proto_cdc_dcmd {
|
||||
@ -71,13 +72,26 @@ struct brcmf_proto_cdc_dcmd {
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
|
||||
((idx) << BDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
/**
|
||||
* struct brcmf_proto_bdc_header - BDC header format
|
||||
*
|
||||
* @flags: flags contain protocol and checksum info.
|
||||
* @priority: 802.1d priority and USB flow control info (bit 4:7).
|
||||
* @flags2: additional flags containing dongle interface index.
|
||||
* @data_offset: start of packet data. header is following by firmware signals.
|
||||
*/
|
||||
struct brcmf_proto_bdc_header {
|
||||
u8 flags;
|
||||
u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
|
||||
u8 priority;
|
||||
u8 flags2;
|
||||
u8 data_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* maximum length of firmware signal data between
|
||||
* the BDC header and packet data in the tx path.
|
||||
*/
|
||||
#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
|
||||
#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
|
||||
@ -258,7 +272,7 @@ static void pkt_set_sum_good(struct sk_buff *skb, bool x)
|
||||
skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
|
||||
}
|
||||
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
@ -266,7 +280,6 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
brcmf_dbg(CDC, "Enter\n");
|
||||
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
|
||||
skb_push(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
@ -277,11 +290,11 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
|
||||
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->data_offset = 0;
|
||||
h->data_offset = offset;
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
}
|
||||
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
@ -328,7 +341,10 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
|
||||
pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
|
||||
|
||||
skb_pull(pktbuf, BDC_HEADER_LEN);
|
||||
skb_pull(pktbuf, h->data_offset << 2);
|
||||
if (do_fws)
|
||||
brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
|
||||
else
|
||||
skb_pull(pktbuf, h->data_offset << 2);
|
||||
|
||||
if (pktbuf->len == 0)
|
||||
return -ENODATA;
|
||||
@ -350,7 +366,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
|
||||
}
|
||||
|
||||
drvr->prot = cdc;
|
||||
drvr->hdrlen += BDC_HEADER_LEN;
|
||||
drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
|
||||
sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "fwil.h"
|
||||
#include "tracepoint.h"
|
||||
|
||||
#define PKTFILTER_BUF_SIZE 128
|
||||
#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
|
||||
@ -373,3 +374,35 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
void __brcmf_err(const char *func, const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
pr_err("%s: %pV", func, &vaf);
|
||||
trace_brcmf_err(func, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_BRCM_TRACING) || defined(CONFIG_BRCMDBG)
|
||||
void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf = {
|
||||
.fmt = fmt,
|
||||
};
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
if (brcmf_msg_level & level)
|
||||
pr_debug("%s %pV", func, &vaf);
|
||||
trace_brcmf_dbg(level, func, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "tracepoint.h"
|
||||
|
||||
static struct dentry *root_folder;
|
||||
|
||||
@ -123,3 +124,44 @@ void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
|
||||
debugfs_create_file("counters", S_IRUGO, dentry,
|
||||
sdcnt, &brcmf_debugfs_sdio_counter_ops);
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct brcmf_fws_stats *fwstats = f->private_data;
|
||||
char buf[100];
|
||||
int res;
|
||||
|
||||
/* only allow read from start */
|
||||
if (*ppos > 0)
|
||||
return 0;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"header_pulls: %u\n"
|
||||
"header_only_pkt: %u\n"
|
||||
"tlv_parse_failed: %u\n"
|
||||
"tlv_invalid_type: %u\n",
|
||||
fwstats->header_pulls,
|
||||
fwstats->header_only_pkt,
|
||||
fwstats->tlv_parse_failed,
|
||||
fwstats->tlv_invalid_type);
|
||||
|
||||
return simple_read_from_buffer(data, count, ppos, buf, res);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_debugfs_fws_stats_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_debugfs_fws_stats_read
|
||||
};
|
||||
|
||||
void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats)
|
||||
{
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dentry))
|
||||
debugfs_create_file("fws_stats", S_IRUGO, dentry,
|
||||
stats, &brcmf_debugfs_fws_stats_ops);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
* debugging is not selected. When debugging the driver error
|
||||
* messages are as important as other tracing or even more so.
|
||||
*/
|
||||
#ifndef CONFIG_BRCM_TRACING
|
||||
#ifdef CONFIG_BRCMDBG
|
||||
#define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__)
|
||||
#else
|
||||
@ -52,15 +53,21 @@
|
||||
pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
#else
|
||||
__printf(2, 3)
|
||||
void __brcmf_err(const char *func, const char *fmt, ...);
|
||||
#define brcmf_err(fmt, ...) \
|
||||
__brcmf_err(__func__, fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BRCM_TRACING)
|
||||
__printf(3, 4)
|
||||
void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...);
|
||||
#define brcmf_dbg(level, fmt, ...) \
|
||||
do { \
|
||||
if (brcmf_msg_level & BRCMF_##level##_VAL) \
|
||||
pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||
__brcmf_dbg(BRCMF_##level##_VAL, __func__, \
|
||||
fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
|
||||
#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
|
||||
#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
|
||||
@ -69,7 +76,7 @@ do { \
|
||||
#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL)
|
||||
#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL)
|
||||
|
||||
#else /* (defined DEBUG) || (defined DEBUG) */
|
||||
#else /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
|
||||
|
||||
#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
|
||||
|
||||
@ -81,7 +88,7 @@ do { \
|
||||
#define BRCMF_EVENT_ON() 0
|
||||
#define BRCMF_FIL_ON() 0
|
||||
|
||||
#endif /* defined(DEBUG) */
|
||||
#endif /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
|
||||
|
||||
#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \
|
||||
do { \
|
||||
@ -125,6 +132,13 @@ struct brcmf_sdio_count {
|
||||
ulong rx_readahead_cnt; /* packets where header read-ahead was used */
|
||||
};
|
||||
|
||||
struct brcmf_fws_stats {
|
||||
u32 tlv_parse_failed;
|
||||
u32 tlv_invalid_type;
|
||||
u32 header_only_pkt;
|
||||
u32 header_pulls;
|
||||
};
|
||||
|
||||
struct brcmf_pub;
|
||||
#ifdef DEBUG
|
||||
void brcmf_debugfs_init(void);
|
||||
@ -134,6 +148,8 @@ void brcmf_debugfs_detach(struct brcmf_pub *drvr);
|
||||
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
|
||||
void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
|
||||
struct brcmf_sdio_count *sdcnt);
|
||||
void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats);
|
||||
#else
|
||||
static inline void brcmf_debugfs_init(void)
|
||||
{
|
||||
@ -148,6 +164,10 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||
static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
|
||||
struct brcmf_fws_stats *stats)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BRCMF_DBG_H_ */
|
||||
|
@ -30,17 +30,18 @@
|
||||
#include "p2p.h"
|
||||
#include "wl_cfg80211.h"
|
||||
#include "fwil.h"
|
||||
#include "fwsignal.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */
|
||||
|
||||
/* Error bits */
|
||||
int brcmf_msg_level;
|
||||
module_param(brcmf_msg_level, int, 0);
|
||||
module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "level of debug output");
|
||||
|
||||
/* P2P0 enable */
|
||||
static int brcmf_p2p_enable;
|
||||
@ -230,7 +231,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
|
||||
atomic_inc(&ifp->pend_8021x_cnt);
|
||||
|
||||
/* If the protocol uses a data header, apply it */
|
||||
brcmf_proto_hdrpush(drvr, ifp->ifidx, skb);
|
||||
brcmf_proto_hdrpush(drvr, ifp->ifidx, 0, skb);
|
||||
|
||||
/* Use bus module to send data frame */
|
||||
ret = brcmf_bus_txdata(drvr->bus_if, skb);
|
||||
@ -283,7 +284,7 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
|
||||
skb_unlink(skb, skb_list);
|
||||
|
||||
/* process and remove protocol-specific header */
|
||||
ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
|
||||
ret = brcmf_proto_hdrpull(drvr, drvr->fw_signals, &ifidx, skb);
|
||||
ifp = drvr->iflist[ifidx];
|
||||
|
||||
if (ret || !ifp || !ifp->ndev) {
|
||||
@ -357,23 +358,29 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_pub *drvr = bus_if->drvr;
|
||||
struct brcmf_if *ifp;
|
||||
int res;
|
||||
|
||||
brcmf_proto_hdrpull(drvr, &ifidx, txp);
|
||||
res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
|
||||
|
||||
ifp = drvr->iflist[ifidx];
|
||||
if (!ifp)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
eh = (struct ethhdr *)(txp->data);
|
||||
type = ntohs(eh->h_proto);
|
||||
if (res == 0) {
|
||||
eh = (struct ethhdr *)(txp->data);
|
||||
type = ntohs(eh->h_proto);
|
||||
|
||||
if (type == ETH_P_PAE) {
|
||||
atomic_dec(&ifp->pend_8021x_cnt);
|
||||
if (waitqueue_active(&ifp->pend_8021x_wait))
|
||||
wake_up(&ifp->pend_8021x_wait);
|
||||
if (type == ETH_P_PAE) {
|
||||
atomic_dec(&ifp->pend_8021x_cnt);
|
||||
if (waitqueue_active(&ifp->pend_8021x_wait))
|
||||
wake_up(&ifp->pend_8021x_wait);
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
ifp->stats.tx_errors++;
|
||||
|
||||
done:
|
||||
brcmu_pkt_buf_free_skb(txp);
|
||||
}
|
||||
|
||||
static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
|
||||
@ -873,6 +880,9 @@ int brcmf_bus_start(struct device *dev)
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
drvr->fw_signals = true;
|
||||
(void)brcmf_fws_init(drvr);
|
||||
|
||||
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
|
||||
if (drvr->config == NULL) {
|
||||
ret = -ENOMEM;
|
||||
@ -889,6 +899,8 @@ int brcmf_bus_start(struct device *dev)
|
||||
brcmf_err("failed: %d\n", ret);
|
||||
if (drvr->config)
|
||||
brcmf_cfg80211_detach(drvr->config);
|
||||
if (drvr->fws)
|
||||
brcmf_fws_deinit(drvr);
|
||||
free_netdev(ifp->ndev);
|
||||
drvr->iflist[0] = NULL;
|
||||
if (p2p_ifp) {
|
||||
@ -952,6 +964,9 @@ void brcmf_detach(struct device *dev)
|
||||
if (drvr->prot)
|
||||
brcmf_proto_detach(drvr);
|
||||
|
||||
if (drvr->fws)
|
||||
brcmf_fws_deinit(drvr);
|
||||
|
||||
brcmf_debugfs_detach(drvr);
|
||||
bus_if->drvr = NULL;
|
||||
kfree(drvr);
|
||||
|
@ -33,7 +33,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr);
|
||||
/* Add any protocol-specific data header.
|
||||
* Caller must reserve prot_hdrlen prepend space.
|
||||
*/
|
||||
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
|
||||
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
|
||||
struct sk_buff *txp);
|
||||
|
||||
/* Sets dongle media info (drv_version, mac address). */
|
||||
|
@ -1546,7 +1546,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
struct sk_buff_head pktlist; /* needed for bus interface */
|
||||
u16 pad; /* Number of pad bytes to read */
|
||||
uint rxleft = 0; /* Remaining number of frames allowed */
|
||||
int sdret; /* Return code from calls */
|
||||
int ret; /* Return code from calls */
|
||||
uint rxcount = 0; /* Total frames read */
|
||||
struct brcmf_sdio_read *rd = &bus->cur_read, rd_new;
|
||||
u8 head_read = 0;
|
||||
@ -1577,15 +1577,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
/* read header first for unknow frame length */
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
if (!rd->len) {
|
||||
sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
|
||||
ret = brcmf_sdcard_recv_buf(bus->sdiodev,
|
||||
bus->sdiodev->sbwad,
|
||||
SDIO_FUNC_2, F2SYNC,
|
||||
bus->rxhdr,
|
||||
BRCMF_FIRSTREAD);
|
||||
bus->sdcnt.f2rxhdrs++;
|
||||
if (sdret < 0) {
|
||||
if (ret < 0) {
|
||||
brcmf_err("RXHEADER FAILED: %d\n",
|
||||
sdret);
|
||||
ret);
|
||||
bus->sdcnt.rx_hdrfail++;
|
||||
brcmf_sdbrcm_rxfail(bus, true, true);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
@ -1637,14 +1637,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
skb_pull(pkt, head_read);
|
||||
pkt_align(pkt, rd->len_left, BRCMF_SDALIGN);
|
||||
|
||||
sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
|
||||
ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
|
||||
SDIO_FUNC_2, F2SYNC, pkt);
|
||||
bus->sdcnt.f2rxdata++;
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
|
||||
if (sdret < 0) {
|
||||
if (ret < 0) {
|
||||
brcmf_err("read %d bytes from channel %d failed: %d\n",
|
||||
rd->len, rd->channel, sdret);
|
||||
rd->len, rd->channel, ret);
|
||||
brcmu_pkt_buf_free_skb(pkt);
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
brcmf_sdbrcm_rxfail(bus, true,
|
||||
@ -1775,7 +1775,7 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
|
||||
/* Writes a HW/SW header into the packet and sends it. */
|
||||
/* Assumes: (a) header space already there, (b) caller holds lock */
|
||||
static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
||||
uint chan, bool free_pkt)
|
||||
uint chan)
|
||||
{
|
||||
int ret;
|
||||
u8 *frame;
|
||||
@ -1805,10 +1805,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
||||
|
||||
pkt_align(new, pkt->len, BRCMF_SDALIGN);
|
||||
memcpy(new->data, pkt->data, pkt->len);
|
||||
if (free_pkt)
|
||||
brcmu_pkt_buf_free_skb(pkt);
|
||||
/* free the pkt if canned one is not used */
|
||||
free_pkt = true;
|
||||
brcmu_pkt_buf_free_skb(pkt);
|
||||
pkt = new;
|
||||
frame = (u8 *) (pkt->data);
|
||||
/* precondition: (frame % BRCMF_SDALIGN) == 0) */
|
||||
@ -1901,10 +1898,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
||||
/* restore pkt buffer pointer before calling tx complete routine */
|
||||
skb_pull(pkt, SDPCM_HDRLEN + pad);
|
||||
brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
|
||||
|
||||
if (free_pkt)
|
||||
brcmu_pkt_buf_free_skb(pkt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1932,7 +1925,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
|
||||
spin_unlock_bh(&bus->txqlock);
|
||||
datalen = pkt->len - SDPCM_HDRLEN;
|
||||
|
||||
ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
|
||||
ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL);
|
||||
|
||||
/* In poll mode, need to check for other events */
|
||||
if (!bus->intr && cnt) {
|
||||
@ -2343,7 +2336,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
|
||||
if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
|
||||
skb_pull(pkt, SDPCM_HDRLEN);
|
||||
brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
|
||||
brcmu_pkt_buf_free_skb(pkt);
|
||||
brcmf_err("out of bus->txq !!!\n");
|
||||
ret = -ENOSR;
|
||||
} else {
|
||||
|
382
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
Normal file
382
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/err.h>
|
||||
#include <uapi/linux/nl80211.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "fwil.h"
|
||||
#include "fweh.h"
|
||||
#include "fwsignal.h"
|
||||
|
||||
/**
|
||||
* DOC: Firmware Signalling
|
||||
*
|
||||
* Firmware can send signals to host and vice versa, which are passed in the
|
||||
* data packets using TLV based header. This signalling layer is on top of the
|
||||
* BDC bus protocol layer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* single definition for firmware-driver flow control tlv's.
|
||||
*
|
||||
* each tlv is specified by BRCMF_FWS_TLV_DEF(name, ID, length).
|
||||
* A length value 0 indicates variable length tlv.
|
||||
*/
|
||||
#define BRCMF_FWS_TLV_DEFLIST \
|
||||
BRCMF_FWS_TLV_DEF(MAC_OPEN, 1, 1) \
|
||||
BRCMF_FWS_TLV_DEF(MAC_CLOSE, 2, 1) \
|
||||
BRCMF_FWS_TLV_DEF(MAC_REQUEST_CREDIT, 3, 2) \
|
||||
BRCMF_FWS_TLV_DEF(TXSTATUS, 4, 4) \
|
||||
BRCMF_FWS_TLV_DEF(PKTTAG, 5, 4) \
|
||||
BRCMF_FWS_TLV_DEF(MACDESC_ADD, 6, 8) \
|
||||
BRCMF_FWS_TLV_DEF(MACDESC_DEL, 7, 8) \
|
||||
BRCMF_FWS_TLV_DEF(RSSI, 8, 1) \
|
||||
BRCMF_FWS_TLV_DEF(INTERFACE_OPEN, 9, 1) \
|
||||
BRCMF_FWS_TLV_DEF(INTERFACE_CLOSE, 10, 1) \
|
||||
BRCMF_FWS_TLV_DEF(FIFO_CREDITBACK, 11, 8) \
|
||||
BRCMF_FWS_TLV_DEF(PENDING_TRAFFIC_BMP, 12, 2) \
|
||||
BRCMF_FWS_TLV_DEF(MAC_REQUEST_PACKET, 13, 3) \
|
||||
BRCMF_FWS_TLV_DEF(HOST_REORDER_RXPKTS, 14, 10) \
|
||||
BRCMF_FWS_TLV_DEF(TRANS_ID, 18, 6) \
|
||||
BRCMF_FWS_TLV_DEF(COMP_TXSTATUS, 19, 1) \
|
||||
BRCMF_FWS_TLV_DEF(FILLER, 255, 0)
|
||||
|
||||
/**
|
||||
* enum brcmf_fws_tlv_type - definition of tlv identifiers.
|
||||
*/
|
||||
#define BRCMF_FWS_TLV_DEF(name, id, len) \
|
||||
BRCMF_FWS_TYPE_ ## name = id,
|
||||
enum brcmf_fws_tlv_type {
|
||||
BRCMF_FWS_TLV_DEFLIST
|
||||
BRCMF_FWS_TYPE_INVALID
|
||||
};
|
||||
#undef BRCMF_FWS_TLV_DEF
|
||||
|
||||
/**
|
||||
* enum brcmf_fws_tlv_len - length values for tlvs.
|
||||
*/
|
||||
#define BRCMF_FWS_TLV_DEF(name, id, len) \
|
||||
BRCMF_FWS_TYPE_ ## name ## _LEN = len,
|
||||
enum brcmf_fws_tlv_len {
|
||||
BRCMF_FWS_TLV_DEFLIST
|
||||
};
|
||||
#undef BRCMF_FWS_TLV_DEF
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* brcmf_fws_tlv_names - array of tlv names.
|
||||
*/
|
||||
#define BRCMF_FWS_TLV_DEF(name, id, len) \
|
||||
{ id, #name },
|
||||
static struct {
|
||||
enum brcmf_fws_tlv_type id;
|
||||
const char *name;
|
||||
} brcmf_fws_tlv_names[] = {
|
||||
BRCMF_FWS_TLV_DEFLIST
|
||||
};
|
||||
#undef BRCMF_FWS_TLV_DEF
|
||||
|
||||
static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(brcmf_fws_tlv_names); i++)
|
||||
if (brcmf_fws_tlv_names[i].id == id)
|
||||
return brcmf_fws_tlv_names[i].name;
|
||||
|
||||
return "INVALID";
|
||||
}
|
||||
#else
|
||||
static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
|
||||
{
|
||||
return "NODEBUG";
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/**
|
||||
* flags used to enable tlv signalling from firmware.
|
||||
*/
|
||||
#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001
|
||||
#define BRCMF_FWS_FLAGS_XONXOFF_SIGNALS 0x0002
|
||||
#define BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS 0x0004
|
||||
#define BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008
|
||||
#define BRCMF_FWS_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010
|
||||
#define BRCMF_FWS_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020
|
||||
#define BRCMF_FWS_FLAGS_HOST_RXREORDER_ACTIVE 0x0040
|
||||
|
||||
#define BRCMF_FWS_HANGER_MAXITEMS 1024
|
||||
#define BRCMF_FWS_HANGER_ITEM_STATE_FREE 1
|
||||
#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE 2
|
||||
#define BRCMF_FWS_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
|
||||
|
||||
#define BRCMF_FWS_STATE_OPEN 1
|
||||
#define BRCMF_FWS_STATE_CLOSE 2
|
||||
|
||||
#define BRCMF_FWS_FCMODE_NONE 0
|
||||
#define BRCMF_FWS_FCMODE_IMPLIED_CREDIT 1
|
||||
#define BRCMF_FWS_FCMODE_EXPLICIT_CREDIT 2
|
||||
|
||||
#define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32
|
||||
#define BRCMF_FWS_MAX_IFNUM 16
|
||||
#define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff
|
||||
|
||||
#define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0
|
||||
#define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1
|
||||
|
||||
/**
|
||||
* FWFC packet identifier
|
||||
*
|
||||
* 32-bit packet identifier used in PKTTAG tlv from host to dongle.
|
||||
*
|
||||
* - Generated at the host (e.g. dhd)
|
||||
* - Seen as a generic sequence number by wlc except the flags field
|
||||
*
|
||||
* Generation : b[31] => generation number for this packet [host->fw]
|
||||
* OR, current generation number [fw->host]
|
||||
* Flags : b[30:27] => command, status flags
|
||||
* FIFO-AC : b[26:24] => AC-FIFO id
|
||||
* h-slot : b[23:8] => hanger-slot
|
||||
* freerun : b[7:0] => A free running counter
|
||||
*/
|
||||
#define BRCMF_FWS_PKTTAG_GENERATION_MASK 0x80000000
|
||||
#define BRCMF_FWS_PKTTAG_GENERATION_SHIFT 31
|
||||
#define BRCMF_FWS_PKTTAG_FLAGS_MASK 0x78000000
|
||||
#define BRCMF_FWS_PKTTAG_FLAGS_SHIFT 27
|
||||
#define BRCMF_FWS_PKTTAG_FIFO_MASK 0x07000000
|
||||
#define BRCMF_FWS_PKTTAG_FIFO_SHIFT 24
|
||||
#define BRCMF_FWS_PKTTAG_HSLOT_MASK 0x00ffff00
|
||||
#define BRCMF_FWS_PKTTAG_HSLOT_SHIFT 8
|
||||
#define BRCMF_FWS_PKTTAG_FREERUN_MASK 0x000000ff
|
||||
#define BRCMF_FWS_PKTTAG_FREERUN_SHIFT 0
|
||||
|
||||
#define brcmf_fws_pkttag_set_field(var, field, value) \
|
||||
brcmu_maskset32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \
|
||||
BRCMF_FWS_PKTTAG_ ## field ## _SHIFT, (value))
|
||||
#define brcmf_fws_pkttag_get_field(var, field) \
|
||||
brcmu_maskget32((var), BRCMF_FWS_PKTTAG_ ## field ## _MASK, \
|
||||
BRCMF_FWS_PKTTAG_ ## field ## _SHIFT)
|
||||
|
||||
struct brcmf_fws_info {
|
||||
struct brcmf_pub *drvr;
|
||||
struct brcmf_fws_stats stats;
|
||||
};
|
||||
|
||||
static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
|
||||
{
|
||||
brcmf_dbg(CTL, "rssi %d\n", rssi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
|
||||
{
|
||||
__le32 timestamp;
|
||||
|
||||
memcpy(×tamp, &data[2], sizeof(timestamp));
|
||||
brcmf_dbg(INFO, "received: seq %d, timestamp %d\n", data[1],
|
||||
le32_to_cpu(timestamp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* using macro so sparse checking does not complain
|
||||
* about locking imbalance.
|
||||
*/
|
||||
#define brcmf_fws_lock(drvr, flags) \
|
||||
do { \
|
||||
flags = 0; \
|
||||
spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
|
||||
} while (0)
|
||||
|
||||
/* using macro so sparse checking does not complain
|
||||
* about locking imbalance.
|
||||
*/
|
||||
#define brcmf_fws_unlock(drvr, flags) \
|
||||
spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
|
||||
|
||||
int brcmf_fws_init(struct brcmf_pub *drvr)
|
||||
{
|
||||
u32 tlv;
|
||||
int rc;
|
||||
|
||||
/* enable rssi signals */
|
||||
tlv = drvr->fw_signals ? BRCMF_FWS_FLAGS_RSSI_SIGNALS : 0;
|
||||
|
||||
spin_lock_init(&drvr->fws_spinlock);
|
||||
|
||||
drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
|
||||
if (!drvr->fws) {
|
||||
rc = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* enable proptxtstatus signaling by default */
|
||||
rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
|
||||
if (rc < 0) {
|
||||
brcmf_err("failed to set bdcv2 tlv signaling\n");
|
||||
goto fail;
|
||||
}
|
||||
/* set linkage back */
|
||||
drvr->fws->drvr = drvr;
|
||||
|
||||
/* create debugfs file for statistics */
|
||||
brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats);
|
||||
|
||||
/* TODO: remove upon feature delivery */
|
||||
brcmf_err("%s bdcv2 tlv signaling [%x]\n",
|
||||
drvr->fw_signals ? "enabled" : "disabled", tlv);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
/* disable flow control entirely */
|
||||
drvr->fw_signals = false;
|
||||
brcmf_fws_deinit(drvr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void brcmf_fws_deinit(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* free top structure */
|
||||
kfree(drvr->fws);
|
||||
drvr->fws = NULL;
|
||||
}
|
||||
|
||||
int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct brcmf_fws_info *fws = drvr->fws;
|
||||
ulong flags;
|
||||
u8 *signal_data;
|
||||
s16 data_len;
|
||||
u8 type;
|
||||
u8 len;
|
||||
u8 *data;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n",
|
||||
ifidx, skb->len, signal_len);
|
||||
|
||||
WARN_ON(signal_len > skb->len);
|
||||
|
||||
/* if flow control disabled, skip to packet data and leave */
|
||||
if (!signal_len || !drvr->fw_signals) {
|
||||
skb_pull(skb, signal_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lock during tlv parsing */
|
||||
brcmf_fws_lock(drvr, flags);
|
||||
|
||||
fws->stats.header_pulls++;
|
||||
data_len = signal_len;
|
||||
signal_data = skb->data;
|
||||
|
||||
while (data_len > 0) {
|
||||
/* extract tlv info */
|
||||
type = signal_data[0];
|
||||
|
||||
/* FILLER type is actually not a TLV, but
|
||||
* a single byte that can be skipped.
|
||||
*/
|
||||
if (type == BRCMF_FWS_TYPE_FILLER) {
|
||||
signal_data += 1;
|
||||
data_len -= 1;
|
||||
continue;
|
||||
}
|
||||
len = signal_data[1];
|
||||
data = signal_data + 2;
|
||||
|
||||
/* abort parsing when length invalid */
|
||||
if (data_len < len + 2)
|
||||
break;
|
||||
|
||||
brcmf_dbg(INFO, "tlv type=%d (%s), len=%d\n", type,
|
||||
brcmf_fws_get_tlv_name(type), len);
|
||||
switch (type) {
|
||||
case BRCMF_FWS_TYPE_MAC_OPEN:
|
||||
case BRCMF_FWS_TYPE_MAC_CLOSE:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_MAC_OPEN_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_TXSTATUS:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_TXSTATUS_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_PKTTAG:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_PKTTAG_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_MACDESC_ADD:
|
||||
case BRCMF_FWS_TYPE_MACDESC_DEL:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_MACDESC_ADD_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_RSSI:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_RSSI_LEN);
|
||||
brcmf_fws_rssi_indicate(fws, *(s8 *)data);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
|
||||
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_INTERFACE_OPEN_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_FIFO_CREDITBACK_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_MAC_REQUEST_PACKET_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS_LEN);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_TRANS_ID:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_TRANS_ID_LEN);
|
||||
brcmf_fws_dbg_seqnum_check(fws, data);
|
||||
break;
|
||||
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
|
||||
WARN_ON(len != BRCMF_FWS_TYPE_COMP_TXSTATUS_LEN);
|
||||
break;
|
||||
default:
|
||||
fws->stats.tlv_invalid_type++;
|
||||
break;
|
||||
}
|
||||
|
||||
signal_data += len + 2;
|
||||
data_len -= len + 2;
|
||||
}
|
||||
|
||||
if (data_len != 0)
|
||||
fws->stats.tlv_parse_failed++;
|
||||
|
||||
/* signalling processing result does
|
||||
* not affect the actual ethernet packet.
|
||||
*/
|
||||
skb_pull(skb, signal_len);
|
||||
|
||||
/* this may be a signal-only packet
|
||||
*/
|
||||
if (skb->len == 0)
|
||||
fws->stats.header_only_pkt++;
|
||||
|
||||
brcmf_fws_unlock(drvr, flags);
|
||||
return 0;
|
||||
}
|
25
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
Normal file
25
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FWSIGNAL_H_
|
||||
#define FWSIGNAL_H_
|
||||
|
||||
int brcmf_fws_init(struct brcmf_pub *drvr);
|
||||
void brcmf_fws_deinit(struct brcmf_pub *drvr);
|
||||
int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
|
||||
struct sk_buff *skb);
|
||||
#endif /* FWSIGNAL_H_ */
|
22
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
Normal file
22
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h> /* bug in tracepoint.h, it should include this */
|
||||
|
||||
#ifndef __CHECKER__
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "tracepoint.h"
|
||||
#endif
|
87
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
Normal file
87
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#if !defined(BRCMF_TRACEPOINT_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define BRCMF_TRACEPOINT_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#ifndef CONFIG_BRCM_TRACING
|
||||
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(...)
|
||||
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(evt_class, name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
|
||||
#endif /* CONFIG_BRCM_TRACING */
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmfmac
|
||||
|
||||
#define MAX_MSG_LEN 100
|
||||
|
||||
TRACE_EVENT(brcmf_err,
|
||||
TP_PROTO(const char *func, struct va_format *vaf),
|
||||
TP_ARGS(func, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__string(func, func)
|
||||
__dynamic_array(char, msg, MAX_MSG_LEN)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(func, func);
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
MAX_MSG_LEN, vaf->fmt,
|
||||
*vaf->va) >= MAX_MSG_LEN);
|
||||
),
|
||||
TP_printk("%s: %s", __get_str(func), __get_str(msg))
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcmf_dbg,
|
||||
TP_PROTO(u32 level, const char *func, struct va_format *vaf),
|
||||
TP_ARGS(level, func, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, level)
|
||||
__string(func, func)
|
||||
__dynamic_array(char, msg, MAX_MSG_LEN)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->level = level;
|
||||
__assign_str(func, func);
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
MAX_MSG_LEN, vaf->fmt,
|
||||
*vaf->va) >= MAX_MSG_LEN);
|
||||
),
|
||||
TP_printk("%s: %s", __get_str(func), __get_str(msg))
|
||||
);
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE tracepoint
|
||||
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCM_TRACING */
|
||||
|
||||
#endif /* BRCMF_TRACEPOINT_H_ */
|
@ -112,11 +112,6 @@ struct brcmf_usbdev_info {
|
||||
static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
|
||||
struct brcmf_usbreq *req);
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
|
||||
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@ -422,8 +417,6 @@ static void brcmf_usb_tx_complete(struct urb *urb)
|
||||
brcmf_usb_del_fromq(devinfo, req);
|
||||
|
||||
brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
|
||||
|
||||
brcmu_pkt_buf_free_skb(req->skb);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
|
||||
if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
|
||||
@ -577,15 +570,17 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(USB, "Enter, skb=%p\n", skb);
|
||||
if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
|
||||
return -EIO;
|
||||
if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
|
||||
&devinfo->tx_freecount);
|
||||
if (!req) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
brcmf_err("no req to send\n");
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
req->skb = skb;
|
||||
@ -598,18 +593,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
|
||||
if (ret) {
|
||||
brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n");
|
||||
brcmf_usb_del_fromq(devinfo, req);
|
||||
brcmu_pkt_buf_free_skb(req->skb);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
|
||||
&devinfo->tx_freecount);
|
||||
} else {
|
||||
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
|
||||
!devinfo->tx_flowblock) {
|
||||
brcmf_txflowblock(dev, true);
|
||||
devinfo->tx_flowblock = true;
|
||||
}
|
||||
&devinfo->tx_freecount);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
|
||||
!devinfo->tx_flowblock) {
|
||||
brcmf_txflowblock(dev, true);
|
||||
devinfo->tx_flowblock = true;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
brcmf_txcomplete(dev, skb, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1485,6 +1483,7 @@ static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
|
||||
|
@ -3052,16 +3052,16 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
|
||||
brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
|
||||
request->n_match_sets, request->n_ssids);
|
||||
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||
brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (!request || !request->n_ssids || !request->n_match_sets) {
|
||||
if (!request->n_ssids || !request->n_match_sets) {
|
||||
brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
|
||||
request ? request->n_ssids : 0);
|
||||
request->n_ssids);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,10 @@ BRCMSMAC_OFILES := \
|
||||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
BRCMSMAC_OFILES += led.o
|
||||
endif
|
||||
|
||||
MODULEPFX := brcmsmac
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
|
||||
|
126
drivers/net/wireless/brcm80211/brcmsmac/led.c
Normal file
126
drivers/net/wireless/brcm80211/brcmsmac/led.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/bcma/bcma_driver_chipcommon.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include "mac80211_if.h"
|
||||
#include "pub.h"
|
||||
#include "main.h"
|
||||
#include "led.h"
|
||||
|
||||
/* number of leds */
|
||||
#define BRCMS_LED_NO 4
|
||||
/* behavior mask */
|
||||
#define BRCMS_LED_BEH_MASK 0x7f
|
||||
/* activelow (polarity) bit */
|
||||
#define BRCMS_LED_AL_MASK 0x80
|
||||
/* radio enabled */
|
||||
#define BRCMS_LED_RADIO 3
|
||||
|
||||
static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
|
||||
{
|
||||
if (wl->radio_led.gpio == -1)
|
||||
return;
|
||||
|
||||
if (wl->radio_led.active_low)
|
||||
state = !state;
|
||||
|
||||
if (state)
|
||||
gpio_set_value(wl->radio_led.gpio, 1);
|
||||
else
|
||||
gpio_set_value(wl->radio_led.gpio, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Callback from the LED subsystem. */
|
||||
static void brcms_led_brightness_set(struct led_classdev *led_dev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct brcms_info *wl = container_of(led_dev,
|
||||
struct brcms_info, led_dev);
|
||||
brcms_radio_led_ctrl(wl, brightness);
|
||||
}
|
||||
|
||||
void brcms_led_unregister(struct brcms_info *wl)
|
||||
{
|
||||
if (wl->led_dev.dev)
|
||||
led_classdev_unregister(&wl->led_dev);
|
||||
if (wl->radio_led.gpio != -1)
|
||||
gpio_free(wl->radio_led.gpio);
|
||||
}
|
||||
|
||||
int brcms_led_register(struct brcms_info *wl)
|
||||
{
|
||||
int i, err;
|
||||
struct brcms_led *radio_led = &wl->radio_led;
|
||||
/* get CC core */
|
||||
struct bcma_drv_cc *cc_drv = &wl->wlc->hw->d11core->bus->drv_cc;
|
||||
struct gpio_chip *bcma_gpio = &cc_drv->gpio;
|
||||
struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
|
||||
u8 *leds[] = { &sprom->gpio0,
|
||||
&sprom->gpio1,
|
||||
&sprom->gpio2,
|
||||
&sprom->gpio3 };
|
||||
unsigned gpio = -1;
|
||||
bool active_low = false;
|
||||
|
||||
/* none by default */
|
||||
radio_led->gpio = -1;
|
||||
radio_led->active_low = false;
|
||||
|
||||
if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
|
||||
return -ENODEV;
|
||||
|
||||
/* find radio enabled LED */
|
||||
for (i = 0; i < BRCMS_LED_NO; i++) {
|
||||
u8 led = *leds[i];
|
||||
if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
|
||||
gpio = bcma_gpio->base + i;
|
||||
if (led & BRCMS_LED_AL_MASK)
|
||||
active_low = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpio == -1 || !gpio_is_valid(gpio))
|
||||
return -ENODEV;
|
||||
|
||||
/* request and configure LED gpio */
|
||||
err = gpio_request_one(gpio,
|
||||
active_low ? GPIOF_OUT_INIT_HIGH
|
||||
: GPIOF_OUT_INIT_LOW,
|
||||
"radio on");
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "requesting led gpio %d failed (err: %d)\n",
|
||||
gpio, err);
|
||||
return err;
|
||||
}
|
||||
err = gpio_direction_output(gpio, 1);
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "cannot set led gpio %d to output (err: %d)\n",
|
||||
gpio, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
|
||||
"brcmsmac-%s:radio", wiphy_name(wl->wiphy));
|
||||
|
||||
wl->led_dev.name = wl->radio_led.name;
|
||||
wl->led_dev.default_trigger =
|
||||
ieee80211_get_radio_led_name(wl->pub->ieee_hw);
|
||||
wl->led_dev.brightness_set = brcms_led_brightness_set;
|
||||
err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
|
||||
|
||||
if (err) {
|
||||
wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
|
||||
wl->radio_led.name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
wiphy_info(wl->wiphy, "registered radio enabled led device: %s gpio: %d\n",
|
||||
wl->radio_led.name,
|
||||
gpio);
|
||||
radio_led->gpio = gpio;
|
||||
radio_led->active_low = active_low;
|
||||
|
||||
return 0;
|
||||
}
|
36
drivers/net/wireless/brcm80211/brcmsmac/led.h
Normal file
36
drivers/net/wireless/brcm80211/brcmsmac/led.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_LED_H_
|
||||
#define _BRCM_LED_H_
|
||||
struct brcms_led {
|
||||
char name[32];
|
||||
unsigned gpio;
|
||||
bool active_low;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
static inline void brcms_led_unregister(struct brcms_info *wl) {};
|
||||
static inline int brcms_led_register(struct brcms_info *wl)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _BRCM_LED_H_ */
|
@ -34,6 +34,7 @@
|
||||
#include "mac80211_if.h"
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "led.h"
|
||||
|
||||
#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
|
||||
#define BRCMS_FLUSH_TIMEOUT 500 /* msec */
|
||||
@ -904,6 +905,7 @@ static void brcms_remove(struct bcma_device *pdev)
|
||||
struct brcms_info *wl = hw->priv;
|
||||
|
||||
if (wl->wlc) {
|
||||
brcms_led_unregister(wl);
|
||||
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
|
||||
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
|
||||
ieee80211_unregister_hw(hw);
|
||||
@ -1151,6 +1153,8 @@ static int brcms_bcma_probe(struct bcma_device *pdev)
|
||||
pr_err("%s: brcms_attach failed!\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
brcms_led_register(wl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,10 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include "ucode_loader.h"
|
||||
#include "led.h"
|
||||
/*
|
||||
* Starting index for 5G rates in the
|
||||
* legacy rate table.
|
||||
@ -81,6 +83,8 @@ struct brcms_info {
|
||||
struct wiphy *wiphy;
|
||||
struct brcms_ucode ucode;
|
||||
bool mute_tx;
|
||||
struct brcms_led radio_led;
|
||||
struct led_classdev led_dev;
|
||||
};
|
||||
|
||||
/* misc callbacks */
|
||||
|
@ -7810,9 +7810,14 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
|
||||
|
||||
/* read the ucode version if we have not yet done so */
|
||||
if (wlc->ucode_rev == 0) {
|
||||
wlc->ucode_rev =
|
||||
brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
|
||||
wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
|
||||
u16 rev;
|
||||
u16 patch;
|
||||
|
||||
rev = brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR);
|
||||
patch = brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
|
||||
wlc->ucode_rev = (rev << NBITS(u16)) | patch;
|
||||
snprintf(wlc->wiphy->fw_version,
|
||||
sizeof(wlc->wiphy->fw_version), "%u.%u", rev, patch);
|
||||
}
|
||||
|
||||
/* ..now really unleash hell (allow the MAC out of suspend) */
|
||||
|
@ -116,6 +116,31 @@ struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_pdeq);
|
||||
|
||||
/*
|
||||
* precedence based dequeue with match function. Passing a NULL pointer
|
||||
* for the match function parameter is considered to be a wildcard so
|
||||
* any packet on the queue is returned. In that case it is no different
|
||||
* from brcmu_pktq_pdeq() above.
|
||||
*/
|
||||
struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
|
||||
bool (*match_fn)(struct sk_buff *skb,
|
||||
void *arg), void *arg)
|
||||
{
|
||||
struct sk_buff_head *q;
|
||||
struct sk_buff *p, *next;
|
||||
|
||||
q = &pq->q[prec].skblist;
|
||||
skb_queue_walk_safe(q, p, next) {
|
||||
if (match_fn == NULL || match_fn(p, arg)) {
|
||||
skb_unlink(p, q);
|
||||
pq->len--;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_pdeq_match);
|
||||
|
||||
struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
|
||||
{
|
||||
struct sk_buff_head *q;
|
||||
|
@ -120,6 +120,10 @@ extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
|
||||
struct sk_buff *p);
|
||||
extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
|
||||
extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
|
||||
extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
|
||||
bool (*match_fn)(struct sk_buff *p,
|
||||
void *arg),
|
||||
void *arg);
|
||||
|
||||
/* packet primitives */
|
||||
extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
|
||||
@ -173,6 +177,29 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
|
||||
/* ip address */
|
||||
struct ipv4_addr;
|
||||
|
||||
/*
|
||||
* bitfield macros using masking and shift
|
||||
*
|
||||
* remark: the mask parameter should be a shifted mask.
|
||||
*/
|
||||
static inline void brcmu_maskset32(u32 *var, u32 mask, u8 shift, u32 value)
|
||||
{
|
||||
value = (value << shift) & mask;
|
||||
*var = (*var & ~mask) | value;
|
||||
}
|
||||
static inline u32 brcmu_maskget32(u32 var, u32 mask, u8 shift)
|
||||
{
|
||||
return (var & mask) >> shift;
|
||||
}
|
||||
static inline void brcmu_maskset16(u16 *var, u16 mask, u8 shift, u16 value)
|
||||
{
|
||||
value = (value << shift) & mask;
|
||||
*var = (*var & ~mask) | value;
|
||||
}
|
||||
static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift)
|
||||
{
|
||||
return (var & mask) >> shift;
|
||||
}
|
||||
|
||||
/* externs */
|
||||
/* format/print */
|
||||
|
@ -3475,7 +3475,7 @@ static struct attribute_group il3945_attribute_group = {
|
||||
.attrs = il3945_sysfs_entries,
|
||||
};
|
||||
|
||||
struct ieee80211_ops il3945_mac_ops = {
|
||||
static struct ieee80211_ops il3945_mac_ops __read_mostly = {
|
||||
.tx = il3945_mac_tx,
|
||||
.start = il3945_mac_start,
|
||||
.stop = il3945_mac_stop,
|
||||
|
@ -150,10 +150,6 @@ struct il3945_frame {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
|
||||
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
|
||||
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
|
||||
|
||||
#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
|
||||
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
|
||||
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
|
||||
|
@ -612,7 +612,7 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
|
||||
|
||||
/* Called for N_RX (legacy ABG frames), or
|
||||
* N_RX_MPDU (HT high-throughput N frames). */
|
||||
void
|
||||
static void
|
||||
il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
struct ieee80211_hdr *header;
|
||||
@ -744,7 +744,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
|
||||
/* Cache phy data (Rx signal strength, etc) for HT frame (N_RX_PHY).
|
||||
* This will be used later in il_hdl_rx() for N_RX_MPDU. */
|
||||
void
|
||||
static void
|
||||
il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
struct il_rx_pkt *pkt = rxb_addr(rxb);
|
||||
@ -1250,7 +1250,7 @@ il4965_dump_fh(struct il_priv *il, char **buf, bool display)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
struct il_rx_pkt *pkt = rxb_addr(rxb);
|
||||
@ -1357,7 +1357,7 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
static void
|
||||
il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
const int recalib_seconds = 60;
|
||||
@ -1399,7 +1399,7 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
il4965_temperature_calib(il);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
struct il_rx_pkt *pkt = rxb_addr(rxb);
|
||||
@ -2050,7 +2050,7 @@ il4965_txq_ctx_reset(struct il_priv *il)
|
||||
il_tx_queue_reset(il, txq_id);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
il4965_txq_ctx_unmap(struct il_priv *il)
|
||||
{
|
||||
int txq_id;
|
||||
@ -2258,7 +2258,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
|
||||
|
||||
spin_lock_irqsave(&il->sta_lock, flags);
|
||||
tid_data = &il->stations[sta_id].tid[tid];
|
||||
*ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
*ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
|
||||
tid_data->agg.txq_id = txq_id;
|
||||
il_set_swq_id(&il->txq[txq_id], il4965_get_ac_from_tid(tid), txq_id);
|
||||
spin_unlock_irqrestore(&il->sta_lock, flags);
|
||||
@ -2408,7 +2408,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
|
||||
/* aggregated HW queue */
|
||||
if (txq_id == tid_data->agg.txq_id &&
|
||||
q->read_ptr == q->write_ptr) {
|
||||
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
u16 ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
|
||||
int tx_fifo = il4965_get_fifo_from_tid(tid);
|
||||
D_HT("HW queue empty: continue DELBA flow\n");
|
||||
il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
|
||||
@ -2627,7 +2627,8 @@ il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
|
||||
static inline u32
|
||||
il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
|
||||
{
|
||||
return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
|
||||
return le32_to_cpup(&tx_resp->u.status +
|
||||
tx_resp->frame_count) & IEEE80211_MAX_SN;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
@ -2717,15 +2718,15 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
|
||||
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
|
||||
if (idx != (IEEE80211_SEQ_TO_SN(sc) & 0xff)) {
|
||||
IL_ERR("BUG_ON idx doesn't match seq control"
|
||||
" idx=%d, seq_idx=%d, seq=%d\n", idx,
|
||||
SEQ_TO_SN(sc), hdr->seq_ctrl);
|
||||
IEEE80211_SEQ_TO_SN(sc), hdr->seq_ctrl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
|
||||
SEQ_TO_SN(sc));
|
||||
IEEE80211_SEQ_TO_SN(sc));
|
||||
|
||||
sh = idx - start;
|
||||
if (sh > 64) {
|
||||
@ -2895,7 +2896,7 @@ il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
|
||||
* Handles block-acknowledge notification from device, which reports success
|
||||
* of frames sent via aggregation.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
{
|
||||
struct il_rx_pkt *pkt = rxb_addr(rxb);
|
||||
@ -6316,7 +6317,7 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
|
||||
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
|
||||
}
|
||||
|
||||
const struct ieee80211_ops il4965_mac_ops = {
|
||||
static const struct ieee80211_ops il4965_mac_ops = {
|
||||
.tx = il4965_mac_tx,
|
||||
.start = il4965_mac_start,
|
||||
.stop = il4965_mac_stop,
|
||||
|
@ -1122,7 +1122,7 @@ il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd)
|
||||
sizeof(struct il_powertable_cmd), cmd);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
|
||||
{
|
||||
int ret;
|
||||
|
@ -541,10 +541,6 @@ struct il_frame {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
|
||||
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
|
||||
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
|
||||
|
||||
enum {
|
||||
CMD_SYNC = 0,
|
||||
CMD_SIZE_NORMAL = 0,
|
||||
|
@ -6,7 +6,6 @@ config IWLWIFI
|
||||
select LEDS_CLASS
|
||||
select LEDS_TRIGGERS
|
||||
select MAC80211_LEDS
|
||||
select IWLDVM
|
||||
---help---
|
||||
Select to build the driver supporting the:
|
||||
|
||||
@ -45,6 +44,7 @@ config IWLWIFI
|
||||
config IWLDVM
|
||||
tristate "Intel Wireless WiFi DVM Firmware support"
|
||||
depends on IWLWIFI
|
||||
default IWLWIFI
|
||||
help
|
||||
This is the driver supporting the DVM firmware which is
|
||||
currently the only firmware available for existing devices.
|
||||
@ -58,6 +58,15 @@ config IWLMVM
|
||||
|
||||
Say yes if you have such a device.
|
||||
|
||||
# don't call it _MODULE -- will confuse Kconfig/fixdep/...
|
||||
config IWLWIFI_OPMODE_MODULAR
|
||||
bool
|
||||
default y if IWLDVM=m
|
||||
default y if IWLMVM=m
|
||||
|
||||
comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
|
||||
depends on IWLWIFI && IWLDVM=n && IWLMVM=n
|
||||
|
||||
menu "Debugging Options"
|
||||
depends on IWLWIFI
|
||||
|
||||
|
@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o
|
||||
iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
|
||||
iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
|
||||
iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
|
||||
iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o
|
||||
iwlwifi-objs += pcie/7000.o
|
||||
iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o
|
||||
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
|
||||
|
@ -22,7 +22,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp {
|
||||
__le16 scd_ssn;
|
||||
u8 txed; /* number of frames sent */
|
||||
u8 txed_2_done; /* number of frames acked */
|
||||
__le16 reserved1;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
|
@ -19,7 +19,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
bool restart_fw = iwlwifi_mod_params.restart_fw;
|
||||
int ret;
|
||||
|
||||
iwlwifi_mod_params.restart_fw = true;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
/* take the return value to make compiler happy - it will fail anyway */
|
||||
ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
iwlwifi_mod_params.restart_fw = restart_fw;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_general_stats);
|
||||
@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
|
||||
DEBUGFS_READ_FILE_OPS(reply_tx_error);
|
||||
DEBUGFS_WRITE_FILE_OPS(echo_test);
|
||||
DEBUGFS_WRITE_FILE_OPS(fw_restart);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(log_event);
|
||||
#endif
|
||||
@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
|
||||
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR);
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -1137,7 +1137,8 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
|
||||
static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *channel,
|
||||
int duration)
|
||||
int duration,
|
||||
enum ieee80211_roc_type type)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
|
||||
|
@ -19,7 +19,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -19,7 +19,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
@ -418,7 +418,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
|
||||
" Tx flags = 0x%08x, agg.state = %d",
|
||||
info->flags, tid_data->agg.state);
|
||||
IWL_ERR(priv, "sta_id = %d, tid = %d seq_num = %d",
|
||||
sta_id, tid, SEQ_TO_SN(tid_data->seq_number));
|
||||
sta_id, tid,
|
||||
IEEE80211_SEQ_TO_SN(tid_data->seq_number));
|
||||
goto drop_unlock_sta;
|
||||
}
|
||||
|
||||
@ -569,7 +570,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
||||
return 0;
|
||||
}
|
||||
|
||||
tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
|
||||
|
||||
/* There are still packets for this RA / TID in the HW */
|
||||
if (!test_bit(txq_id, priv->agg_q_alloc)) {
|
||||
@ -651,7 +652,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
||||
|
||||
spin_lock_bh(&priv->sta_lock);
|
||||
tid_data = &priv->tid_data[sta_id][tid];
|
||||
tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
|
||||
tid_data->agg.ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
|
||||
tid_data->agg.txq_id = txq_id;
|
||||
|
||||
*ssn = tid_data->agg.ssn;
|
||||
@ -911,7 +912,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
|
||||
static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
|
||||
{
|
||||
return le32_to_cpup((__le32 *)&tx_resp->status +
|
||||
tx_resp->frame_count) & MAX_SN;
|
||||
tx_resp->frame_count) & IEEE80211_MAX_SN;
|
||||
}
|
||||
|
||||
static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
|
||||
@ -1148,7 +1149,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
|
||||
|
||||
if (tx_resp->frame_count == 1) {
|
||||
u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl);
|
||||
next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10);
|
||||
next_reclaimed = IEEE80211_SEQ_TO_SN(next_reclaimed + 0x10);
|
||||
|
||||
if (is_agg) {
|
||||
/* If this is an aggregation queue, we can rely on the
|
||||
|
@ -19,7 +19,7 @@
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-csr.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "cfg.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MAX 5
|
@ -28,7 +28,6 @@
|
||||
#include <linux/stringify.h>
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "cfg.h"
|
||||
#include "dvm/commands.h" /* needed for BT for now */
|
||||
|
||||
/* Highest firmware API version supported */
|
@ -29,7 +29,6 @@
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-csr.h"
|
||||
#include "cfg.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL5000_UCODE_API_MAX 5
|
@ -28,7 +28,6 @@
|
||||
#include <linux/stringify.h>
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "cfg.h"
|
||||
#include "dvm/commands.h" /* needed for BT for now */
|
||||
|
||||
/* Highest firmware API version supported */
|
@ -1,34 +1,70 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* 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
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* 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.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "cfg.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MAX 6
|
||||
@ -70,7 +106,6 @@ static const struct iwl_base_params iwl7000_base_params = {
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user