diff options
Diffstat (limited to 'drivers/net/wireless/rsi')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_hal.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_sdio.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 173 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_usb.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_sdio.h | 8 |
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); |