aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rsi')
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_hal.c3
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c6
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio_ops.c173
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c36
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb_ops.c2
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h8
6 files changed, 95 insertions, 133 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 3f7e3cfb6f00..ce9892152f4d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -248,7 +248,8 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
rsi_set_len_qno(&data_desc->len_qno,
(skb->len - FRAME_DESC_SZ),
RSI_WIFI_MGMT_Q);
- if ((skb->len - header_size) == EAPOL4_PACKET_LEN) {
+ if (((skb->len - header_size) == EAPOL4_PACKET_LEN) ||
+ ((skb->len - header_size) == EAPOL4_PACKET_LEN - 2)) {
data_desc->misc_flags |=
RSI_DESC_REQUIRE_CFM_TO_HOST;
xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index a7b8684143f4..592e9dadcb55 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -153,9 +153,7 @@ static void rsi_handle_interrupt(struct sdio_func *function)
if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED)
return;
- dev->sdio_irq_task = current;
- rsi_interrupt_handler(adapter);
- dev->sdio_irq_task = NULL;
+ rsi_set_event(&dev->rx_thread.event);
}
/**
@@ -1058,8 +1056,6 @@ static int rsi_probe(struct sdio_func *pfunction,
rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
goto fail_kill_thread;
}
- skb_queue_head_init(&sdev->rx_q.head);
- sdev->rx_q.num_rx_pkts = 0;
sdio_claim_host(pfunction);
if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 7825c9a889d3..8ace1874e5cb 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -60,39 +60,20 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
return status;
}
+static void rsi_rx_handler(struct rsi_hw *adapter);
+
void rsi_sdio_rx_thread(struct rsi_common *common)
{
struct rsi_hw *adapter = common->priv;
struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
- struct sk_buff *skb;
- int status;
do {
rsi_wait_event(&sdev->rx_thread.event, EVENT_WAIT_FOREVER);
rsi_reset_event(&sdev->rx_thread.event);
+ rsi_rx_handler(adapter);
+ } while (!atomic_read(&sdev->rx_thread.thread_done));
- while (true) {
- if (atomic_read(&sdev->rx_thread.thread_done))
- goto out;
-
- skb = skb_dequeue(&sdev->rx_q.head);
- if (!skb)
- break;
- if (sdev->rx_q.num_rx_pkts > 0)
- sdev->rx_q.num_rx_pkts--;
- status = rsi_read_pkt(common, skb->data, skb->len);
- if (status) {
- rsi_dbg(ERR_ZONE, "Failed to read the packet\n");
- dev_kfree_skb(skb);
- break;
- }
- dev_kfree_skb(skb);
- }
- } while (1);
-
-out:
rsi_dbg(INFO_ZONE, "%s: Terminated SDIO RX thread\n", __func__);
- skb_queue_purge(&sdev->rx_q.head);
atomic_inc(&sdev->rx_thread.thread_done);
complete_and_exit(&sdev->rx_thread.completion, 0);
}
@@ -113,10 +94,6 @@ static int rsi_process_pkt(struct rsi_common *common)
u32 rcv_pkt_len = 0;
int status = 0;
u8 value = 0;
- struct sk_buff *skb;
-
- if (dev->rx_q.num_rx_pkts >= RSI_MAX_RX_PKTS)
- return 0;
num_blks = ((adapter->interrupt_status & 1) |
((adapter->interrupt_status >> RECV_NUM_BLOCKS) << 1));
@@ -144,22 +121,19 @@ static int rsi_process_pkt(struct rsi_common *common)
rcv_pkt_len = (num_blks * 256);
- skb = dev_alloc_skb(rcv_pkt_len);
- if (!skb)
- return -ENOMEM;
-
- status = rsi_sdio_host_intf_read_pkt(adapter, skb->data, rcv_pkt_len);
+ status = rsi_sdio_host_intf_read_pkt(adapter, dev->pktbuffer,
+ rcv_pkt_len);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n",
__func__);
- dev_kfree_skb(skb);
return status;
}
- skb_put(skb, rcv_pkt_len);
- skb_queue_tail(&dev->rx_q.head, skb);
- dev->rx_q.num_rx_pkts++;
- rsi_set_event(&dev->rx_thread.event);
+ status = rsi_read_pkt(common, dev->pktbuffer, rcv_pkt_len);
+ if (status) {
+ rsi_dbg(ERR_ZONE, "Failed to read the packet\n");
+ return status;
+ }
return 0;
}
@@ -251,18 +225,17 @@ int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
}
/**
- * rsi_interrupt_handler() - This function read and process SDIO interrupts.
+ * rsi_rx_handler() - Read and process SDIO interrupts.
* @adapter: Pointer to the adapter structure.
*
* Return: None.
*/
-void rsi_interrupt_handler(struct rsi_hw *adapter)
+static void rsi_rx_handler(struct rsi_hw *adapter)
{
struct rsi_common *common = adapter->priv;
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
int status;
- enum sdio_interrupt_type isr_type;
u8 isr_status = 0;
u8 fw_status = 0;
@@ -293,73 +266,69 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
__func__, isr_status, (1 << MSDU_PKT_PENDING),
(1 << FW_ASSERT_IND));
- do {
- RSI_GET_SDIO_INTERRUPT_TYPE(isr_status, isr_type);
-
- switch (isr_type) {
- case BUFFER_AVAILABLE:
- status = rsi_sdio_check_buffer_status(adapter,
- 0);
- if (status < 0)
- rsi_dbg(ERR_ZONE,
- "%s: Failed to check buffer status\n",
- __func__);
- rsi_sdio_ack_intr(common->priv,
- (1 << PKT_BUFF_AVAILABLE));
- rsi_set_event(&common->tx_thread.event);
-
- rsi_dbg(ISR_ZONE,
- "%s: ==> BUFFER_AVAILABLE <==\n",
- __func__);
- dev->buff_status_updated = true;
- break;
-
- case FIRMWARE_ASSERT_IND:
+ if (isr_status & BIT(PKT_BUFF_AVAILABLE)) {
+ status = rsi_sdio_check_buffer_status(adapter, 0);
+ if (status < 0)
rsi_dbg(ERR_ZONE,
- "%s: ==> FIRMWARE Assert <==\n",
+ "%s: Failed to check buffer status\n",
__func__);
- status = rsi_sdio_read_register(common->priv,
+ rsi_sdio_ack_intr(common->priv,
+ BIT(PKT_BUFF_AVAILABLE));
+ rsi_set_event(&common->tx_thread.event);
+
+ rsi_dbg(ISR_ZONE, "%s: ==> BUFFER_AVAILABLE <==\n",
+ __func__);
+ dev->buff_status_updated = true;
+
+ isr_status &= ~BIT(PKT_BUFF_AVAILABLE);
+ }
+
+ if (isr_status & BIT(FW_ASSERT_IND)) {
+ rsi_dbg(ERR_ZONE, "%s: ==> FIRMWARE Assert <==\n",
+ __func__);
+ status = rsi_sdio_read_register(common->priv,
SDIO_FW_STATUS_REG,
&fw_status);
- if (status) {
- rsi_dbg(ERR_ZONE,
- "%s: Failed to read f/w reg\n",
- __func__);
- } else {
- rsi_dbg(ERR_ZONE,
- "%s: Firmware Status is 0x%x\n",
- __func__ , fw_status);
- rsi_sdio_ack_intr(common->priv,
- (1 << FW_ASSERT_IND));
- }
-
- common->fsm_state = FSM_CARD_NOT_READY;
- break;
-
- case MSDU_PACKET_PENDING:
- rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n");
- dev->rx_info.total_sdio_msdu_pending_intr++;
-
- status = rsi_process_pkt(common);
- if (status) {
- rsi_dbg(ERR_ZONE,
- "%s: Failed to read pkt\n",
- __func__);
- mutex_unlock(&common->rx_lock);
- return;
- }
- break;
- default:
- rsi_sdio_ack_intr(common->priv, isr_status);
- dev->rx_info.total_sdio_unknown_intr++;
- isr_status = 0;
- rsi_dbg(ISR_ZONE,
- "Unknown Interrupt %x\n",
- isr_status);
- break;
+ if (status) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to read f/w reg\n",
+ __func__);
+ } else {
+ rsi_dbg(ERR_ZONE,
+ "%s: Firmware Status is 0x%x\n",
+ __func__, fw_status);
+ rsi_sdio_ack_intr(common->priv,
+ BIT(FW_ASSERT_IND));
}
- isr_status ^= BIT(isr_type - 1);
- } while (isr_status);
+
+ common->fsm_state = FSM_CARD_NOT_READY;
+
+ isr_status &= ~BIT(FW_ASSERT_IND);
+ }
+
+ if (isr_status & BIT(MSDU_PKT_PENDING)) {
+ rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n");
+ dev->rx_info.total_sdio_msdu_pending_intr++;
+
+ status = rsi_process_pkt(common);
+ if (status) {
+ rsi_dbg(ERR_ZONE, "%s: Failed to read pkt\n",
+ __func__);
+ mutex_unlock(&common->rx_lock);
+ return;
+ }
+
+ isr_status &= ~BIT(MSDU_PKT_PENDING);
+ }
+
+ if (isr_status) {
+ rsi_sdio_ack_intr(common->priv, isr_status);
+ dev->rx_info.total_sdio_unknown_intr++;
+ isr_status = 0;
+ rsi_dbg(ISR_ZONE, "Unknown Interrupt %x\n",
+ isr_status);
+ }
+
mutex_unlock(&common->rx_lock);
} while (1);
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index a62d41c0ccbc..a4a533c2a783 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2014 Redpine Signals Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -75,7 +75,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
* rsi_write_multiple() - This function writes multiple bytes of information
* to the USB card.
* @adapter: Pointer to the adapter structure.
- * @addr: Address of the register.
+ * @endpoint: Type of endpoint.
* @data: Pointer to the data that has to be written.
* @count: Number of multiple bytes to be written.
*
@@ -313,6 +313,8 @@ static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num)
/**
* rsi_rx_urb_submit() - This function submits the given URB to the USB stack.
* @adapter: Pointer to the adapter structure.
+ * @ep_num: Endpoint number.
+ * @mem_flags: The type of memory to allocate.
*
* Return: 0 on success, a negative error code on failure.
*/
@@ -741,24 +743,24 @@ static int rsi_reset_card(struct rsi_hw *adapter)
if (ret < 0)
goto fail;
} else {
- if ((rsi_usb_master_reg_write(adapter,
- NWP_WWD_INTERRUPT_TIMER,
- NWP_WWD_INT_TIMER_CLKS,
- RSI_9116_REG_SIZE)) < 0) {
+ ret = rsi_usb_master_reg_write(adapter,
+ NWP_WWD_INTERRUPT_TIMER,
+ NWP_WWD_INT_TIMER_CLKS,
+ RSI_9116_REG_SIZE);
+ if (ret < 0)
goto fail;
- }
- if ((rsi_usb_master_reg_write(adapter,
- NWP_WWD_SYSTEM_RESET_TIMER,
- NWP_WWD_SYS_RESET_TIMER_CLKS,
- RSI_9116_REG_SIZE)) < 0) {
+ ret = rsi_usb_master_reg_write(adapter,
+ NWP_WWD_SYSTEM_RESET_TIMER,
+ NWP_WWD_SYS_RESET_TIMER_CLKS,
+ RSI_9116_REG_SIZE);
+ if (ret < 0)
goto fail;
- }
- if ((rsi_usb_master_reg_write(adapter,
- NWP_WWD_MODE_AND_RSTART,
- NWP_WWD_TIMER_DISABLE,
- RSI_9116_REG_SIZE)) < 0) {
+ ret = rsi_usb_master_reg_write(adapter,
+ NWP_WWD_MODE_AND_RSTART,
+ NWP_WWD_TIMER_DISABLE,
+ RSI_9116_REG_SIZE);
+ if (ret < 0)
goto fail;
- }
}
rsi_dbg(INFO_ZONE, "Reset card done\n");
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
index b1687d22f73f..4ffcdde1acb1 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2014 Redpine Signals Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index 9afc1d0d2684..1c756263cf15 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -107,11 +107,6 @@ struct receive_info {
u32 buf_available_counter;
};
-struct rsi_sdio_rx_q {
- u8 num_rx_pkts;
- struct sk_buff_head head;
-};
-
struct rsi_91x_sdiodev {
struct sdio_func *pfunction;
struct task_struct *sdio_irq_task;
@@ -124,11 +119,10 @@ struct rsi_91x_sdiodev {
u16 tx_blk_size;
u8 write_fail;
bool buff_status_updated;
- struct rsi_sdio_rx_q rx_q;
struct rsi_thread rx_thread;
+ u8 pktbuffer[8192] __aligned(4);
};
-void rsi_interrupt_handler(struct rsi_hw *adapter);
int rsi_init_sdio_slave_regs(struct rsi_hw *adapter);
int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data);
int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length);