forked from Minki/linux
Merge tag 'for-linville-20140717' of git://github.com/kvalo/ath
This commit is contained in:
commit
5235cd2121
@ -603,16 +603,19 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
src_ring->hw_index =
|
||||
ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
src_ring->hw_index &= nentries_mask;
|
||||
read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
if (read_index == 0xffffffff)
|
||||
return -ENODEV;
|
||||
|
||||
read_index &= nentries_mask;
|
||||
src_ring->hw_index = read_index;
|
||||
|
||||
ath10k_pci_sleep(ar);
|
||||
}
|
||||
|
||||
read_index = src_ring->hw_index;
|
||||
|
||||
if ((read_index == sw_index) || (read_index == 0xffffffff))
|
||||
if (read_index == sw_index)
|
||||
return -EIO;
|
||||
|
||||
sbase = src_ring->shadow_base;
|
||||
|
@ -802,7 +802,7 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
|
||||
INIT_LIST_HEAD(&ar->arvifs);
|
||||
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) {
|
||||
ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
|
||||
ar->hw_params.name,
|
||||
ar->target_version,
|
||||
@ -811,6 +811,12 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
ar->fw_api,
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor);
|
||||
ath10k_info("debug %d debugfs %d tracing %d dfs %d\n",
|
||||
config_enabled(CONFIG_ATH10K_DEBUG),
|
||||
config_enabled(CONFIG_ATH10K_DEBUGFS),
|
||||
config_enabled(CONFIG_ATH10K_TRACING),
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
|
||||
}
|
||||
|
||||
__set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
|
||||
|
||||
@ -988,7 +994,9 @@ err_unregister_mac:
|
||||
err_release_fw:
|
||||
ath10k_core_free_firmware_files(ar);
|
||||
err:
|
||||
device_release_driver(ar->dev);
|
||||
/* TODO: It's probably a good idea to release device from the driver
|
||||
* but calling device_release_driver() here will cause a deadlock.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -290,6 +290,9 @@ struct ath10k_debug {
|
||||
struct ath_dfs_pool_stats dfs_pool_stats;
|
||||
|
||||
u32 fw_dbglog_mask;
|
||||
|
||||
u8 htt_max_amsdu;
|
||||
u8 htt_max_ampdu;
|
||||
};
|
||||
|
||||
enum ath10k_state {
|
||||
|
@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[64];
|
||||
u8 amsdu = 3, ampdu = 64;
|
||||
unsigned int len;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->debug.htt_max_amsdu)
|
||||
amsdu = ar->debug.htt_max_amsdu;
|
||||
|
||||
if (ar->debug.htt_max_ampdu)
|
||||
ampdu = ar->debug.htt_max_ampdu;
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
int res;
|
||||
char buf[64];
|
||||
unsigned int amsdu, ampdu;
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
res = sscanf(buf, "%u %u", &amsdu, &du);
|
||||
|
||||
if (res != 2)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
res = count;
|
||||
ar->debug.htt_max_amsdu = amsdu;
|
||||
ar->debug.htt_max_ampdu = ampdu;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_htt_max_amsdu_ampdu = {
|
||||
.read = ath10k_read_htt_max_amsdu_ampdu,
|
||||
.write = ath10k_write_htt_max_amsdu_ampdu,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_fw_dbglog(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
|
||||
* warning from del_timer(). */
|
||||
if (ar->debug.htt_stats_mask != 0)
|
||||
cancel_delayed_work(&ar->debug.htt_stats_dwork);
|
||||
|
||||
ar->debug.htt_max_amsdu = 0;
|
||||
ar->debug.htt_max_ampdu = 0;
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_simulate_radar(struct file *file,
|
||||
@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
|
||||
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_htt_stats_mask);
|
||||
|
||||
debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar,
|
||||
&fops_htt_max_amsdu_ampdu);
|
||||
|
||||
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_fw_dbglog);
|
||||
|
||||
|
@ -240,16 +240,10 @@ struct htt_oob_sync_req {
|
||||
__le16 rsvd0;
|
||||
} __packed;
|
||||
|
||||
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
|
||||
#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0
|
||||
|
||||
struct htt_aggr_conf {
|
||||
u8 max_num_ampdu_subframes;
|
||||
union {
|
||||
/* dont use bitfields; undefined behaviour */
|
||||
u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
|
||||
u8 max_num_amsdu_subframes:5;
|
||||
} __packed;
|
||||
/* amsdu_subframes is limited by 0x1F mask */
|
||||
u8 max_num_amsdu_subframes;
|
||||
} __packed;
|
||||
|
||||
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
|
||||
@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
|
||||
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
|
||||
int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
|
||||
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
|
||||
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
|
||||
u8 max_subfrms_ampdu,
|
||||
u8 max_subfrms_amsdu);
|
||||
|
||||
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
|
||||
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
|
||||
|
@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
|
||||
u8 max_subfrms_ampdu,
|
||||
u8 max_subfrms_amsdu)
|
||||
{
|
||||
struct htt_aggr_conf *aggr_conf;
|
||||
struct sk_buff *skb;
|
||||
struct htt_cmd *cmd;
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
/* Firmware defaults are: amsdu = 3 and ampdu = 64 */
|
||||
|
||||
if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
|
||||
return -EINVAL;
|
||||
|
||||
if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
|
||||
return -EINVAL;
|
||||
|
||||
len = sizeof(cmd->hdr);
|
||||
len += sizeof(cmd->aggr_conf);
|
||||
|
||||
skb = ath10k_htc_alloc_skb(len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_put(skb, len);
|
||||
cmd = (struct htt_cmd *)skb->data;
|
||||
cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
|
||||
|
||||
aggr_conf = &cmd->aggr_conf;
|
||||
aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
|
||||
aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
|
||||
aggr_conf->max_num_amsdu_subframes,
|
||||
aggr_conf->max_num_ampdu_subframes);
|
||||
|
||||
ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
|
||||
if (ret) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
{
|
||||
struct device *dev = htt->ar->dev;
|
||||
|
@ -1362,8 +1362,6 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
||||
ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
|
||||
}
|
||||
|
||||
init_completion(&xfer.done);
|
||||
|
||||
ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
|
||||
if (ret)
|
||||
goto err_resp;
|
||||
@ -1414,10 +1412,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
|
||||
&nbytes, &transfer_id))
|
||||
return;
|
||||
|
||||
if (xfer->wait_for_resp)
|
||||
return;
|
||||
|
||||
complete(&xfer->done);
|
||||
xfer->tx_done = true;
|
||||
}
|
||||
|
||||
static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
|
||||
@ -1438,7 +1433,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
|
||||
}
|
||||
|
||||
xfer->resp_len = nbytes;
|
||||
complete(&xfer->done);
|
||||
xfer->rx_done = true;
|
||||
}
|
||||
|
||||
static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
@ -1451,7 +1446,7 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
ath10k_pci_bmi_send_done(tx_pipe);
|
||||
ath10k_pci_bmi_recv_data(rx_pipe);
|
||||
|
||||
if (completion_done(&xfer->done))
|
||||
if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
|
||||
return 0;
|
||||
|
||||
schedule();
|
||||
|
@ -38,7 +38,8 @@
|
||||
#define DIAG_TRANSFER_LIMIT 2048
|
||||
|
||||
struct bmi_xfer {
|
||||
struct completion done;
|
||||
bool tx_done;
|
||||
bool rx_done;
|
||||
bool wait_for_resp;
|
||||
u32 resp_len;
|
||||
};
|
||||
|
@ -2106,7 +2106,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
enum wmi_event_id id;
|
||||
u16 len;
|
||||
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
@ -2114,8 +2113,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
len = skb->len;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
@ -2225,7 +2222,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
enum wmi_10x_event_id id;
|
||||
u16 len;
|
||||
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
@ -2233,8 +2229,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
len = skb->len;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
|
@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
|
||||
(void) (check_type == val); \
|
||||
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
|
||||
ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
|
||||
*val = le32_to_cpu(tmp); \
|
||||
if (!ret) \
|
||||
*val = le32_to_cpu(tmp); \
|
||||
ret; \
|
||||
})
|
||||
|
||||
|
@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (info->inactivity_timeout) {
|
||||
inactivity_timeout = info->inactivity_timeout;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
ar->fw_capabilities))
|
||||
inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
|
||||
60);
|
||||
|
||||
@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
||||
}
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities)) {
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
|
@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
|
||||
|
||||
/* FIXME: we should free all firmwares in the error cases below */
|
||||
|
||||
/*
|
||||
* Backwards compatibility support for older ar6004 firmware images
|
||||
* which do not set these feature flags.
|
||||
*/
|
||||
if (ar->target_type == TARGET_TYPE_AR6004 &&
|
||||
ar->fw_api <= 4) {
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities);
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
ar->fw_capabilities);
|
||||
|
||||
if (ar->hw.id == AR6004_HW_1_3_VERSION)
|
||||
__set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities);
|
||||
}
|
||||
|
||||
/* Indicate that WMI is enabled (although not ready yet) */
|
||||
set_bit(WMI_ENABLED, &ar->flag);
|
||||
ar->wmi = ath6kl_wmi_init(ar);
|
||||
|
@ -136,6 +136,21 @@ enum ath6kl_fw_capability {
|
||||
*/
|
||||
ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
|
||||
|
||||
/* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
|
||||
ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
|
||||
/* WMI_AP_CONN_INACT_CMDID uses minutes as units */
|
||||
ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
||||
|
||||
/* use low priority endpoint for all data */
|
||||
ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
|
||||
/* ratetable is the 2 stream version (max MCS15) */
|
||||
ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
||||
|
||||
/* firmare doesn't support IP checksumming */
|
||||
ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
||||
|
||||
/* this needs to be last */
|
||||
ATH6KL_FW_CAPABILITY_MAX,
|
||||
};
|
||||
@ -149,15 +164,13 @@ struct ath6kl_fw_ie {
|
||||
};
|
||||
|
||||
enum ath6kl_hw_flags {
|
||||
ATH6KL_HW_64BIT_RATES = BIT(0),
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
|
||||
ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
|
||||
ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
|
||||
};
|
||||
|
||||
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
||||
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
||||
#define ATH6KL_FW_API4_FILE "fw-4.bin"
|
||||
#define ATH6KL_FW_API5_FILE "fw-5.bin"
|
||||
|
||||
/* AR6003 1.0 definitions */
|
||||
#define AR6003_HW_1_0_VERSION 0x300002ba
|
||||
@ -215,8 +228,21 @@ enum ath6kl_hw_flags {
|
||||
#define AR6004_HW_1_3_VERSION 0x31c8088a
|
||||
#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
|
||||
#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
|
||||
#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
||||
#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
||||
#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_1_3_UTF_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_1_3_TESTSCRIPT_FILE "nullTestFlow.bin"
|
||||
#define AR6004_HW_1_3_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
||||
#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
||||
|
||||
/* AR6004 3.0 definitions */
|
||||
#define AR6004_HW_3_0_VERSION 0x31C809F8
|
||||
#define AR6004_HW_3_0_FW_DIR "ath6k/AR6004/hw3.0"
|
||||
#define AR6004_HW_3_0_FIRMWARE_FILE "fw.ram.bin"
|
||||
#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_3_0_UTF_FIRMWARE_FILE "utf.bin"
|
||||
#define AR6004_HW_3_0_TESTSCRIPT_FILE "nullTestFlow.bin"
|
||||
#define AR6004_HW_3_0_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
||||
#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
||||
|
||||
/* Per STA data, used in AP mode */
|
||||
#define STA_PS_AWAKE BIT(0)
|
||||
|
@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
|
||||
static void htc_rxctrl_complete(struct htc_target *context,
|
||||
struct htc_packet *packet)
|
||||
{
|
||||
/* TODO, can't really receive HTC control messages yet.... */
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
|
||||
struct sk_buff *skb = packet->skb;
|
||||
|
||||
if (packet->endpoint == ENDPOINT_0 &&
|
||||
packet->status == -ECANCELED &&
|
||||
skb != NULL)
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
/* htc pipe initialization */
|
||||
@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
|
||||
|
||||
static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
|
||||
{
|
||||
/* TODO */
|
||||
struct htc_endpoint *endpoint;
|
||||
struct htc_packet *packet, *tmp_pkt;
|
||||
int i;
|
||||
|
||||
for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
|
||||
endpoint = &target->endpoint[i];
|
||||
|
||||
spin_lock_bh(&target->rx_lock);
|
||||
|
||||
list_for_each_entry_safe(packet, tmp_pkt,
|
||||
&endpoint->rx_bufq, list) {
|
||||
list_del(&packet->list);
|
||||
spin_unlock_bh(&target->rx_lock);
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx flush pkt 0x%p len %d ep %d\n",
|
||||
packet, packet->buf_len,
|
||||
packet->endpoint);
|
||||
dev_kfree_skb(packet->pkt_cntxt);
|
||||
spin_lock_bh(&target->rx_lock);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&target->rx_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
|
||||
|
@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x433900,
|
||||
.refclk_hz = 26000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_0_FW_DIR,
|
||||
@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x43d400,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_1_FW_DIR,
|
||||
.fw = AR6004_HW_1_1_FIRMWARE_FILE,
|
||||
@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x435c00,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_2_FW_DIR,
|
||||
@ -152,20 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_ext_data_addr = 0x437000,
|
||||
.reserved_ram_size = 7168,
|
||||
.board_addr = 0x436400,
|
||||
.refclk_hz = 40000000,
|
||||
.refclk_hz = 0,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_64BIT_RATES |
|
||||
ATH6KL_HW_AP_INACTIVITY_MINS |
|
||||
ATH6KL_HW_MAP_LP_ENDPOINT,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_3_FW_DIR,
|
||||
.fw = AR6004_HW_1_3_FIRMWARE_FILE,
|
||||
.tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
|
||||
.utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
|
||||
.testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
|
||||
},
|
||||
|
||||
.fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
|
||||
},
|
||||
{
|
||||
.id = AR6004_HW_3_0_VERSION,
|
||||
.name = "ar6004 hw 3.0",
|
||||
.dataset_patch_addr = 0,
|
||||
.app_load_addr = 0x1234,
|
||||
.board_ext_data_addr = 0,
|
||||
.reserved_ram_size = 7168,
|
||||
.board_addr = 0x436400,
|
||||
.testscript_addr = 0,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_3_0_FW_DIR,
|
||||
.fw = AR6004_HW_3_0_FIRMWARE_FILE,
|
||||
.tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
|
||||
.utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
|
||||
.testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
|
||||
},
|
||||
|
||||
.fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@ -601,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
* but possible in theory.
|
||||
*/
|
||||
|
||||
if (ar->target_type == TARGET_TYPE_AR6003) {
|
||||
if ((ar->target_type == TARGET_TYPE_AR6003) ||
|
||||
(ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
||||
(ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
|
||||
param = ar->hw.board_ext_data_addr;
|
||||
ram_reserved_size = ar->hw.reserved_ram_size;
|
||||
|
||||
@ -629,9 +651,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
return status;
|
||||
|
||||
/* Configure target refclk_hz */
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
|
||||
if (status)
|
||||
return status;
|
||||
if (ar->hw.refclk_hz != 0) {
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
|
||||
ar->hw.refclk_hz);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1112,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
|
||||
if (ret == 0) {
|
||||
ar->fw_api = 5;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
|
||||
if (ret == 0) {
|
||||
ar->fw_api = 4;
|
||||
@ -1161,11 +1192,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data,
|
||||
board_address);
|
||||
} else {
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
||||
ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to get board file target address.\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine where in target ram to write extended board data */
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
||||
ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to get extended board file target address.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ar->target_type == TARGET_TYPE_AR6003 &&
|
||||
board_ext_address == 0) {
|
||||
@ -1230,7 +1269,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
/* record the fact that Board Data IS initialized */
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
|
||||
if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
||||
(ar->version.target_ver == AR6004_HW_3_0_VERSION))
|
||||
param = board_data_size;
|
||||
else
|
||||
param = 1;
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1361,7 +1406,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
|
||||
ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
||||
|
||||
if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
|
||||
(ar->version.target_ver != AR6004_HW_3_0_VERSION))
|
||||
ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
||||
|
||||
ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
|
||||
|
||||
return 0;
|
||||
@ -1567,6 +1616,11 @@ static const struct fw_capa_str_map {
|
||||
{ ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
|
||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
|
||||
{ ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
|
||||
{ ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
|
||||
{ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
|
||||
{ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
|
||||
{ ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
|
||||
{ ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
|
||||
};
|
||||
|
||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
||||
|
@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
||||
struct ath6kl *ar = vif->ar;
|
||||
struct target_stats *stats = &vif->target_stats;
|
||||
struct tkip_ccmp_stats *ccmp_stats;
|
||||
s32 rate;
|
||||
u8 ac;
|
||||
|
||||
if (len < sizeof(*tgt_stats))
|
||||
@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
||||
le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
|
||||
stats->tx_rts_fail_cnt +=
|
||||
le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
|
||||
stats->tx_ucast_rate =
|
||||
ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
|
||||
|
||||
rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
|
||||
stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
||||
|
||||
stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
|
||||
stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
|
||||
@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
||||
le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
|
||||
stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
|
||||
stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
|
||||
stats->rx_ucast_rate =
|
||||
ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
|
||||
|
||||
rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
|
||||
stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
||||
|
||||
ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
|
||||
|
||||
@ -1290,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
|
||||
|
||||
void init_netdev(struct net_device *dev)
|
||||
{
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
|
||||
dev->netdev_ops = &ath6kl_netdev_ops;
|
||||
dev->destructor = free_netdev;
|
||||
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
|
||||
@ -1301,7 +1306,9 @@ void init_netdev(struct net_device *dev)
|
||||
WMI_MAX_TX_META_SZ +
|
||||
ATH6KL_HTC_ALIGN_BYTES, 4);
|
||||
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
||||
ar->fw_capabilities))
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
||||
break;
|
||||
case WMI_DATA_VI_SVC:
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities))
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
||||
else
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
||||
@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
||||
break;
|
||||
case WMI_DATA_VO_SVC:
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
||||
ar->fw_capabilities))
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
||||
else
|
||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
||||
@ -1208,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id ath6kl_usb_ids[] = {
|
||||
{USB_DEVICE(0x0cf3, 0x9375)},
|
||||
{USB_DEVICE(0x0cf3, 0x9374)},
|
||||
{ /* Terminating entry */ },
|
||||
};
|
||||
|
@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const s32 wmi_rate_tbl_mcs15[][2] = {
|
||||
/* {W/O SGI, with SGI} */
|
||||
{1000, 1000},
|
||||
{2000, 2000},
|
||||
{5500, 5500},
|
||||
{11000, 11000},
|
||||
{6000, 6000},
|
||||
{9000, 9000},
|
||||
{12000, 12000},
|
||||
{18000, 18000},
|
||||
{24000, 24000},
|
||||
{36000, 36000},
|
||||
{48000, 48000},
|
||||
{54000, 54000},
|
||||
{6500, 7200}, /* HT 20, MCS 0 */
|
||||
{13000, 14400},
|
||||
{19500, 21700},
|
||||
{26000, 28900},
|
||||
{39000, 43300},
|
||||
{52000, 57800},
|
||||
{58500, 65000},
|
||||
{65000, 72200},
|
||||
{13000, 14400}, /* HT 20, MCS 8 */
|
||||
{26000, 28900},
|
||||
{39000, 43300},
|
||||
{52000, 57800},
|
||||
{78000, 86700},
|
||||
{104000, 115600},
|
||||
{117000, 130000},
|
||||
{130000, 144400}, /* HT 20, MCS 15 */
|
||||
{13500, 15000}, /*HT 40, MCS 0 */
|
||||
{27000, 30000},
|
||||
{40500, 45000},
|
||||
{54000, 60000},
|
||||
{81000, 90000},
|
||||
{108000, 120000},
|
||||
{121500, 135000},
|
||||
{135000, 150000},
|
||||
{27000, 30000}, /*HT 40, MCS 8 */
|
||||
{54000, 60000},
|
||||
{81000, 90000},
|
||||
{108000, 120000},
|
||||
{162000, 180000},
|
||||
{216000, 240000},
|
||||
{243000, 270000},
|
||||
{270000, 300000}, /*HT 40, MCS 15 */
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
|
||||
static const u8 up_to_ac[] = {
|
||||
WMM_AC_BE,
|
||||
@ -2838,7 +2887,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
||||
{
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
||||
ar->fw_capabilities))
|
||||
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
|
||||
else
|
||||
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
|
||||
@ -3279,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
s32 ath6kl_wmi_get_rate(s8 rate_index)
|
||||
s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
|
||||
{
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
u8 sgi = 0;
|
||||
s32 ret;
|
||||
|
||||
if (rate_index == RATE_AUTO)
|
||||
return 0;
|
||||
@ -3292,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
|
||||
sgi = 1;
|
||||
}
|
||||
|
||||
if (WARN_ON(rate_index > RATE_MCS_7_40))
|
||||
rate_index = RATE_MCS_7_40;
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
||||
ar->fw_capabilities)) {
|
||||
if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
|
||||
return 0;
|
||||
|
||||
return wmi_rate_tbl[(u32) rate_index][sgi];
|
||||
ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
|
||||
} else {
|
||||
if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
|
||||
return 0;
|
||||
|
||||
ret = wmi_rate_tbl[(u32) rate_index][sgi];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
|
||||
|
@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
|
||||
struct ath6kl_htcap *htcap);
|
||||
int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
|
||||
|
||||
s32 ath6kl_wmi_get_rate(s8 rate_index);
|
||||
s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
|
||||
|
||||
int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
|
||||
__be32 ips0, __be32 ips1);
|
||||
|
Loading…
Reference in New Issue
Block a user