mwifiex: add support for Marvell pcie8766 chipset
This patch supports 88W8766P chipset with a PCIe interface. The corresponding firmware image file is located at: "mrvl/pcie8766_uapsta.bin" Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Ramesh Radhakrishnan <rramesh@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Frank Huang <frankh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
ec205999d3
Коммит
d930faee14
|
@ -246,8 +246,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
|||
tx_param.next_pkt_len = 0;
|
||||
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
|
||||
skb_aggr->data,
|
||||
skb_aggr->len, &tx_param);
|
||||
skb_aggr, &tx_param);
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
|
||||
|
|
|
@ -19,3 +19,14 @@ config MWIFIEX_SDIO
|
|||
|
||||
If you choose to build it as a module, it will be called
|
||||
mwifiex_sdio.
|
||||
|
||||
config MWIFIEX_PCIE
|
||||
tristate "Marvell WiFi-Ex Driver for PCIE 8766"
|
||||
depends on MWIFIEX && PCI
|
||||
select FW_LOADER
|
||||
---help---
|
||||
This adds support for wireless adapters based on Marvell
|
||||
8766 chipset with PCIe interface.
|
||||
|
||||
If you choose to build it as a module, it will be called
|
||||
mwifiex_pcie.
|
||||
|
|
|
@ -39,3 +39,6 @@ obj-$(CONFIG_MWIFIEX) += mwifiex.o
|
|||
|
||||
mwifiex_sdio-y += sdio.o
|
||||
obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
|
||||
|
||||
mwifiex_pcie-y += pcie.o
|
||||
obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
|
||||
|
|
|
@ -94,7 +94,7 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
|
|||
skb_trim(cmd_node->cmd_skb, 0);
|
||||
|
||||
if (cmd_node->resp_skb) {
|
||||
dev_kfree_skb_any(cmd_node->resp_skb);
|
||||
adapter->if_ops.cmdrsp_complete(adapter, cmd_node->resp_skb);
|
||||
cmd_node->resp_skb = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +176,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
|||
skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
|
||||
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
|
||||
cmd_node->cmd_skb->data,
|
||||
cmd_node->cmd_skb->len, NULL);
|
||||
cmd_node->cmd_skb, NULL);
|
||||
|
||||
skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
|
||||
|
||||
|
@ -238,8 +237,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
|||
|
||||
skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
|
||||
adapter->sleep_cfm->data,
|
||||
adapter->sleep_cfm->len, NULL);
|
||||
adapter->sleep_cfm, NULL);
|
||||
skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
|
||||
|
||||
if (ret == -1) {
|
||||
|
@ -402,8 +400,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
|||
|
||||
adapter->event_cause = 0;
|
||||
adapter->event_skb = NULL;
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
adapter->if_ops.event_complete(adapter, skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ enum KEY_TYPE_ID {
|
|||
|
||||
#define MAX_FIRMWARE_POLL_TRIES 100
|
||||
|
||||
#define FIRMWARE_READY 0xfedc
|
||||
#define FIRMWARE_READY_SDIO 0xfedc
|
||||
#define FIRMWARE_READY_PCIE 0xfedcba00
|
||||
|
||||
enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
|
||||
|
@ -221,7 +222,7 @@ enum MWIFIEX_802_11_WEP_STATUS {
|
|||
#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
|
||||
#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
|
||||
#define HostCmd_CMD_SET_BSS_MODE 0x00f7
|
||||
|
||||
#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
|
||||
|
||||
enum ENH_PS_MODES {
|
||||
EN_PS = 1,
|
||||
|
@ -1137,6 +1138,30 @@ struct host_cmd_ds_set_bss_mode {
|
|||
u8 con_type;
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_ds_pcie_details {
|
||||
/* TX buffer descriptor ring address */
|
||||
u32 txbd_addr_lo;
|
||||
u32 txbd_addr_hi;
|
||||
/* TX buffer descriptor ring count */
|
||||
u32 txbd_count;
|
||||
|
||||
/* RX buffer descriptor ring address */
|
||||
u32 rxbd_addr_lo;
|
||||
u32 rxbd_addr_hi;
|
||||
/* RX buffer descriptor ring count */
|
||||
u32 rxbd_count;
|
||||
|
||||
/* Event buffer descriptor ring address */
|
||||
u32 evtbd_addr_lo;
|
||||
u32 evtbd_addr_hi;
|
||||
/* Event buffer descriptor ring count */
|
||||
u32 evtbd_count;
|
||||
|
||||
/* Sleep cookie buffer physical address */
|
||||
u32 sleep_cookie_addr_lo;
|
||||
u32 sleep_cookie_addr_hi;
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_ds_command {
|
||||
__le16 command;
|
||||
__le16 size;
|
||||
|
@ -1184,6 +1209,7 @@ struct host_cmd_ds_command {
|
|||
struct host_cmd_ds_rf_reg_access rf_reg;
|
||||
struct host_cmd_ds_pmic_reg_access pmic_reg;
|
||||
struct host_cmd_ds_set_bss_mode bss_mode;
|
||||
struct host_cmd_ds_pcie_details pcie_host_spec;
|
||||
struct host_cmd_ds_802_11_eeprom_access eeprom;
|
||||
} params;
|
||||
} __packed;
|
||||
|
|
|
@ -191,7 +191,12 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
|
|||
(adapter->sleep_cfm->data);
|
||||
|
||||
adapter->cmd_sent = false;
|
||||
adapter->data_sent = true;
|
||||
|
||||
if (adapter->iface_type == MWIFIEX_PCIE)
|
||||
adapter->data_sent = false;
|
||||
else
|
||||
adapter->data_sent = true;
|
||||
|
||||
adapter->cmd_resp_received = false;
|
||||
adapter->event_received = false;
|
||||
adapter->data_received = false;
|
||||
|
@ -581,11 +586,13 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
|
|||
int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
|
||||
struct mwifiex_fw_image *pmfw)
|
||||
{
|
||||
int ret, winner;
|
||||
int ret;
|
||||
u32 poll_num = 1;
|
||||
|
||||
adapter->winner = 0;
|
||||
|
||||
/* Check if firmware is already running */
|
||||
ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner);
|
||||
ret = adapter->if_ops.check_fw_status(adapter, poll_num);
|
||||
if (!ret) {
|
||||
dev_notice(adapter->dev,
|
||||
"WLAN FW already running! Skip FW download\n");
|
||||
|
@ -594,7 +601,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
|
|||
poll_num = MAX_FIRMWARE_POLL_TRIES;
|
||||
|
||||
/* Check if we are the winner for downloading FW */
|
||||
if (!winner) {
|
||||
if (!adapter->winner) {
|
||||
dev_notice(adapter->dev,
|
||||
"Other interface already running!"
|
||||
" Skip FW download\n");
|
||||
|
@ -612,7 +619,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
|
|||
|
||||
poll_fw:
|
||||
/* Check if the firmware is downloaded successfully or not */
|
||||
ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL);
|
||||
ret = adapter->if_ops.check_fw_status(adapter, poll_num);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "FW failed to be active in time\n");
|
||||
return -1;
|
||||
|
|
|
@ -661,7 +661,7 @@ mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
|
|||
*/
|
||||
int
|
||||
mwifiex_add_card(void *card, struct semaphore *sem,
|
||||
struct mwifiex_if_ops *if_ops)
|
||||
struct mwifiex_if_ops *if_ops, u8 iface_type)
|
||||
{
|
||||
struct mwifiex_adapter *adapter;
|
||||
char fmt[64];
|
||||
|
@ -675,6 +675,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
|
|||
goto err_init_sw;
|
||||
}
|
||||
|
||||
adapter->iface_type = iface_type;
|
||||
|
||||
adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
|
||||
adapter->surprise_removed = false;
|
||||
init_waitqueue_head(&adapter->init_wait_q);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "ioctl.h"
|
||||
#include "util.h"
|
||||
#include "fw.h"
|
||||
#include "pcie.h"
|
||||
|
||||
extern const char driver_version[];
|
||||
|
||||
|
@ -107,6 +108,8 @@ enum {
|
|||
|
||||
#define MAX_FREQUENCY_BAND_BG 2484
|
||||
|
||||
#define MWIFIEX_EVENT_HEADER_LEN 4
|
||||
|
||||
struct mwifiex_dbg {
|
||||
u32 num_cmd_host_to_card_failure;
|
||||
u32 num_cmd_sleep_cfm_host_to_card_failure;
|
||||
|
@ -156,6 +159,11 @@ enum MWIFIEX_PS_STATE {
|
|||
PS_STATE_SLEEP
|
||||
};
|
||||
|
||||
enum mwifiex_iface_type {
|
||||
MWIFIEX_SDIO,
|
||||
MWIFIEX_PCIE,
|
||||
};
|
||||
|
||||
struct mwifiex_add_ba_param {
|
||||
u32 tx_win_size;
|
||||
u32 rx_win_size;
|
||||
|
@ -517,27 +525,31 @@ struct cmd_ctrl_node {
|
|||
struct mwifiex_if_ops {
|
||||
int (*init_if) (struct mwifiex_adapter *);
|
||||
void (*cleanup_if) (struct mwifiex_adapter *);
|
||||
int (*check_fw_status) (struct mwifiex_adapter *, u32, int *);
|
||||
int (*check_fw_status) (struct mwifiex_adapter *, u32);
|
||||
int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
|
||||
int (*register_dev) (struct mwifiex_adapter *);
|
||||
void (*unregister_dev) (struct mwifiex_adapter *);
|
||||
int (*enable_int) (struct mwifiex_adapter *);
|
||||
int (*process_int_status) (struct mwifiex_adapter *);
|
||||
int (*host_to_card) (struct mwifiex_adapter *, u8,
|
||||
u8 *payload, u32 pkt_len,
|
||||
int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
|
||||
struct mwifiex_tx_param *);
|
||||
int (*wakeup) (struct mwifiex_adapter *);
|
||||
int (*wakeup_complete) (struct mwifiex_adapter *);
|
||||
|
||||
/* Interface specific functions */
|
||||
void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
|
||||
void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
|
||||
int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *);
|
||||
int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *);
|
||||
};
|
||||
|
||||
struct mwifiex_adapter {
|
||||
u8 iface_type;
|
||||
struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
|
||||
u8 priv_num;
|
||||
const struct firmware *firmware;
|
||||
char fw_name[32];
|
||||
int winner;
|
||||
struct device *dev;
|
||||
bool surprise_removed;
|
||||
u32 fw_release_number;
|
||||
|
@ -872,7 +884,7 @@ struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
|
|||
*adapter, u8 bss_index);
|
||||
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
|
||||
u32 func_init_shutdown);
|
||||
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *);
|
||||
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
|
||||
int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
|
||||
|
||||
void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,148 @@
|
|||
/* @file mwifiex_pcie.h
|
||||
*
|
||||
* @brief This file contains definitions for PCI-E interface.
|
||||
* driver.
|
||||
*
|
||||
* Copyright (C) 2011, Marvell International Ltd.
|
||||
*
|
||||
* This software file (the "File") is distributed by Marvell International
|
||||
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
|
||||
* (the "License"). You may use, redistribute and/or modify this File in
|
||||
* accordance with the terms and conditions of the License, a copy of which
|
||||
* is available by writing to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
|
||||
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
||||
*
|
||||
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
|
||||
* this warranty disclaimer.
|
||||
*/
|
||||
|
||||
#ifndef _MWIFIEX_PCIE_H
|
||||
#define _MWIFIEX_PCIE_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pcieport_if.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin"
|
||||
|
||||
/* Constants for Buffer Descriptor (BD) rings */
|
||||
#define MWIFIEX_MAX_TXRX_BD 0x20
|
||||
#define MWIFIEX_TXBD_MASK 0x3F
|
||||
#define MWIFIEX_RXBD_MASK 0x3F
|
||||
|
||||
#define MWIFIEX_MAX_EVT_BD 0x04
|
||||
#define MWIFIEX_EVTBD_MASK 0x07
|
||||
|
||||
/* PCIE INTERNAL REGISTERS */
|
||||
#define PCIE_SCRATCH_0_REG 0xC10
|
||||
#define PCIE_SCRATCH_1_REG 0xC14
|
||||
#define PCIE_CPU_INT_EVENT 0xC18
|
||||
#define PCIE_CPU_INT_STATUS 0xC1C
|
||||
#define PCIE_HOST_INT_STATUS 0xC30
|
||||
#define PCIE_HOST_INT_MASK 0xC34
|
||||
#define PCIE_HOST_INT_STATUS_MASK 0xC3C
|
||||
#define PCIE_SCRATCH_2_REG 0xC40
|
||||
#define PCIE_SCRATCH_3_REG 0xC44
|
||||
#define PCIE_SCRATCH_4_REG 0xCC0
|
||||
#define PCIE_SCRATCH_5_REG 0xCC4
|
||||
#define PCIE_SCRATCH_6_REG 0xCC8
|
||||
#define PCIE_SCRATCH_7_REG 0xCCC
|
||||
#define PCIE_SCRATCH_8_REG 0xCD0
|
||||
#define PCIE_SCRATCH_9_REG 0xCD4
|
||||
#define PCIE_SCRATCH_10_REG 0xCD8
|
||||
#define PCIE_SCRATCH_11_REG 0xCDC
|
||||
#define PCIE_SCRATCH_12_REG 0xCE0
|
||||
|
||||
#define CPU_INTR_DNLD_RDY BIT(0)
|
||||
#define CPU_INTR_DOOR_BELL BIT(1)
|
||||
#define CPU_INTR_SLEEP_CFM_DONE BIT(2)
|
||||
#define CPU_INTR_RESET BIT(3)
|
||||
|
||||
#define HOST_INTR_DNLD_DONE BIT(0)
|
||||
#define HOST_INTR_UPLD_RDY BIT(1)
|
||||
#define HOST_INTR_CMD_DONE BIT(2)
|
||||
#define HOST_INTR_EVENT_RDY BIT(3)
|
||||
#define HOST_INTR_MASK (HOST_INTR_DNLD_DONE | \
|
||||
HOST_INTR_UPLD_RDY | \
|
||||
HOST_INTR_CMD_DONE | \
|
||||
HOST_INTR_EVENT_RDY)
|
||||
|
||||
#define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7)
|
||||
#define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0)
|
||||
#define MWIFIEX_BD_FLAG_LAST_DESC BIT(1)
|
||||
#define REG_CMD_ADDR_LO PCIE_SCRATCH_0_REG
|
||||
#define REG_CMD_ADDR_HI PCIE_SCRATCH_1_REG
|
||||
#define REG_CMD_SIZE PCIE_SCRATCH_2_REG
|
||||
|
||||
#define REG_CMDRSP_ADDR_LO PCIE_SCRATCH_4_REG
|
||||
#define REG_CMDRSP_ADDR_HI PCIE_SCRATCH_5_REG
|
||||
|
||||
/* TX buffer description read pointer */
|
||||
#define REG_TXBD_RDPTR PCIE_SCRATCH_6_REG
|
||||
/* TX buffer description write pointer */
|
||||
#define REG_TXBD_WRPTR PCIE_SCRATCH_7_REG
|
||||
/* RX buffer description read pointer */
|
||||
#define REG_RXBD_RDPTR PCIE_SCRATCH_8_REG
|
||||
/* RX buffer description write pointer */
|
||||
#define REG_RXBD_WRPTR PCIE_SCRATCH_9_REG
|
||||
/* Event buffer description read pointer */
|
||||
#define REG_EVTBD_RDPTR PCIE_SCRATCH_10_REG
|
||||
/* Event buffer description write pointer */
|
||||
#define REG_EVTBD_WRPTR PCIE_SCRATCH_11_REG
|
||||
/* Driver ready signature write pointer */
|
||||
#define REG_DRV_READY PCIE_SCRATCH_12_REG
|
||||
|
||||
/* Max retry number of command write */
|
||||
#define MAX_WRITE_IOMEM_RETRY 2
|
||||
/* Define PCIE block size for firmware download */
|
||||
#define MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD 256
|
||||
/* FW awake cookie after FW ready */
|
||||
#define FW_AWAKE_COOKIE (0xAA55AA55)
|
||||
|
||||
struct mwifiex_pcie_buf_desc {
|
||||
u64 paddr;
|
||||
u16 len;
|
||||
u16 flags;
|
||||
} __packed;
|
||||
|
||||
struct pcie_service_card {
|
||||
struct pci_dev *dev;
|
||||
struct mwifiex_adapter *adapter;
|
||||
|
||||
u32 txbd_wrptr;
|
||||
u32 txbd_rdptr;
|
||||
u32 txbd_ring_size;
|
||||
u8 *txbd_ring_vbase;
|
||||
phys_addr_t txbd_ring_pbase;
|
||||
struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD];
|
||||
struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD];
|
||||
|
||||
u32 rxbd_wrptr;
|
||||
u32 rxbd_rdptr;
|
||||
u32 rxbd_ring_size;
|
||||
u8 *rxbd_ring_vbase;
|
||||
phys_addr_t rxbd_ring_pbase;
|
||||
struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD];
|
||||
struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD];
|
||||
|
||||
u32 evtbd_wrptr;
|
||||
u32 evtbd_rdptr;
|
||||
u32 evtbd_ring_size;
|
||||
u8 *evtbd_ring_vbase;
|
||||
phys_addr_t evtbd_ring_pbase;
|
||||
struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD];
|
||||
struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD];
|
||||
|
||||
struct sk_buff *cmd_buf;
|
||||
struct sk_buff *cmdrsp_buf;
|
||||
struct sk_buff *sleep_cookie;
|
||||
void __iomem *pci_mmap;
|
||||
void __iomem *pci_mmap1;
|
||||
};
|
||||
|
||||
#endif /* _MWIFIEX_PCIE_H */
|
|
@ -89,7 +89,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) {
|
||||
if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops,
|
||||
MWIFIEX_SDIO)) {
|
||||
pr_err("%s: add card failed\n", __func__);
|
||||
kfree(card);
|
||||
sdio_claim_host(func);
|
||||
|
@ -830,7 +831,7 @@ done:
|
|||
* The winner interface is also determined by this function.
|
||||
*/
|
||||
static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
|
||||
u32 poll_num, int *winner)
|
||||
u32 poll_num)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 firmware_stat;
|
||||
|
@ -842,7 +843,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
|
|||
ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
|
||||
if (ret)
|
||||
continue;
|
||||
if (firmware_stat == FIRMWARE_READY) {
|
||||
if (firmware_stat == FIRMWARE_READY_SDIO) {
|
||||
ret = 0;
|
||||
break;
|
||||
} else {
|
||||
|
@ -851,15 +852,15 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
|
|||
}
|
||||
}
|
||||
|
||||
if (winner && ret) {
|
||||
if (ret) {
|
||||
if (mwifiex_read_reg
|
||||
(adapter, CARD_FW_STATUS0_REG, &winner_status))
|
||||
winner_status = 0;
|
||||
|
||||
if (winner_status)
|
||||
*winner = 0;
|
||||
adapter->winner = 0;
|
||||
else
|
||||
*winner = 1;
|
||||
adapter->winner = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1413,7 +1414,7 @@ tx_curr_single:
|
|||
* the type. The firmware handles the packets based upon this set type.
|
||||
*/
|
||||
static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
|
||||
u8 type, u8 *payload, u32 pkt_len,
|
||||
u8 type, struct sk_buff *skb,
|
||||
struct mwifiex_tx_param *tx_param)
|
||||
{
|
||||
struct sdio_mmc_card *card = adapter->card;
|
||||
|
@ -1421,6 +1422,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
|
|||
u32 buf_block_len;
|
||||
u32 blk_size;
|
||||
u8 port = CTRL_PORT;
|
||||
u8 *payload = (u8 *)skb->data;
|
||||
u32 pkt_len = skb->len;
|
||||
|
||||
/* Allocate buffer and copy payload */
|
||||
blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
|
@ -1722,6 +1725,8 @@ static struct mwifiex_if_ops sdio_ops = {
|
|||
/* SDIO specific */
|
||||
.update_mp_end_port = mwifiex_update_mp_end_port,
|
||||
.cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
|
||||
.cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
|
||||
.event_complete = mwifiex_sdio_event_complete,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -169,9 +169,6 @@
|
|||
/* Rx unit register */
|
||||
#define CARD_RX_UNIT_REG 0x63
|
||||
|
||||
/* Event header len w/o 4 bytes of interface header */
|
||||
#define MWIFIEX_EVENT_HEADER_LEN 4
|
||||
|
||||
/* Max retry number of CMD53 write */
|
||||
#define MAX_WRITE_IOMEM_RETRY 2
|
||||
|
||||
|
@ -304,4 +301,25 @@ struct sdio_mmc_card {
|
|||
struct mwifiex_sdio_mpa_tx mpa_tx;
|
||||
struct mwifiex_sdio_mpa_rx mpa_rx;
|
||||
};
|
||||
|
||||
/*
|
||||
* .cmdrsp_complete handler
|
||||
*/
|
||||
static inline int mwifiex_sdio_cmdrsp_complete(struct mwifiex_adapter *adapter,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* .event_complete handler
|
||||
*/
|
||||
static inline int mwifiex_sdio_event_complete(struct mwifiex_adapter *adapter,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _MWIFIEX_SDIO_H */
|
||||
|
|
|
@ -901,6 +901,59 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares command to set PCI-Express
|
||||
* host buffer configuration
|
||||
*
|
||||
* Preparation includes -
|
||||
* - Setting command ID, action and proper size
|
||||
* - Setting host buffer configuration
|
||||
* - Ensuring correct endian-ness
|
||||
*/
|
||||
static int
|
||||
mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd, u16 action)
|
||||
{
|
||||
struct host_cmd_ds_pcie_details *host_spec =
|
||||
&cmd->params.pcie_host_spec;
|
||||
struct pcie_service_card *card = priv->adapter->card;
|
||||
phys_addr_t *buf_pa;
|
||||
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS);
|
||||
cmd->size = cpu_to_le16(sizeof(struct
|
||||
host_cmd_ds_pcie_details) + S_DS_GEN);
|
||||
cmd->result = 0;
|
||||
|
||||
memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details));
|
||||
|
||||
if (action == HostCmd_ACT_GEN_SET) {
|
||||
/* Send the ring base addresses and count to firmware */
|
||||
host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
|
||||
host_spec->txbd_addr_hi =
|
||||
(u32)(((u64)card->txbd_ring_pbase)>>32);
|
||||
host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
|
||||
host_spec->rxbd_addr_hi =
|
||||
(u32)(((u64)card->rxbd_ring_pbase)>>32);
|
||||
host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->evtbd_addr_lo =
|
||||
(u32)(card->evtbd_ring_pbase);
|
||||
host_spec->evtbd_addr_hi =
|
||||
(u32)(((u64)card->evtbd_ring_pbase)>>32);
|
||||
host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
|
||||
if (card->sleep_cookie) {
|
||||
buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
|
||||
host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
|
||||
host_spec->sleep_cookie_addr_hi =
|
||||
(u32) (((u64)*buf_pa) >> 32);
|
||||
dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: "
|
||||
"0x%x\n", host_spec->sleep_cookie_addr_lo);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares the commands before sending them to the firmware.
|
||||
*
|
||||
|
@ -1079,6 +1132,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
|
|||
host_cmd_ds_set_bss_mode) + S_DS_GEN);
|
||||
ret = 0;
|
||||
break;
|
||||
case HostCmd_CMD_PCIE_DESC_DETAILS:
|
||||
ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action);
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->adapter->dev,
|
||||
"PREP_CMD: unknown cmd- %#x\n", cmd_no);
|
||||
|
@ -1095,6 +1151,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
|
|||
* working state.
|
||||
*
|
||||
* The following commands are issued sequentially -
|
||||
* - Set PCI-Express host buffer configuration (PCIE only)
|
||||
* - Function init (for first interface only)
|
||||
* - Read MAC address (for first interface only)
|
||||
* - Reconfigure Tx buffer size (for first interface only)
|
||||
|
@ -1116,6 +1173,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
|
|||
struct mwifiex_ds_11n_tx_cfg tx_cfg;
|
||||
|
||||
if (first_sta) {
|
||||
if (priv->adapter->iface_type == MWIFIEX_PCIE) {
|
||||
ret = mwifiex_send_cmd_async(priv,
|
||||
HostCmd_CMD_PCIE_DESC_DETAILS,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL);
|
||||
|
|
|
@ -952,6 +952,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
|||
case HostCmd_CMD_11N_CFG:
|
||||
ret = mwifiex_ret_11n_cfg(resp, data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_PCIE_DESC_DETAILS:
|
||||
break;
|
||||
default:
|
||||
dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
|
||||
resp->command);
|
||||
|
|
|
@ -151,7 +151,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
|
|||
skb_push(skb, INTF_HEADER_LEN);
|
||||
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
|
||||
skb->data, skb->len, NULL);
|
||||
skb, NULL);
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
adapter->data_sent = true;
|
||||
|
|
|
@ -78,7 +78,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
|
|||
(struct txpd *) (head_ptr + INTF_HEADER_LEN);
|
||||
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
|
||||
skb->data, skb->len, tx_param);
|
||||
skb, tx_param);
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
|
|
|
@ -22,11 +22,16 @@
|
|||
|
||||
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
|
||||
{
|
||||
return (struct mwifiex_rxinfo *)skb->cb;
|
||||
return (struct mwifiex_rxinfo *)(skb->cb + sizeof(phys_addr_t));
|
||||
}
|
||||
|
||||
static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
|
||||
{
|
||||
return (struct mwifiex_txinfo *)skb->cb;
|
||||
return (struct mwifiex_txinfo *)(skb->cb + sizeof(phys_addr_t));
|
||||
}
|
||||
|
||||
static inline phys_addr_t *MWIFIEX_SKB_PACB(struct sk_buff *skb)
|
||||
{
|
||||
return (phys_addr_t *)skb->cb;
|
||||
}
|
||||
#endif /* !_MWIFIEX_UTIL_H_ */
|
||||
|
|
|
@ -1125,8 +1125,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
|
|||
tx_param.next_pkt_len =
|
||||
((skb_next) ? skb_next->len +
|
||||
sizeof(struct txpd) : 0);
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
|
||||
skb->data, skb->len, &tx_param);
|
||||
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, skb,
|
||||
&tx_param);
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче