diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-03-25 03:53:42 -0300 |
commit | 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 (patch) | |
tree | fa581f6dc1c0596391690d1f67eceef3af8246dc /drivers/net/wireless/ath/wcn36xx | |
parent | d4e493caf788ef44982e131ff9c786546904d934 (diff) |
Linux-libre 4.5-gnu
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx')
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/dxe.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/hal.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/smd.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/smd.h | 9 |
4 files changed, 58 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index f8dfa05b2..8643801f3 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -474,36 +474,37 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, struct wcn36xx_dxe_desc *dxe = ctl->desc; dma_addr_t dma_addr; struct sk_buff *skb; + int ret = 0, int_mask; + u32 value; + + if (ch->ch_type == WCN36XX_DXE_CH_RX_L) { + value = WCN36XX_DXE_CTRL_RX_L; + int_mask = WCN36XX_DXE_INT_CH1_MASK; + } else { + value = WCN36XX_DXE_CTRL_RX_H; + int_mask = WCN36XX_DXE_INT_CH3_MASK; + } while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { skb = ctl->skb; dma_addr = dxe->dst_addr_l; - wcn36xx_dxe_fill_skb(wcn->dev, ctl); - - switch (ch->ch_type) { - case WCN36XX_DXE_CH_RX_L: - dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, - WCN36XX_DXE_INT_CH1_MASK); - break; - case WCN36XX_DXE_CH_RX_H: - dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, - WCN36XX_DXE_INT_CH3_MASK); - break; - default: - wcn36xx_warn("Unknown channel\n"); - } - - dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, - DMA_FROM_DEVICE); - wcn36xx_rx_skb(wcn, skb); + ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl); + if (0 == ret) { + /* new skb allocation ok. Use the new one and queue + * the old one to network system. + */ + dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, + DMA_FROM_DEVICE); + wcn36xx_rx_skb(wcn, skb); + } /* else keep old skb not submitted and use it for rx DMA */ + + dxe->ctrl = value; ctl = ctl->next; dxe = ctl->desc; } + wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, int_mask); ch->head_blk_ctl = ctl; - return 0; } diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index a1f1127d7..b947de0fb 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -345,6 +345,8 @@ enum wcn36xx_hal_host_msg_type { WCN36XX_HAL_DHCP_START_IND = 189, WCN36XX_HAL_DHCP_STOP_IND = 190, + WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233, + WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE }; diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 9a132d99a..936938c74 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -302,6 +302,22 @@ static int wcn36xx_smd_rsp_status_check(void *buf, size_t len) return 0; } +static int wcn36xx_smd_rsp_status_check_v2(struct wcn36xx *wcn, void *buf, + size_t len) +{ + struct wcn36xx_fw_msg_status_rsp_v2 *rsp; + + if (len < sizeof(struct wcn36xx_hal_msg_header) + sizeof(*rsp)) + return wcn36xx_smd_rsp_status_check(buf, len); + + rsp = buf + sizeof(struct wcn36xx_hal_msg_header); + + if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) + return rsp->status; + + return 0; +} + int wcn36xx_smd_load_nv(struct wcn36xx *wcn) { struct nv_data *nv_d; @@ -1582,7 +1598,8 @@ int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn, wcn36xx_err("Sending hal_remove_bsskey failed\n"); goto out; } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf, + wcn->hal_rsp_len); if (ret) { wcn36xx_err("hal_remove_bsskey response failed err=%d\n", ret); goto out; @@ -1951,7 +1968,8 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) wcn36xx_err("Sending hal_trigger_ba failed\n"); goto out; } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf, + wcn->hal_rsp_len); if (ret) { wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret); goto out; @@ -2128,6 +2146,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) complete(&wcn->hal_rsp_compl); break; + case WCN36XX_HAL_COEX_IND: + case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: case WCN36XX_HAL_OTA_TX_COMPL_IND: case WCN36XX_HAL_MISSED_BEACON_IND: case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: @@ -2174,6 +2194,9 @@ static void wcn36xx_ind_smd_work(struct work_struct *work) msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; switch (msg_header->msg_type) { + case WCN36XX_HAL_COEX_IND: + case WCN36XX_HAL_AVOID_FREQ_RANGE_IND: + break; case WCN36XX_HAL_OTA_TX_COMPL_IND: wcn36xx_smd_tx_compl_ind(wcn, hal_ind_msg->msg, diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 008d03423..8361f9e39 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -44,6 +44,15 @@ struct wcn36xx_fw_msg_status_rsp { u32 status; } __packed; +/* wcn3620 returns this for tigger_ba */ + +struct wcn36xx_fw_msg_status_rsp_v2 { + u8 bss_id[6]; + u32 status __packed; + u16 count_following_candidates __packed; + /* candidate list follows */ +}; + struct wcn36xx_hal_ind_msg { struct list_head list; u8 *msg; |