diff options
Diffstat (limited to 'drivers/staging/wilc1000/wilc_wlan.c')
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan.c | 291 |
1 files changed, 104 insertions, 187 deletions
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index d4ebbf67e50b..6787b6e9f124 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1,9 +1,21 @@ // SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries. + * All rights reserved. + */ + +#include <linux/if_ether.h> +#include <linux/ip.h> #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP; +static inline bool is_wilc1000(u32 id) +{ + return ((id & 0xfffff000) == 0x100000 ? true : false); +} + static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire) { mutex_lock(&wilc->hif_cs); @@ -20,42 +32,25 @@ static inline void release_bus(struct wilc *wilc, enum bus_release release) static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe) { - if (tqe == wilc->txq_head) { - wilc->txq_head = tqe->next; - if (wilc->txq_head) - wilc->txq_head->prev = NULL; - } else if (tqe == wilc->txq_tail) { - wilc->txq_tail = (tqe->prev); - if (wilc->txq_tail) - wilc->txq_tail->next = NULL; - } else { - tqe->prev->next = tqe->next; - tqe->next->prev = tqe->prev; - } + list_del(&tqe->list); wilc->txq_entries -= 1; } static struct txq_entry_t * wilc_wlan_txq_remove_from_head(struct net_device *dev) { - struct txq_entry_t *tqe; + struct txq_entry_t *tqe = NULL; unsigned long flags; - struct wilc_vif *vif; - struct wilc *wilc; - - vif = netdev_priv(dev); - wilc = vif->wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (wilc->txq_head) { - tqe = wilc->txq_head; - wilc->txq_head = tqe->next; - if (wilc->txq_head) - wilc->txq_head->prev = NULL; + if (!list_empty(&wilc->txq_head.list)) { + tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t, + list); + list_del(&tqe->list); wilc->txq_entries -= 1; - } else { - tqe = NULL; } spin_unlock_irqrestore(&wilc->txq_spinlock, flags); return tqe; @@ -65,25 +60,12 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, struct txq_entry_t *tqe) { unsigned long flags; - struct wilc_vif *vif; - struct wilc *wilc; - - vif = netdev_priv(dev); - wilc = vif->wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (!wilc->txq_head) { - tqe->next = NULL; - tqe->prev = NULL; - wilc->txq_head = tqe; - wilc->txq_tail = tqe; - } else { - tqe->next = NULL; - tqe->prev = wilc->txq_tail; - wilc->txq_tail->next = tqe; - wilc->txq_tail = tqe; - } + list_add_tail(&tqe->list, &wilc->txq_head.list); wilc->txq_entries += 1; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -101,17 +83,7 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif, spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (!wilc->txq_head) { - tqe->next = NULL; - tqe->prev = NULL; - wilc->txq_head = tqe; - wilc->txq_tail = tqe; - } else { - tqe->next = wilc->txq_head; - tqe->prev = NULL; - wilc->txq_head->prev = tqe; - wilc->txq_head = tqe; - } + list_add(&tqe->list, &wilc->txq_head.list); wilc->txq_entries += 1; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -184,50 +156,32 @@ static inline int add_tcp_pending_ack(u32 ack, u32 session_index, static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe) { - u8 *eth_hdr_ptr; - u8 *buffer = tqe->buffer; - unsigned short h_proto; + void *buffer = tqe->buffer; + const struct ethhdr *eth_hdr_ptr = buffer; int i; unsigned long flags; - struct wilc_vif *vif; - struct wilc *wilc; - - vif = netdev_priv(dev); - wilc = vif->wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; spin_lock_irqsave(&wilc->txq_spinlock, flags); - eth_hdr_ptr = &buffer[0]; - h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12])); - if (h_proto == ETH_P_IP) { - u8 *ip_hdr_ptr; - u8 protocol; + if (eth_hdr_ptr->h_proto == htons(ETH_P_IP)) { + const struct iphdr *ip_hdr_ptr = buffer + ETH_HLEN; - ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN]; - protocol = ip_hdr_ptr[9]; - - if (protocol == 0x06) { - u8 *tcp_hdr_ptr; + if (ip_hdr_ptr->protocol == IPPROTO_TCP) { + const struct tcphdr *tcp_hdr_ptr; u32 IHL, total_length, data_offset; - tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN]; - IHL = (ip_hdr_ptr[0] & 0xf) << 2; - total_length = ((u32)ip_hdr_ptr[2] << 8) + - (u32)ip_hdr_ptr[3]; - data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2; + IHL = ip_hdr_ptr->ihl << 2; + tcp_hdr_ptr = buffer + ETH_HLEN + IHL; + total_length = ntohs(ip_hdr_ptr->tot_len); + + data_offset = tcp_hdr_ptr->doff << 2; if (total_length == (IHL + data_offset)) { u32 seq_no, ack_no; - seq_no = ((u32)tcp_hdr_ptr[4] << 24) + - ((u32)tcp_hdr_ptr[5] << 16) + - ((u32)tcp_hdr_ptr[6] << 8) + - (u32)tcp_hdr_ptr[7]; - - ack_no = ((u32)tcp_hdr_ptr[8] << 24) + - ((u32)tcp_hdr_ptr[9] << 16) + - ((u32)tcp_hdr_ptr[10] << 8) + - (u32)tcp_hdr_ptr[11]; - + seq_no = ntohl(tcp_hdr_ptr->seq); + ack_no = ntohl(tcp_hdr_ptr->ack_seq); for (i = 0; i < tcp_session; i++) { u32 j = ack_session_info[i].seq_num; @@ -249,15 +203,13 @@ static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe) static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) { - struct wilc_vif *vif; - struct wilc *wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; u32 i = 0; u32 dropped = 0; + unsigned long flags; - vif = netdev_priv(dev); - wilc = vif->wilc; - - spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags); + spin_lock_irqsave(&wilc->txq_spinlock, flags); for (i = pending_base; i < (pending_base + pending_acks); i++) { u32 session_index; u32 bigger_ack_num; @@ -295,7 +247,7 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) else pending_base = 0; - spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags); + spin_unlock_irqrestore(&wilc->txq_spinlock, flags); while (dropped > 0) { wait_for_completion_timeout(&wilc->txq_event, @@ -402,12 +354,14 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc) { - struct txq_entry_t *tqe; + struct txq_entry_t *tqe = NULL; unsigned long flags; spin_lock_irqsave(&wilc->txq_spinlock, flags); - tqe = wilc->txq_head; + if (!list_empty(&wilc->txq_head.list)) + tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t, + list); spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -421,45 +375,37 @@ static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc, spin_lock_irqsave(&wilc->txq_spinlock, flags); - tqe = tqe->next; + if (!list_is_last(&tqe->list, &wilc->txq_head.list)) + tqe = list_next_entry(tqe, list); + else + tqe = NULL; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); return tqe; } -static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) +static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe) { if (wilc->quit) - return 0; + return; mutex_lock(&wilc->rxq_cs); - if (!wilc->rxq_head) { - rqe->next = NULL; - wilc->rxq_head = rqe; - wilc->rxq_tail = rqe; - } else { - wilc->rxq_tail->next = rqe; - rqe->next = NULL; - wilc->rxq_tail = rqe; - } - wilc->rxq_entries += 1; + list_add_tail(&rqe->list, &wilc->rxq_head.list); mutex_unlock(&wilc->rxq_cs); - return wilc->rxq_entries; } static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc) { - if (wilc->rxq_head) { - struct rxq_entry_t *rqe; - - mutex_lock(&wilc->rxq_cs); - rqe = wilc->rxq_head; - wilc->rxq_head = wilc->rxq_head->next; - wilc->rxq_entries -= 1; - mutex_unlock(&wilc->rxq_cs); - return rqe; + struct rxq_entry_t *rqe = NULL; + + mutex_lock(&wilc->rxq_cs); + if (!list_empty(&wilc->rxq_head.list)) { + rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t, + list); + list_del(&rqe->list); } - return NULL; + mutex_unlock(&wilc->rxq_cs); + return rqe; } void chip_allow_sleep(struct wilc *wilc) @@ -471,7 +417,6 @@ void chip_allow_sleep(struct wilc *wilc) wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0)); wilc->hif_func->hif_write_reg(wilc, 0xfa, 0); } -EXPORT_SYMBOL_GPL(chip_allow_sleep); void chip_wakeup(struct wilc *wilc) { @@ -488,7 +433,7 @@ void chip_wakeup(struct wilc *wilc) wilc_get_chipid(wilc, true); } while (wilc_get_chipid(wilc, true) == 0); } while (wilc_get_chipid(wilc, true) == 0); - } else if ((wilc->io_type & 0x1) == HIF_SDIO) { + } else if ((wilc->io_type & 0x1) == HIF_SDIO) { wilc->hif_func->hif_write_reg(wilc, 0xfa, 1); udelay(200); wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); @@ -526,7 +471,6 @@ void chip_wakeup(struct wilc *wilc) } chip_ps_state = CHIP_WAKEDUP; } -EXPORT_SYMBOL_GPL(chip_wakeup); void wilc_chip_sleep_manually(struct wilc *wilc) { @@ -540,7 +484,6 @@ void wilc_chip_sleep_manually(struct wilc *wilc) chip_ps_state = CHIP_SLEEPING_MANUAL; release_bus(wilc, RELEASE_ONLY); } -EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually); void host_wakeup_notify(struct wilc *wilc) { @@ -548,7 +491,6 @@ void host_wakeup_notify(struct wilc *wilc) wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1); release_bus(wilc, RELEASE_ONLY); } -EXPORT_SYMBOL_GPL(host_wakeup_notify); void host_sleep_notify(struct wilc *wilc) { @@ -556,14 +498,12 @@ void host_sleep_notify(struct wilc *wilc) wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1); release_bus(wilc, RELEASE_ONLY); } -EXPORT_SYMBOL_GPL(host_sleep_notify); int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) { int i, entries = 0; u32 sum; u32 reg; - u8 *txb; u32 offset = 0; int vmm_sz = 0; struct txq_entry_t *tqe; @@ -571,15 +511,10 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) int counter; int timeout; u32 vmm_table[WILC_VMM_TBL_SIZE]; - struct wilc_vif *vif; - struct wilc *wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; const struct wilc_hif_func *func; - - vif = netdev_priv(dev); - wilc = vif->wilc; - - txb = wilc->tx_buffer; - wilc->txq_exit = 0; + u8 *txb = wilc->tx_buffer; if (wilc->quit) goto out; @@ -611,7 +546,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) vmm_table[i] = vmm_sz / 4; if (tqe->type == WILC_CFG_PKT) vmm_table[i] |= BIT(10); - vmm_table[i] = cpu_to_le32(vmm_table[i]); + cpu_to_le32s(&vmm_table[i]); i++; sum += vmm_sz; @@ -714,7 +649,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) if (vmm_table[i] == 0) break; - vmm_table[i] = cpu_to_le32(vmm_table[i]); + le32_to_cpus(&vmm_table[i]); vmm_sz = (vmm_table[i] & 0x3ff); vmm_sz *= 4; header = (tqe->type << 31) | @@ -725,7 +660,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) else header &= ~BIT(30); - header = cpu_to_le32(header); + cpu_to_le32s(&header); memcpy(&txb[offset], &header, 4); if (tqe->type == WILC_CFG_PKT) { buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; @@ -765,7 +700,6 @@ out_release_bus: out: mutex_unlock(&wilc->txq_add_to_head_cs); - wilc->txq_exit = 1; *txq_count = wilc->txq_entries; return ret; } @@ -781,7 +715,7 @@ static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size) do { buff_ptr = buffer + offset; memcpy(&header, buff_ptr, 4); - header = cpu_to_le32(header); + le32_to_cpus(&header); is_cfg_packet = (header >> 31) & 0x1; pkt_offset = (header >> 22) & 0x1ff; @@ -832,8 +766,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) u8 *buffer; struct rxq_entry_t *rqe; - wilc->rxq_exit = 0; - do { if (wilc->quit) { complete(&wilc->cfg_event); @@ -849,8 +781,6 @@ static void wilc_wlan_handle_rxq(struct wilc *wilc) kfree(rqe); } while (1); - - wilc->rxq_exit = 1; } static void wilc_unknown_isr_ext(struct wilc *wilc) @@ -869,7 +799,7 @@ static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats) else mdelay(WILC_PLL_TO_SPI); - while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials)) + while (!(is_wilc1000(wilc_get_chipid(wilc, true)) && --trials)) mdelay(1); } @@ -895,31 +825,28 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) retries++; } - if (size > 0) { - if (LINUX_RX_SIZE - offset < size) - offset = 0; + if (size <= 0) + return; - if (wilc->rx_buffer) - buffer = &wilc->rx_buffer[offset]; - else - goto _end_; - - wilc->hif_func->hif_clear_int_ext(wilc, - DATA_INT_CLR | ENABLE_RX_VMM); - ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); - -_end_: - if (ret) { - offset += size; - wilc->rx_buffer_offset = offset; - rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); - if (rqe) { - rqe->buffer = buffer; - rqe->buffer_size = size; - wilc_wlan_rxq_add(wilc, rqe); - } - } - } + if (LINUX_RX_SIZE - offset < size) + offset = 0; + + buffer = &wilc->rx_buffer[offset]; + + wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM); + ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size); + if (!ret) + return; + + offset += size; + wilc->rx_buffer_offset = offset; + rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); + if (!rqe) + return; + + rqe->buffer = buffer; + rqe->buffer_size = size; + wilc_wlan_rxq_add(wilc, rqe); wilc_wlan_handle_rxq(wilc); } @@ -944,7 +871,6 @@ void wilc_handle_isr(struct wilc *wilc) release_bus(wilc, RELEASE_ALLOW_SLEEP); } -EXPORT_SYMBOL_GPL(wilc_handle_isr); int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size) @@ -964,8 +890,8 @@ int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, do { memcpy(&addr, &buffer[offset], 4); memcpy(&size, &buffer[offset + 4], 4); - addr = cpu_to_le32(addr); - size = cpu_to_le32(size); + le32_to_cpus(&addr); + le32_to_cpus(&size); acquire_bus(wilc, ACQUIRE_ONLY); offset += 8; while (((int)size) && (offset < buffer_size)) { @@ -1139,11 +1065,8 @@ void wilc_wlan_cleanup(struct net_device *dev) struct rxq_entry_t *rqe; u32 reg = 0; int ret; - struct wilc_vif *vif; - struct wilc *wilc; - - vif = netdev_priv(dev); - wilc = vif->wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; wilc->quit = 1; do { @@ -1232,10 +1155,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, if (!commit) return ret_size; - netdev_dbg(vif->ndev, - "[WILC]PACKET Commit with sequence number %d\n", - wilc->cfg_seq_no); - netdev_dbg(vif->ndev, "Processing cfg_set()\n"); + netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no); wilc->cfg_frame_in_use = 1; if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler)) @@ -1243,7 +1163,7 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, if (!wait_for_completion_timeout(&wilc->cfg_event, msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { - netdev_dbg(vif->ndev, "Set Timed Out\n"); + netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } @@ -1282,7 +1202,7 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, if (!wait_for_completion_timeout(&wilc->cfg_event, msecs_to_jiffies(CFG_PKTS_TIMEOUT))) { - netdev_dbg(vif->ndev, "Get Timed Out\n"); + netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__); ret_size = 0; } wilc->cfg_frame_in_use = 0; @@ -1339,11 +1259,8 @@ static u32 init_chip(struct net_device *dev) { u32 chipid; u32 reg, ret = 0; - struct wilc_vif *vif; - struct wilc *wilc; - - vif = netdev_priv(dev); - wilc = vif->wilc; + struct wilc_vif *vif = netdev_priv(dev); + struct wilc *wilc = vif->wilc; acquire_bus(wilc, ACQUIRE_ONLY); @@ -1382,7 +1299,7 @@ u32 wilc_get_chipid(struct wilc *wilc, bool update) if (chipid == 0 || update) { wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid); wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid); - if (!ISWILC1000(tempchipid)) { + if (!is_wilc1000(tempchipid)) { chipid = 0; return chipid; } |