Commit d930faee authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville

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: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarRamesh Radhakrishnan <rramesh@marvell.com>
Signed-off-by: default avatarYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: default avatarKiran Divekar <dkiran@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarFrank Huang <frankh@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ec205999
...@@ -246,8 +246,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ...@@ -246,8 +246,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
tx_param.next_pkt_len = 0; tx_param.next_pkt_len = 0;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
skb_aggr->data, skb_aggr, &tx_param);
skb_aggr->len, &tx_param);
switch (ret) { switch (ret) {
case -EBUSY: case -EBUSY:
spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
......
...@@ -19,3 +19,14 @@ config MWIFIEX_SDIO ...@@ -19,3 +19,14 @@ config MWIFIEX_SDIO
If you choose to build it as a module, it will be called If you choose to build it as a module, it will be called
mwifiex_sdio. 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 ...@@ -39,3 +39,6 @@ obj-$(CONFIG_MWIFIEX) += mwifiex.o
mwifiex_sdio-y += sdio.o mwifiex_sdio-y += sdio.o
obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_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, ...@@ -94,7 +94,7 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
skb_trim(cmd_node->cmd_skb, 0); skb_trim(cmd_node->cmd_skb, 0);
if (cmd_node->resp_skb) { 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; cmd_node->resp_skb = NULL;
} }
} }
...@@ -176,8 +176,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, ...@@ -176,8 +176,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
cmd_node->cmd_skb->data, cmd_node->cmd_skb, NULL);
cmd_node->cmd_skb->len, NULL);
skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
...@@ -238,8 +237,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) ...@@ -238,8 +237,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
skb_push(adapter->sleep_cfm, INTF_HEADER_LEN); skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
adapter->sleep_cfm->data, adapter->sleep_cfm, NULL);
adapter->sleep_cfm->len, NULL);
skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN); skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
if (ret == -1) { if (ret == -1) {
...@@ -402,8 +400,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) ...@@ -402,8 +400,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
adapter->event_cause = 0; adapter->event_cause = 0;
adapter->event_skb = NULL; adapter->event_skb = NULL;
adapter->if_ops.event_complete(adapter, skb);
dev_kfree_skb_any(skb);
return ret; return ret;
} }
......
...@@ -84,7 +84,8 @@ enum KEY_TYPE_ID { ...@@ -84,7 +84,8 @@ enum KEY_TYPE_ID {
#define MAX_FIRMWARE_POLL_TRIES 100 #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 { enum MWIFIEX_802_11_PRIVACY_FILTER {
MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL, MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
...@@ -221,7 +222,7 @@ enum MWIFIEX_802_11_WEP_STATUS { ...@@ -221,7 +222,7 @@ enum MWIFIEX_802_11_WEP_STATUS {
#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5 #define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed #define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
#define HostCmd_CMD_SET_BSS_MODE 0x00f7 #define HostCmd_CMD_SET_BSS_MODE 0x00f7
#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
enum ENH_PS_MODES { enum ENH_PS_MODES {
EN_PS = 1, EN_PS = 1,
...@@ -1137,6 +1138,30 @@ struct host_cmd_ds_set_bss_mode { ...@@ -1137,6 +1138,30 @@ struct host_cmd_ds_set_bss_mode {
u8 con_type; u8 con_type;
} __packed; } __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 { struct host_cmd_ds_command {
__le16 command; __le16 command;
__le16 size; __le16 size;
...@@ -1184,6 +1209,7 @@ struct host_cmd_ds_command { ...@@ -1184,6 +1209,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_rf_reg_access rf_reg; struct host_cmd_ds_rf_reg_access rf_reg;
struct host_cmd_ds_pmic_reg_access pmic_reg; struct host_cmd_ds_pmic_reg_access pmic_reg;
struct host_cmd_ds_set_bss_mode bss_mode; 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; struct host_cmd_ds_802_11_eeprom_access eeprom;
} params; } params;
} __packed; } __packed;
......
...@@ -191,7 +191,12 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) ...@@ -191,7 +191,12 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
(adapter->sleep_cfm->data); (adapter->sleep_cfm->data);
adapter->cmd_sent = false; 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->cmd_resp_received = false;
adapter->event_received = false; adapter->event_received = false;
adapter->data_received = false; adapter->data_received = false;
...@@ -581,11 +586,13 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) ...@@ -581,11 +586,13 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
struct mwifiex_fw_image *pmfw) struct mwifiex_fw_image *pmfw)
{ {
int ret, winner; int ret;
u32 poll_num = 1; u32 poll_num = 1;
adapter->winner = 0;
/* Check if firmware is already running */ /* 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) { if (!ret) {
dev_notice(adapter->dev, dev_notice(adapter->dev,
"WLAN FW already running! Skip FW download\n"); "WLAN FW already running! Skip FW download\n");
...@@ -594,7 +601,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, ...@@ -594,7 +601,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
poll_num = MAX_FIRMWARE_POLL_TRIES; poll_num = MAX_FIRMWARE_POLL_TRIES;
/* Check if we are the winner for downloading FW */ /* Check if we are the winner for downloading FW */
if (!winner) { if (!adapter->winner) {
dev_notice(adapter->dev, dev_notice(adapter->dev,
"Other interface already running!" "Other interface already running!"
" Skip FW download\n"); " Skip FW download\n");
...@@ -612,7 +619,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, ...@@ -612,7 +619,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
poll_fw: poll_fw:
/* Check if the firmware is downloaded successfully or not */ /* 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) { if (ret) {
dev_err(adapter->dev, "FW failed to be active in time\n"); dev_err(adapter->dev, "FW failed to be active in time\n");
return -1; return -1;
......
...@@ -661,7 +661,7 @@ mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) ...@@ -661,7 +661,7 @@ mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
*/ */
int int
mwifiex_add_card(void *card, struct semaphore *sem, 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; struct mwifiex_adapter *adapter;
char fmt[64]; char fmt[64];
...@@ -675,6 +675,8 @@ mwifiex_add_card(void *card, struct semaphore *sem, ...@@ -675,6 +675,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
goto err_init_sw; goto err_init_sw;
} }
adapter->iface_type = iface_type;
adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
adapter->surprise_removed = false; adapter->surprise_removed = false;
init_waitqueue_head(&adapter->init_wait_q); init_waitqueue_head(&adapter->init_wait_q);
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "ioctl.h" #include "ioctl.h"
#include "util.h" #include "util.h"
#include "fw.h" #include "fw.h"
#include "pcie.h"
extern const char driver_version[]; extern const char driver_version[];
...@@ -107,6 +108,8 @@ enum { ...@@ -107,6 +108,8 @@ enum {
#define MAX_FREQUENCY_BAND_BG 2484 #define MAX_FREQUENCY_BAND_BG 2484
#define MWIFIEX_EVENT_HEADER_LEN 4
struct mwifiex_dbg { struct mwifiex_dbg {
u32 num_cmd_host_to_card_failure; u32 num_cmd_host_to_card_failure;
u32 num_cmd_sleep_cfm_host_to_card_failure; u32 num_cmd_sleep_cfm_host_to_card_failure;
...@@ -156,6 +159,11 @@ enum MWIFIEX_PS_STATE { ...@@ -156,6 +159,11 @@ enum MWIFIEX_PS_STATE {
PS_STATE_SLEEP PS_STATE_SLEEP
}; };
enum mwifiex_iface_type {
MWIFIEX_SDIO,
MWIFIEX_PCIE,
};
struct mwifiex_add_ba_param { struct mwifiex_add_ba_param {
u32 tx_win_size; u32 tx_win_size;
u32 rx_win_size; u32 rx_win_size;
...@@ -517,27 +525,31 @@ struct cmd_ctrl_node { ...@@ -517,27 +525,31 @@ struct cmd_ctrl_node {
struct mwifiex_if_ops { struct mwifiex_if_ops {
int (*init_if) (struct mwifiex_adapter *); int (*init_if) (struct mwifiex_adapter *);
void (*cleanup_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 (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
int (*register_dev) (struct mwifiex_adapter *); int (*register_dev) (struct mwifiex_adapter *);
void (*unregister_dev) (struct mwifiex_adapter *); void (*unregister_dev) (struct mwifiex_adapter *);
int (*enable_int) (struct mwifiex_adapter *); int (*enable_int) (struct mwifiex_adapter *);
int (*process_int_status) (struct mwifiex_adapter *); int (*process_int_status) (struct mwifiex_adapter *);
int (*host_to_card) (struct mwifiex_adapter *, u8, int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
u8 *payload, u32 pkt_len,
struct mwifiex_tx_param *); struct mwifiex_tx_param *);
int (*wakeup) (struct mwifiex_adapter *); int (*wakeup) (struct mwifiex_adapter *);
int (*wakeup_complete) (struct mwifiex_adapter *); int (*wakeup_complete) (struct mwifiex_adapter *);
/* Interface specific functions */
void (*update_mp_end_port) (struct mwifiex_adapter *, u16); void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
void (*cleanup_mpa_buf) (struct mwifiex_adapter *); 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 { struct mwifiex_adapter {
u8 iface_type;
struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
u8 priv_num; u8 priv_num;
const struct firmware *firmware; const struct firmware *firmware;
char fw_name[32]; char fw_name[32];
int winner;
struct device *dev; struct device *dev;
bool surprise_removed; bool surprise_removed;
u32 fw_release_number; u32 fw_release_number;
...@@ -872,7 +884,7 @@ struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter ...@@ -872,7 +884,7 @@ struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
*adapter, u8 bss_index); *adapter, u8 bss_index);
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
u32 func_init_shutdown); 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 *); int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
......
This diff is collapsed.
/* @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) ...@@ -89,7 +89,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
return -EIO; 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__); pr_err("%s: add card failed\n", __func__);
kfree(card); kfree(card);
sdio_claim_host(func); sdio_claim_host(func);
...@@ -830,7 +831,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ...@@ -830,7 +831,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
* The winner interface is also determined by this function. * The winner interface is also determined by this function.
*/ */
static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
u32 poll_num, int *winner) u32 poll_num)
{ {
int ret = 0; int ret = 0;
u16 firmware_stat; u16 firmware_stat;
...@@ -842,7 +843,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, ...@@ -842,7 +843,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
if (ret) if (ret)
continue; continue;
if (firmware_stat == FIRMWARE_READY) { if (firmware_stat == FIRMWARE_READY_SDIO) {
ret = 0; ret = 0;
break; break;
} else { } else {
...@@ -851,15 +852,15 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, ...@@ -851,15 +852,15 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
} }
} }
if (winner && ret) { if (ret) {
if (mwifiex_read_reg if (mwifiex_read_reg
(adapter, CARD_FW_STATUS0_REG, &winner_status)) (adapter, CARD_FW_STATUS0_REG, &winner_status))
winner_status = 0; winner_status = 0;
if (winner_status) if (winner_status)
*winner = 0; adapter->winner = 0;
else else
*winner = 1; adapter->winner = 1;
} }
return ret; return ret;
} }
...@@ -1413,7 +1414,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, ...@@ -1413,7 +1414,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
* the type. The firmware handles the packets based upon this set type. * the type. The firmware handles the packets based upon this set type.
*/ */
static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, 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 mwifiex_tx_param *tx_param)
{ {
struct sdio_mmc_card *card = adapter->card; struct sdio_mmc_card *card = adapter->card;
...@@ -1421,6 +1422,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, ...@@ -1421,6 +1422,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
u32 buf_block_len; u32 buf_block_len;
u32 blk_size; u32 blk_size;
u8 port = CTRL_PORT; u8 port = CTRL_PORT;
u8 *payload = (u8 *)skb->data;
u32 pkt_len = skb->len;
/* Allocate buffer and copy payload */ /* Allocate buffer and copy payload */
blk_size = MWIFIEX_SDIO_BLOCK_SIZE; blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
...@@ -1722,6 +1725,8 @@ static struct mwifiex_if_ops sdio_ops = { ...@@ -1722,6 +1725,8 @@ static struct mwifiex_if_ops sdio_ops = {
/* SDIO specific */ /* SDIO specific */
.update_mp_end_port = mwifiex_update_mp_end_port, .update_mp_end_port = mwifiex_update_mp_end_port,
.cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
.cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
.event_complete = mwifiex_sdio_event_complete,
}; };
/* /*
......
...@@ -169,9 +169,6 @@ ...@@ -169,9 +169,6 @@
/* Rx unit register */ /* Rx unit register */
#define CARD_RX_UNIT_REG 0x63 #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 */ /* Max retry number of CMD53 write */
#define MAX_WRITE_IOMEM_RETRY 2 #define MAX_WRITE_IOMEM_RETRY 2
...@@ -304,4 +301,25 @@ struct sdio_mmc_card { ...@@ -304,4 +301,25 @@ struct sdio_mmc_card {
struct mwifiex_sdio_mpa_tx mpa_tx; struct mwifiex_sdio_mpa_tx mpa_tx;
struct mwifiex_sdio_mpa_rx mpa_rx; 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 */ #endif /* _MWIFIEX_SDIO_H */
...@@ -901,6 +901,59 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, ...@@ -901,6 +901,59 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
return 0; 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. * 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, ...@@ -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); host_cmd_ds_set_bss_mode) + S_DS_GEN);
ret = 0; ret = 0;
break; break;
case HostCmd_CMD_PCIE_DESC_DETAILS:
ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action);
break;
default: default:
dev_err(priv->adapter->dev, dev_err(priv->adapter->dev,
"PREP_CMD: unknown cmd- %#x\n", cmd_no); "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, ...@@ -1095,6 +1151,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
* working state. * working state.
* *
* The following commands are issued sequentially - * The following commands are issued sequentially -
* - Set PCI-Express host buffer configuration (PCIE only)
* - Function init (for first interface only) * - Function init (for first interface only)
* - Read MAC address (for first interface only) * - Read MAC address (for first interface only)
* - Reconfigure Tx buffer size (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) ...@@ -1116,6 +1173,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
struct mwifiex_ds_11n_tx_cfg tx_cfg; struct mwifiex_ds_11n_tx_cfg tx_cfg;
if (first_sta) { 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, ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
HostCmd_ACT_GEN_SET, 0, NULL); HostCmd_ACT_GEN_SET, 0, NULL);
......
...@@ -952,6 +952,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, ...@@ -952,6 +952,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
case HostCmd_CMD_11N_CFG: case HostCmd_CMD_11N_CFG:
ret = mwifiex_ret_11n_cfg(resp, data_buf); ret = mwifiex_ret_11n_cfg(resp, data_buf);
break; break;
case HostCmd_CMD_PCIE_DESC_DETAILS:
break;
default: default:
dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
resp->command); resp->command);
......
...@@ -151,7 +151,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) ...@@ -151,7 +151,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
skb_push(skb, INTF_HEADER_LEN); skb_push(skb, INTF_HEADER_LEN);
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
skb->data, skb->len, NULL); skb, NULL);
switch (ret) { switch (ret) {
case -EBUSY: case -EBUSY:
adapter->data_sent = true; adapter->data_sent = true;
......
...@@ -78,7 +78,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, ...@@ -78,7 +78,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
(struct txpd *) (head_ptr + INTF_HEADER_LEN); (struct txpd *) (head_ptr + INTF_HEADER_LEN);
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
skb->data, skb->len, tx_param); skb, tx_param);
} }
switch (ret) { switch (ret) {
......
...@@ -22,11 +22,16 @@ ...@@ -22,11 +22,16 @@
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) 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) 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_ */ #endif /* !_MWIFIEX_UTIL_H_ */
...@@ -1125,8 +1125,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, ...@@ -1125,8 +1125,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
tx_param.next_pkt_len = tx_param.next_pkt_len =
((skb_next) ? skb_next->len + ((skb_next) ? skb_next->len +
sizeof(struct txpd) : 0); sizeof(struct txpd) : 0);
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, skb,
skb->data, skb->len, &tx_param); &tx_param);
switch (ret) { switch (ret) {
case -EBUSY: case -EBUSY:
dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment