Skip to content

Commit

Permalink
Merge tag 'for-linville-20141024' of git://github.com/kvalo/ath
Browse files Browse the repository at this point in the history
Conflicts:
	drivers/net/wireless/ath/wil6210/wil6210.h
  • Loading branch information
John W. Linville committed Oct 27, 2014
2 parents 61ed53d + 84cbf3a commit 490f0dc
Show file tree
Hide file tree
Showing 24 changed files with 2,258 additions and 1,373 deletions.
83 changes: 42 additions & 41 deletions drivers/net/wireless/ath/ath10k/ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
* Guts of ath10k_ce_completed_recv_next.
* The caller takes responsibility for any necessary locking.
*/
static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp,
unsigned int *flagsp)
int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp,
unsigned int *flagsp)
{
struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
unsigned int nentries_mask = dest_ring->nentries_mask;
Expand Down Expand Up @@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
* Guts of ath10k_ce_completed_send_next.
* The caller takes responsibility for any necessary locking.
*/
static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp)
int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp)
{
struct ath10k_ce_ring *src_ring = ce_state->src_ring;
u32 ctrl_addr = ce_state->ctrl_addr;
Expand Down Expand Up @@ -817,7 +817,10 @@ void ath10k_ce_enable_interrupts(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ce_id;

for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
/* Skip the last copy engine, CE7 the diagnostic window, as that
* uses polling and isn't initialized for interrupts.
*/
for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++)
ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]);
}

Expand Down Expand Up @@ -1020,37 +1023,10 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
* initialized by software/firmware.
*/
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *))
const struct ce_attr *attr)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
int ret;

/*
* Make sure there's enough CE ringbuffer entries for HTT TX to avoid
* additional TX locking checks.
*
* For the lack of a better place do the check here.
*/
BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));

spin_lock_bh(&ar_pci->ce_lock);
ce_state->ar = ar;
ce_state->id = ce_id;
ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
ce_state->attr_flags = attr->flags;
ce_state->src_sz_max = attr->src_sz_max;
if (attr->src_nentries)
ce_state->send_cb = send_cb;
if (attr->dest_nentries)
ce_state->recv_cb = recv_cb;
spin_unlock_bh(&ar_pci->ce_lock);

if (attr->src_nentries) {
ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
if (ret) {
Expand Down Expand Up @@ -1098,12 +1074,37 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
}

int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
const struct ce_attr *attr)
const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *))
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
int ret;

/*
* Make sure there's enough CE ringbuffer entries for HTT TX to avoid
* additional TX locking checks.
*
* For the lack of a better place do the check here.
*/
BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));

ce_state->ar = ar;
ce_state->id = ce_id;
ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
ce_state->attr_flags = attr->flags;
ce_state->src_sz_max = attr->src_sz_max;

if (attr->src_nentries)
ce_state->send_cb = send_cb;

if (attr->dest_nentries)
ce_state->recv_cb = recv_cb;

if (attr->src_nentries) {
ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
if (IS_ERR(ce_state->src_ring)) {
Expand Down
21 changes: 17 additions & 4 deletions drivers/net/wireless/ath/ath10k/ce.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,21 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
unsigned int *nbytesp,
unsigned int *transfer_idp);

int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp);

/*==================CE Engine Initialization=======================*/

int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *));
const struct ce_attr *attr);
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
const struct ce_attr *attr);
const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *));
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);

/*==================CE Engine Shutdown=======================*/
Expand All @@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp);

int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp,
unsigned int *flagsp);

/*
* Support clean shutdown by allowing the caller to cancel
* pending sends. Target DMA must be stopped before using
Expand Down
111 changes: 88 additions & 23 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
return fw;
}

static int ath10k_push_board_ext_data(struct ath10k *ar)
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
size_t data_len)
{
u32 board_data_size = QCA988X_BOARD_DATA_SZ;
u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
Expand All @@ -159,14 +160,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
if (board_ext_data_addr == 0)
return 0;

if (ar->board_len != (board_data_size + board_ext_data_size)) {
if (data_len != (board_data_size + board_ext_data_size)) {
ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
ar->board_len, board_data_size, board_ext_data_size);
data_len, board_data_size, board_ext_data_size);
return -EINVAL;
}

ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
ar->board_data + board_data_size,
data + board_data_size,
board_ext_data_size);
if (ret) {
ath10k_err(ar, "could not write board ext data (%d)\n", ret);
Expand All @@ -184,13 +185,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
return 0;
}

static int ath10k_download_board_data(struct ath10k *ar)
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
size_t data_len)
{
u32 board_data_size = QCA988X_BOARD_DATA_SZ;
u32 address;
int ret;

ret = ath10k_push_board_ext_data(ar);
ret = ath10k_push_board_ext_data(ar, data, data_len);
if (ret) {
ath10k_err(ar, "could not push board ext data (%d)\n", ret);
goto exit;
Expand All @@ -202,9 +204,9 @@ static int ath10k_download_board_data(struct ath10k *ar)
goto exit;
}

ret = ath10k_bmi_write_memory(ar, address, ar->board_data,
ret = ath10k_bmi_write_memory(ar, address, data,
min_t(u32, board_data_size,
ar->board_len));
data_len));
if (ret) {
ath10k_err(ar, "could not write board data (%d)\n", ret);
goto exit;
Expand All @@ -220,11 +222,39 @@ static int ath10k_download_board_data(struct ath10k *ar)
return ret;
}

static int ath10k_download_cal_file(struct ath10k *ar)
{
int ret;

if (!ar->cal_file)
return -ENOENT;

if (IS_ERR(ar->cal_file))
return PTR_ERR(ar->cal_file);

ret = ath10k_download_board_data(ar, ar->cal_file->data,
ar->cal_file->size);
if (ret) {
ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
return ret;
}

ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");

return 0;
}

static int ath10k_download_and_run_otp(struct ath10k *ar)
{
u32 result, address = ar->hw_params.patch_load_addr;
int ret;

ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
if (ret) {
ath10k_err(ar, "failed to download board data: %d\n", ret);
return ret;
}

/* OTP is optional */

if (!ar->otp_data || !ar->otp_len) {
Expand Down Expand Up @@ -308,6 +338,9 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
if (ar->firmware && !IS_ERR(ar->firmware))
release_firmware(ar->firmware);

if (ar->cal_file && !IS_ERR(ar->cal_file))
release_firmware(ar->cal_file);

ar->board = NULL;
ar->board_data = NULL;
ar->board_len = 0;
Expand All @@ -319,6 +352,27 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
ar->firmware = NULL;
ar->firmware_data = NULL;
ar->firmware_len = 0;

ar->cal_file = NULL;
}

static int ath10k_fetch_cal_file(struct ath10k *ar)
{
char filename[100];

/* cal-<bus>-<id>.bin */
scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));

ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
if (IS_ERR(ar->cal_file))
/* calibration file is optional, don't print any warnings */
return PTR_ERR(ar->cal_file);

ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
ATH10K_FW_DIR, filename);

return 0;
}

static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
Expand Down Expand Up @@ -562,6 +616,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{
int ret;

/* calibration file is optional, don't check for any errors */
ath10k_fetch_cal_file(ar);

ar->fw_api = 3;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

Expand Down Expand Up @@ -589,30 +646,32 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
return 0;
}

static int ath10k_init_download_firmware(struct ath10k *ar,
enum ath10k_firmware_mode mode)
static int ath10k_download_cal_data(struct ath10k *ar)
{
int ret;

ret = ath10k_download_board_data(ar);
if (ret) {
ath10k_err(ar, "failed to download board data: %d\n", ret);
return ret;
ret = ath10k_download_cal_file(ar);
if (ret == 0) {
ar->cal_mode = ATH10K_CAL_MODE_FILE;
goto done;
}

ath10k_dbg(ar, ATH10K_DBG_BOOT,
"boot did not find a calibration file, try OTP next: %d\n",
ret);

ret = ath10k_download_and_run_otp(ar);
if (ret) {
ath10k_err(ar, "failed to run otp: %d\n", ret);
return ret;
}

ret = ath10k_download_fw(ar, mode);
if (ret) {
ath10k_err(ar, "failed to download firmware: %d\n", ret);
return ret;
}
ar->cal_mode = ATH10K_CAL_MODE_OTP;

return ret;
done:
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
ath10k_cal_mode_str(ar->cal_mode));
return 0;
}

static int ath10k_init_uart(struct ath10k *ar)
Expand Down Expand Up @@ -729,7 +788,11 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
goto err;
}

status = ath10k_init_download_firmware(ar, mode);
status = ath10k_download_cal_data(ar);
if (status)
goto err;

status = ath10k_download_fw(ar, mode);
if (status)
goto err;

Expand Down Expand Up @@ -846,9 +909,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
goto err_hif_stop;

if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
ar->free_vdev_map = (1LL << TARGET_10X_NUM_VDEVS) - 1;
else
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
ar->free_vdev_map = (1LL << TARGET_NUM_VDEVS) - 1;

INIT_LIST_HEAD(&ar->arvifs);

Expand Down Expand Up @@ -1084,6 +1147,7 @@ void ath10k_core_unregister(struct ath10k *ar)
EXPORT_SYMBOL(ath10k_core_unregister);

struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
const struct ath10k_hif_ops *hif_ops)
{
struct ath10k *ar;
Expand All @@ -1100,6 +1164,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
ar->dev = dev;

ar->hif.ops = hif_ops;
ar->hif.bus = bus;

init_completion(&ar->scan.started);
init_completion(&ar->scan.completed);
Expand Down
Loading

0 comments on commit 490f0dc

Please sign in to comment.