12504ba9fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 260c140dfSLino Sanfilippo /* 360c140dfSLino Sanfilippo * Driver for Gigabit Ethernet adapters based on the Session Layer 460c140dfSLino Sanfilippo * Interface (SLIC) technology by Alacritech. The driver does not 560c140dfSLino Sanfilippo * support the hardware acceleration features provided by these cards. 660c140dfSLino Sanfilippo * 760c140dfSLino Sanfilippo * Copyright (C) 2016 Lino Sanfilippo <LinoSanfilippo@gmx.de> 860c140dfSLino Sanfilippo */ 960c140dfSLino Sanfilippo 1060c140dfSLino Sanfilippo #include <linux/kernel.h> 1160c140dfSLino Sanfilippo #include <linux/module.h> 1260c140dfSLino Sanfilippo #include <linux/pci.h> 1360c140dfSLino Sanfilippo #include <linux/netdevice.h> 1460c140dfSLino Sanfilippo #include <linux/etherdevice.h> 1560c140dfSLino Sanfilippo #include <linux/if_ether.h> 1660c140dfSLino Sanfilippo #include <linux/crc32.h> 1760c140dfSLino Sanfilippo #include <linux/dma-mapping.h> 1860c140dfSLino Sanfilippo #include <linux/ethtool.h> 1960c140dfSLino Sanfilippo #include <linux/mii.h> 2060c140dfSLino Sanfilippo #include <linux/interrupt.h> 2160c140dfSLino Sanfilippo #include <linux/delay.h> 2260c140dfSLino Sanfilippo #include <linux/firmware.h> 2360c140dfSLino Sanfilippo #include <linux/list.h> 2460c140dfSLino Sanfilippo #include <linux/u64_stats_sync.h> 2560c140dfSLino Sanfilippo 2660c140dfSLino Sanfilippo #include "slic.h" 2760c140dfSLino Sanfilippo 2860c140dfSLino Sanfilippo #define DRV_NAME "slicoss" 2960c140dfSLino Sanfilippo #define DRV_VERSION "1.0" 3060c140dfSLino Sanfilippo 3160c140dfSLino Sanfilippo static const struct pci_device_id slic_id_tbl[] = { 3260c140dfSLino Sanfilippo { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, 3360c140dfSLino Sanfilippo PCI_DEVICE_ID_ALACRITECH_MOJAVE) }, 3460c140dfSLino Sanfilippo { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, 3560c140dfSLino Sanfilippo PCI_DEVICE_ID_ALACRITECH_OASIS) }, 3660c140dfSLino Sanfilippo { 0 } 3760c140dfSLino Sanfilippo }; 3860c140dfSLino Sanfilippo 3960c140dfSLino Sanfilippo static const char slic_stats_strings[][ETH_GSTRING_LEN] = { 4060c140dfSLino Sanfilippo "rx_packets", 4160c140dfSLino Sanfilippo "rx_bytes", 4260c140dfSLino Sanfilippo "rx_multicasts", 4360c140dfSLino Sanfilippo "rx_errors", 4460c140dfSLino Sanfilippo "rx_buff_miss", 4560c140dfSLino Sanfilippo "rx_tp_csum", 4660c140dfSLino Sanfilippo "rx_tp_oflow", 4760c140dfSLino Sanfilippo "rx_tp_hlen", 4860c140dfSLino Sanfilippo "rx_ip_csum", 4960c140dfSLino Sanfilippo "rx_ip_len", 5060c140dfSLino Sanfilippo "rx_ip_hdr_len", 5160c140dfSLino Sanfilippo "rx_early", 5260c140dfSLino Sanfilippo "rx_buff_oflow", 5360c140dfSLino Sanfilippo "rx_lcode", 5460c140dfSLino Sanfilippo "rx_drbl", 5560c140dfSLino Sanfilippo "rx_crc", 5660c140dfSLino Sanfilippo "rx_oflow_802", 5760c140dfSLino Sanfilippo "rx_uflow_802", 5860c140dfSLino Sanfilippo "tx_packets", 5960c140dfSLino Sanfilippo "tx_bytes", 6060c140dfSLino Sanfilippo "tx_carrier", 6160c140dfSLino Sanfilippo "tx_dropped", 6260c140dfSLino Sanfilippo "irq_errs", 6360c140dfSLino Sanfilippo }; 6460c140dfSLino Sanfilippo 6560c140dfSLino Sanfilippo static inline int slic_next_queue_idx(unsigned int idx, unsigned int qlen) 6660c140dfSLino Sanfilippo { 6760c140dfSLino Sanfilippo return (idx + 1) & (qlen - 1); 6860c140dfSLino Sanfilippo } 6960c140dfSLino Sanfilippo 7060c140dfSLino Sanfilippo static inline int slic_get_free_queue_descs(unsigned int put_idx, 7160c140dfSLino Sanfilippo unsigned int done_idx, 7260c140dfSLino Sanfilippo unsigned int qlen) 7360c140dfSLino Sanfilippo { 7460c140dfSLino Sanfilippo if (put_idx >= done_idx) 7560c140dfSLino Sanfilippo return (qlen - (put_idx - done_idx) - 1); 7660c140dfSLino Sanfilippo return (done_idx - put_idx - 1); 7760c140dfSLino Sanfilippo } 7860c140dfSLino Sanfilippo 7960c140dfSLino Sanfilippo static unsigned int slic_next_compl_idx(struct slic_device *sdev) 8060c140dfSLino Sanfilippo { 8160c140dfSLino Sanfilippo struct slic_stat_queue *stq = &sdev->stq; 8260c140dfSLino Sanfilippo unsigned int active = stq->active_array; 8360c140dfSLino Sanfilippo struct slic_stat_desc *descs; 8460c140dfSLino Sanfilippo struct slic_stat_desc *stat; 8560c140dfSLino Sanfilippo unsigned int idx; 8660c140dfSLino Sanfilippo 8760c140dfSLino Sanfilippo descs = stq->descs[active]; 8860c140dfSLino Sanfilippo stat = &descs[stq->done_idx]; 8960c140dfSLino Sanfilippo 9060c140dfSLino Sanfilippo if (!stat->status) 9160c140dfSLino Sanfilippo return SLIC_INVALID_STAT_DESC_IDX; 9260c140dfSLino Sanfilippo 9360c140dfSLino Sanfilippo idx = (le32_to_cpu(stat->hnd) & 0xffff) - 1; 9460c140dfSLino Sanfilippo /* reset desc */ 9560c140dfSLino Sanfilippo stat->hnd = 0; 9660c140dfSLino Sanfilippo stat->status = 0; 9760c140dfSLino Sanfilippo 9860c140dfSLino Sanfilippo stq->done_idx = slic_next_queue_idx(stq->done_idx, stq->len); 9960c140dfSLino Sanfilippo /* check for wraparound */ 10060c140dfSLino Sanfilippo if (!stq->done_idx) { 10160c140dfSLino Sanfilippo dma_addr_t paddr = stq->paddr[active]; 10260c140dfSLino Sanfilippo 10360c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RBAR, lower_32_bits(paddr) | 10460c140dfSLino Sanfilippo stq->len); 10560c140dfSLino Sanfilippo /* make sure new status descriptors are immediately available */ 10660c140dfSLino Sanfilippo slic_flush_write(sdev); 10760c140dfSLino Sanfilippo active++; 10860c140dfSLino Sanfilippo active &= (SLIC_NUM_STAT_DESC_ARRAYS - 1); 10960c140dfSLino Sanfilippo stq->active_array = active; 11060c140dfSLino Sanfilippo } 11160c140dfSLino Sanfilippo return idx; 11260c140dfSLino Sanfilippo } 11360c140dfSLino Sanfilippo 11460c140dfSLino Sanfilippo static unsigned int slic_get_free_tx_descs(struct slic_tx_queue *txq) 11560c140dfSLino Sanfilippo { 11660c140dfSLino Sanfilippo /* ensure tail idx is updated */ 11760c140dfSLino Sanfilippo smp_mb(); 11860c140dfSLino Sanfilippo return slic_get_free_queue_descs(txq->put_idx, txq->done_idx, txq->len); 11960c140dfSLino Sanfilippo } 12060c140dfSLino Sanfilippo 12160c140dfSLino Sanfilippo static unsigned int slic_get_free_rx_descs(struct slic_rx_queue *rxq) 12260c140dfSLino Sanfilippo { 12360c140dfSLino Sanfilippo return slic_get_free_queue_descs(rxq->put_idx, rxq->done_idx, rxq->len); 12460c140dfSLino Sanfilippo } 12560c140dfSLino Sanfilippo 12660c140dfSLino Sanfilippo static void slic_clear_upr_list(struct slic_upr_list *upr_list) 12760c140dfSLino Sanfilippo { 12860c140dfSLino Sanfilippo struct slic_upr *upr; 12960c140dfSLino Sanfilippo struct slic_upr *tmp; 13060c140dfSLino Sanfilippo 13160c140dfSLino Sanfilippo spin_lock_bh(&upr_list->lock); 13260c140dfSLino Sanfilippo list_for_each_entry_safe(upr, tmp, &upr_list->list, list) { 13360c140dfSLino Sanfilippo list_del(&upr->list); 13460c140dfSLino Sanfilippo kfree(upr); 13560c140dfSLino Sanfilippo } 13660c140dfSLino Sanfilippo upr_list->pending = false; 13760c140dfSLino Sanfilippo spin_unlock_bh(&upr_list->lock); 13860c140dfSLino Sanfilippo } 13960c140dfSLino Sanfilippo 14060c140dfSLino Sanfilippo static void slic_start_upr(struct slic_device *sdev, struct slic_upr *upr) 14160c140dfSLino Sanfilippo { 14260c140dfSLino Sanfilippo u32 reg; 14360c140dfSLino Sanfilippo 14460c140dfSLino Sanfilippo reg = (upr->type == SLIC_UPR_CONFIG) ? SLIC_REG_RCONFIG : 14560c140dfSLino Sanfilippo SLIC_REG_LSTAT; 14660c140dfSLino Sanfilippo slic_write(sdev, reg, lower_32_bits(upr->paddr)); 14760c140dfSLino Sanfilippo slic_flush_write(sdev); 14860c140dfSLino Sanfilippo } 14960c140dfSLino Sanfilippo 15060c140dfSLino Sanfilippo static void slic_queue_upr(struct slic_device *sdev, struct slic_upr *upr) 15160c140dfSLino Sanfilippo { 15260c140dfSLino Sanfilippo struct slic_upr_list *upr_list = &sdev->upr_list; 15360c140dfSLino Sanfilippo bool pending; 15460c140dfSLino Sanfilippo 15560c140dfSLino Sanfilippo spin_lock_bh(&upr_list->lock); 15660c140dfSLino Sanfilippo pending = upr_list->pending; 15760c140dfSLino Sanfilippo INIT_LIST_HEAD(&upr->list); 15860c140dfSLino Sanfilippo list_add_tail(&upr->list, &upr_list->list); 15960c140dfSLino Sanfilippo upr_list->pending = true; 16060c140dfSLino Sanfilippo spin_unlock_bh(&upr_list->lock); 16160c140dfSLino Sanfilippo 16260c140dfSLino Sanfilippo if (!pending) 16360c140dfSLino Sanfilippo slic_start_upr(sdev, upr); 16460c140dfSLino Sanfilippo } 16560c140dfSLino Sanfilippo 16660c140dfSLino Sanfilippo static struct slic_upr *slic_dequeue_upr(struct slic_device *sdev) 16760c140dfSLino Sanfilippo { 16860c140dfSLino Sanfilippo struct slic_upr_list *upr_list = &sdev->upr_list; 16960c140dfSLino Sanfilippo struct slic_upr *next_upr = NULL; 17060c140dfSLino Sanfilippo struct slic_upr *upr = NULL; 17160c140dfSLino Sanfilippo 17260c140dfSLino Sanfilippo spin_lock_bh(&upr_list->lock); 17360c140dfSLino Sanfilippo if (!list_empty(&upr_list->list)) { 17460c140dfSLino Sanfilippo upr = list_first_entry(&upr_list->list, struct slic_upr, list); 17560c140dfSLino Sanfilippo list_del(&upr->list); 17660c140dfSLino Sanfilippo 17760c140dfSLino Sanfilippo if (list_empty(&upr_list->list)) 17860c140dfSLino Sanfilippo upr_list->pending = false; 17960c140dfSLino Sanfilippo else 18060c140dfSLino Sanfilippo next_upr = list_first_entry(&upr_list->list, 18160c140dfSLino Sanfilippo struct slic_upr, list); 18260c140dfSLino Sanfilippo } 18360c140dfSLino Sanfilippo spin_unlock_bh(&upr_list->lock); 18460c140dfSLino Sanfilippo /* trigger processing of the next upr in list */ 18560c140dfSLino Sanfilippo if (next_upr) 18660c140dfSLino Sanfilippo slic_start_upr(sdev, next_upr); 18760c140dfSLino Sanfilippo 18860c140dfSLino Sanfilippo return upr; 18960c140dfSLino Sanfilippo } 19060c140dfSLino Sanfilippo 19160c140dfSLino Sanfilippo static int slic_new_upr(struct slic_device *sdev, unsigned int type, 19260c140dfSLino Sanfilippo dma_addr_t paddr) 19360c140dfSLino Sanfilippo { 19460c140dfSLino Sanfilippo struct slic_upr *upr; 19560c140dfSLino Sanfilippo 19660c140dfSLino Sanfilippo upr = kmalloc(sizeof(*upr), GFP_ATOMIC); 19760c140dfSLino Sanfilippo if (!upr) 19860c140dfSLino Sanfilippo return -ENOMEM; 19960c140dfSLino Sanfilippo upr->type = type; 20060c140dfSLino Sanfilippo upr->paddr = paddr; 20160c140dfSLino Sanfilippo 20260c140dfSLino Sanfilippo slic_queue_upr(sdev, upr); 20360c140dfSLino Sanfilippo 20460c140dfSLino Sanfilippo return 0; 20560c140dfSLino Sanfilippo } 20660c140dfSLino Sanfilippo 20760c140dfSLino Sanfilippo static void slic_set_mcast_bit(u64 *mcmask, unsigned char const *addr) 20860c140dfSLino Sanfilippo { 20960c140dfSLino Sanfilippo u64 mask = *mcmask; 21060c140dfSLino Sanfilippo u8 crc; 21160c140dfSLino Sanfilippo /* Get the CRC polynomial for the mac address: we use bits 1-8 (lsb), 21260c140dfSLino Sanfilippo * bitwise reversed, msb (= lsb bit 0 before bitrev) is automatically 21360c140dfSLino Sanfilippo * discarded. 21460c140dfSLino Sanfilippo */ 21560c140dfSLino Sanfilippo crc = ether_crc(ETH_ALEN, addr) >> 23; 21660c140dfSLino Sanfilippo /* we only have space on the SLIC for 64 entries */ 21760c140dfSLino Sanfilippo crc &= 0x3F; 21860c140dfSLino Sanfilippo mask |= (u64)1 << crc; 21960c140dfSLino Sanfilippo *mcmask = mask; 22060c140dfSLino Sanfilippo } 22160c140dfSLino Sanfilippo 22260c140dfSLino Sanfilippo /* must be called with link_lock held */ 22360c140dfSLino Sanfilippo static void slic_configure_rcv(struct slic_device *sdev) 22460c140dfSLino Sanfilippo { 22560c140dfSLino Sanfilippo u32 val; 22660c140dfSLino Sanfilippo 22760c140dfSLino Sanfilippo val = SLIC_GRCR_RESET | SLIC_GRCR_ADDRAEN | SLIC_GRCR_RCVEN | 22860c140dfSLino Sanfilippo SLIC_GRCR_HASHSIZE << SLIC_GRCR_HASHSIZE_SHIFT | SLIC_GRCR_RCVBAD; 22960c140dfSLino Sanfilippo 23060c140dfSLino Sanfilippo if (sdev->duplex == DUPLEX_FULL) 23160c140dfSLino Sanfilippo val |= SLIC_GRCR_CTLEN; 23260c140dfSLino Sanfilippo 23360c140dfSLino Sanfilippo if (sdev->promisc) 23460c140dfSLino Sanfilippo val |= SLIC_GRCR_RCVALL; 23560c140dfSLino Sanfilippo 23660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRCFG, val); 23760c140dfSLino Sanfilippo } 23860c140dfSLino Sanfilippo 23960c140dfSLino Sanfilippo /* must be called with link_lock held */ 24060c140dfSLino Sanfilippo static void slic_configure_xmt(struct slic_device *sdev) 24160c140dfSLino Sanfilippo { 24260c140dfSLino Sanfilippo u32 val; 24360c140dfSLino Sanfilippo 24460c140dfSLino Sanfilippo val = SLIC_GXCR_RESET | SLIC_GXCR_XMTEN; 24560c140dfSLino Sanfilippo 24660c140dfSLino Sanfilippo if (sdev->duplex == DUPLEX_FULL) 24760c140dfSLino Sanfilippo val |= SLIC_GXCR_PAUSEEN; 24860c140dfSLino Sanfilippo 24960c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WXCFG, val); 25060c140dfSLino Sanfilippo } 25160c140dfSLino Sanfilippo 25260c140dfSLino Sanfilippo /* must be called with link_lock held */ 25360c140dfSLino Sanfilippo static void slic_configure_mac(struct slic_device *sdev) 25460c140dfSLino Sanfilippo { 25560c140dfSLino Sanfilippo u32 val; 25660c140dfSLino Sanfilippo 25760c140dfSLino Sanfilippo if (sdev->speed == SPEED_1000) { 25860c140dfSLino Sanfilippo val = SLIC_GMCR_GAPBB_1000 << SLIC_GMCR_GAPBB_SHIFT | 25960c140dfSLino Sanfilippo SLIC_GMCR_GAPR1_1000 << SLIC_GMCR_GAPR1_SHIFT | 26060c140dfSLino Sanfilippo SLIC_GMCR_GAPR2_1000 << SLIC_GMCR_GAPR2_SHIFT | 26160c140dfSLino Sanfilippo SLIC_GMCR_GBIT; /* enable GMII */ 26260c140dfSLino Sanfilippo } else { 26360c140dfSLino Sanfilippo val = SLIC_GMCR_GAPBB_100 << SLIC_GMCR_GAPBB_SHIFT | 26460c140dfSLino Sanfilippo SLIC_GMCR_GAPR1_100 << SLIC_GMCR_GAPR1_SHIFT | 26560c140dfSLino Sanfilippo SLIC_GMCR_GAPR2_100 << SLIC_GMCR_GAPR2_SHIFT; 26660c140dfSLino Sanfilippo } 26760c140dfSLino Sanfilippo 26860c140dfSLino Sanfilippo if (sdev->duplex == DUPLEX_FULL) 26960c140dfSLino Sanfilippo val |= SLIC_GMCR_FULLD; 27060c140dfSLino Sanfilippo 27160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WMCFG, val); 27260c140dfSLino Sanfilippo } 27360c140dfSLino Sanfilippo 27460c140dfSLino Sanfilippo static void slic_configure_link_locked(struct slic_device *sdev, int speed, 27560c140dfSLino Sanfilippo unsigned int duplex) 27660c140dfSLino Sanfilippo { 27760c140dfSLino Sanfilippo struct net_device *dev = sdev->netdev; 27860c140dfSLino Sanfilippo 27960c140dfSLino Sanfilippo if (sdev->speed == speed && sdev->duplex == duplex) 28060c140dfSLino Sanfilippo return; 28160c140dfSLino Sanfilippo 28260c140dfSLino Sanfilippo sdev->speed = speed; 28360c140dfSLino Sanfilippo sdev->duplex = duplex; 28460c140dfSLino Sanfilippo 28560c140dfSLino Sanfilippo if (sdev->speed == SPEED_UNKNOWN) { 28660c140dfSLino Sanfilippo if (netif_carrier_ok(dev)) 28760c140dfSLino Sanfilippo netif_carrier_off(dev); 28860c140dfSLino Sanfilippo } else { 28960c140dfSLino Sanfilippo /* (re)configure link settings */ 29060c140dfSLino Sanfilippo slic_configure_mac(sdev); 29160c140dfSLino Sanfilippo slic_configure_xmt(sdev); 29260c140dfSLino Sanfilippo slic_configure_rcv(sdev); 29360c140dfSLino Sanfilippo slic_flush_write(sdev); 29460c140dfSLino Sanfilippo 29560c140dfSLino Sanfilippo if (!netif_carrier_ok(dev)) 29660c140dfSLino Sanfilippo netif_carrier_on(dev); 29760c140dfSLino Sanfilippo } 29860c140dfSLino Sanfilippo } 29960c140dfSLino Sanfilippo 30060c140dfSLino Sanfilippo static void slic_configure_link(struct slic_device *sdev, int speed, 30160c140dfSLino Sanfilippo unsigned int duplex) 30260c140dfSLino Sanfilippo { 30360c140dfSLino Sanfilippo spin_lock_bh(&sdev->link_lock); 30460c140dfSLino Sanfilippo slic_configure_link_locked(sdev, speed, duplex); 30560c140dfSLino Sanfilippo spin_unlock_bh(&sdev->link_lock); 30660c140dfSLino Sanfilippo } 30760c140dfSLino Sanfilippo 30860c140dfSLino Sanfilippo static void slic_set_rx_mode(struct net_device *dev) 30960c140dfSLino Sanfilippo { 31060c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 31160c140dfSLino Sanfilippo struct netdev_hw_addr *hwaddr; 31260c140dfSLino Sanfilippo bool set_promisc; 31360c140dfSLino Sanfilippo u64 mcmask; 31460c140dfSLino Sanfilippo 31560c140dfSLino Sanfilippo if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) { 31660c140dfSLino Sanfilippo /* Turn on all multicast addresses. We have to do this for 31760c140dfSLino Sanfilippo * promiscuous mode as well as ALLMCAST mode (it saves the 31860c140dfSLino Sanfilippo * microcode from having to keep state about the MAC 31960c140dfSLino Sanfilippo * configuration). 32060c140dfSLino Sanfilippo */ 32160c140dfSLino Sanfilippo mcmask = ~(u64)0; 32260c140dfSLino Sanfilippo } else { 32360c140dfSLino Sanfilippo mcmask = 0; 32460c140dfSLino Sanfilippo 32560c140dfSLino Sanfilippo netdev_for_each_mc_addr(hwaddr, dev) { 32660c140dfSLino Sanfilippo slic_set_mcast_bit(&mcmask, hwaddr->addr); 32760c140dfSLino Sanfilippo } 32860c140dfSLino Sanfilippo } 32960c140dfSLino Sanfilippo 33060c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_MCASTLOW, lower_32_bits(mcmask)); 33160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_MCASTHIGH, upper_32_bits(mcmask)); 33260c140dfSLino Sanfilippo 33360c140dfSLino Sanfilippo set_promisc = !!(dev->flags & IFF_PROMISC); 33460c140dfSLino Sanfilippo 33560c140dfSLino Sanfilippo spin_lock_bh(&sdev->link_lock); 33660c140dfSLino Sanfilippo if (sdev->promisc != set_promisc) { 33760c140dfSLino Sanfilippo sdev->promisc = set_promisc; 33860c140dfSLino Sanfilippo slic_configure_rcv(sdev); 33960c140dfSLino Sanfilippo } 34060c140dfSLino Sanfilippo spin_unlock_bh(&sdev->link_lock); 34160c140dfSLino Sanfilippo } 34260c140dfSLino Sanfilippo 34360c140dfSLino Sanfilippo static void slic_xmit_complete(struct slic_device *sdev) 34460c140dfSLino Sanfilippo { 34560c140dfSLino Sanfilippo struct slic_tx_queue *txq = &sdev->txq; 34660c140dfSLino Sanfilippo struct net_device *dev = sdev->netdev; 34760c140dfSLino Sanfilippo struct slic_tx_buffer *buff; 34860c140dfSLino Sanfilippo unsigned int frames = 0; 34960c140dfSLino Sanfilippo unsigned int bytes = 0; 350687d4f2bSColin Ian King unsigned int idx; 35160c140dfSLino Sanfilippo 35260c140dfSLino Sanfilippo /* Limit processing to SLIC_MAX_TX_COMPLETIONS frames to avoid that new 35360c140dfSLino Sanfilippo * completions during processing keeps the loop running endlessly. 35460c140dfSLino Sanfilippo */ 35560c140dfSLino Sanfilippo do { 35660c140dfSLino Sanfilippo idx = slic_next_compl_idx(sdev); 35760c140dfSLino Sanfilippo if (idx == SLIC_INVALID_STAT_DESC_IDX) 35860c140dfSLino Sanfilippo break; 35960c140dfSLino Sanfilippo 36060c140dfSLino Sanfilippo txq->done_idx = idx; 36160c140dfSLino Sanfilippo buff = &txq->txbuffs[idx]; 36260c140dfSLino Sanfilippo 36360c140dfSLino Sanfilippo if (unlikely(!buff->skb)) { 36460c140dfSLino Sanfilippo netdev_warn(dev, 36560c140dfSLino Sanfilippo "no skb found for desc idx %i\n", idx); 36660c140dfSLino Sanfilippo continue; 36760c140dfSLino Sanfilippo } 36860c140dfSLino Sanfilippo dma_unmap_single(&sdev->pdev->dev, 36960c140dfSLino Sanfilippo dma_unmap_addr(buff, map_addr), 37060c140dfSLino Sanfilippo dma_unmap_len(buff, map_len), DMA_TO_DEVICE); 37160c140dfSLino Sanfilippo 37260c140dfSLino Sanfilippo bytes += buff->skb->len; 37360c140dfSLino Sanfilippo frames++; 37460c140dfSLino Sanfilippo 37560c140dfSLino Sanfilippo dev_kfree_skb_any(buff->skb); 37660c140dfSLino Sanfilippo buff->skb = NULL; 37760c140dfSLino Sanfilippo } while (frames < SLIC_MAX_TX_COMPLETIONS); 37860c140dfSLino Sanfilippo /* make sure xmit sees the new value for done_idx */ 37960c140dfSLino Sanfilippo smp_wmb(); 38060c140dfSLino Sanfilippo 38160c140dfSLino Sanfilippo u64_stats_update_begin(&sdev->stats.syncp); 38260c140dfSLino Sanfilippo sdev->stats.tx_bytes += bytes; 38360c140dfSLino Sanfilippo sdev->stats.tx_packets += frames; 38460c140dfSLino Sanfilippo u64_stats_update_end(&sdev->stats.syncp); 38560c140dfSLino Sanfilippo 38660c140dfSLino Sanfilippo netif_tx_lock(dev); 38760c140dfSLino Sanfilippo if (netif_queue_stopped(dev) && 38860c140dfSLino Sanfilippo (slic_get_free_tx_descs(txq) >= SLIC_MIN_TX_WAKEUP_DESCS)) 38960c140dfSLino Sanfilippo netif_wake_queue(dev); 39060c140dfSLino Sanfilippo netif_tx_unlock(dev); 39160c140dfSLino Sanfilippo } 39260c140dfSLino Sanfilippo 39360c140dfSLino Sanfilippo static void slic_refill_rx_queue(struct slic_device *sdev, gfp_t gfp) 39460c140dfSLino Sanfilippo { 39560c140dfSLino Sanfilippo const unsigned int ALIGN_MASK = SLIC_RX_BUFF_ALIGN - 1; 39660c140dfSLino Sanfilippo unsigned int maplen = SLIC_RX_BUFF_SIZE; 39760c140dfSLino Sanfilippo struct slic_rx_queue *rxq = &sdev->rxq; 39860c140dfSLino Sanfilippo struct net_device *dev = sdev->netdev; 39960c140dfSLino Sanfilippo struct slic_rx_buffer *buff; 40060c140dfSLino Sanfilippo struct slic_rx_desc *desc; 40160c140dfSLino Sanfilippo unsigned int misalign; 40260c140dfSLino Sanfilippo unsigned int offset; 40360c140dfSLino Sanfilippo struct sk_buff *skb; 40460c140dfSLino Sanfilippo dma_addr_t paddr; 40560c140dfSLino Sanfilippo 40660c140dfSLino Sanfilippo while (slic_get_free_rx_descs(rxq) > SLIC_MAX_REQ_RX_DESCS) { 40760c140dfSLino Sanfilippo skb = alloc_skb(maplen + ALIGN_MASK, gfp); 40860c140dfSLino Sanfilippo if (!skb) 40960c140dfSLino Sanfilippo break; 41060c140dfSLino Sanfilippo 41160c140dfSLino Sanfilippo paddr = dma_map_single(&sdev->pdev->dev, skb->data, maplen, 41260c140dfSLino Sanfilippo DMA_FROM_DEVICE); 41360c140dfSLino Sanfilippo if (dma_mapping_error(&sdev->pdev->dev, paddr)) { 41460c140dfSLino Sanfilippo netdev_err(dev, "mapping rx packet failed\n"); 41560c140dfSLino Sanfilippo /* drop skb */ 41660c140dfSLino Sanfilippo dev_kfree_skb_any(skb); 41760c140dfSLino Sanfilippo break; 41860c140dfSLino Sanfilippo } 41960c140dfSLino Sanfilippo /* ensure head buffer descriptors are 256 byte aligned */ 42060c140dfSLino Sanfilippo offset = 0; 42160c140dfSLino Sanfilippo misalign = paddr & ALIGN_MASK; 42260c140dfSLino Sanfilippo if (misalign) { 42360c140dfSLino Sanfilippo offset = SLIC_RX_BUFF_ALIGN - misalign; 42460c140dfSLino Sanfilippo skb_reserve(skb, offset); 42560c140dfSLino Sanfilippo } 42660c140dfSLino Sanfilippo /* the HW expects dma chunks for descriptor + frame data */ 42760c140dfSLino Sanfilippo desc = (struct slic_rx_desc *)skb->data; 42860c140dfSLino Sanfilippo /* temporarily sync descriptor for CPU to clear status */ 42960c140dfSLino Sanfilippo dma_sync_single_for_cpu(&sdev->pdev->dev, paddr, 43060c140dfSLino Sanfilippo offset + sizeof(*desc), 43160c140dfSLino Sanfilippo DMA_FROM_DEVICE); 43260c140dfSLino Sanfilippo desc->status = 0; 43360c140dfSLino Sanfilippo /* return it to HW again */ 43460c140dfSLino Sanfilippo dma_sync_single_for_device(&sdev->pdev->dev, paddr, 43560c140dfSLino Sanfilippo offset + sizeof(*desc), 43660c140dfSLino Sanfilippo DMA_FROM_DEVICE); 43760c140dfSLino Sanfilippo 43860c140dfSLino Sanfilippo buff = &rxq->rxbuffs[rxq->put_idx]; 43960c140dfSLino Sanfilippo buff->skb = skb; 44060c140dfSLino Sanfilippo dma_unmap_addr_set(buff, map_addr, paddr); 44160c140dfSLino Sanfilippo dma_unmap_len_set(buff, map_len, maplen); 44260c140dfSLino Sanfilippo buff->addr_offset = offset; 44360c140dfSLino Sanfilippo /* complete write to descriptor before it is handed to HW */ 44460c140dfSLino Sanfilippo wmb(); 44560c140dfSLino Sanfilippo /* head buffer descriptors are placed immediately before skb */ 44660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_HBAR, lower_32_bits(paddr) + offset); 44760c140dfSLino Sanfilippo rxq->put_idx = slic_next_queue_idx(rxq->put_idx, rxq->len); 44860c140dfSLino Sanfilippo } 44960c140dfSLino Sanfilippo } 45060c140dfSLino Sanfilippo 45160c140dfSLino Sanfilippo static void slic_handle_frame_error(struct slic_device *sdev, 45260c140dfSLino Sanfilippo struct sk_buff *skb) 45360c140dfSLino Sanfilippo { 45460c140dfSLino Sanfilippo struct slic_stats *stats = &sdev->stats; 45560c140dfSLino Sanfilippo 45660c140dfSLino Sanfilippo if (sdev->model == SLIC_MODEL_OASIS) { 45760c140dfSLino Sanfilippo struct slic_rx_info_oasis *info; 45860c140dfSLino Sanfilippo u32 status_b; 45960c140dfSLino Sanfilippo u32 status; 46060c140dfSLino Sanfilippo 46160c140dfSLino Sanfilippo info = (struct slic_rx_info_oasis *)skb->data; 46260c140dfSLino Sanfilippo status = le32_to_cpu(info->frame_status); 46360c140dfSLino Sanfilippo status_b = le32_to_cpu(info->frame_status_b); 46460c140dfSLino Sanfilippo /* transport layer */ 46560c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_TPCSUM) 46660c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tpcsum); 46760c140dfSLino Sanfilippo if (status & SLIC_VRHSTAT_TPOFLO) 46860c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tpoflow); 46960c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_TPHLEN) 47060c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tphlen); 47160c140dfSLino Sanfilippo /* ip layer */ 47260c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_IPCSUM) 47360c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_ipcsum); 47460c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_IPLERR) 47560c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_iplen); 47660c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_IPHERR) 47760c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_iphlen); 47860c140dfSLino Sanfilippo /* link layer */ 47960c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_RCVE) 48060c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_early); 48160c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_BUFF) 48260c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_buffoflow); 48360c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_CODE) 48460c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_lcode); 48560c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_DRBL) 48660c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_drbl); 48760c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_CRC) 48860c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_crc); 48960c140dfSLino Sanfilippo if (status & SLIC_VRHSTAT_802OE) 49060c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_oflow802); 49160c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_802UE) 49260c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_uflow802); 49360c140dfSLino Sanfilippo if (status_b & SLIC_VRHSTATB_CARRE) 49460c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, tx_carrier); 49560c140dfSLino Sanfilippo } else { /* mojave */ 49660c140dfSLino Sanfilippo struct slic_rx_info_mojave *info; 49760c140dfSLino Sanfilippo u32 status; 49860c140dfSLino Sanfilippo 49960c140dfSLino Sanfilippo info = (struct slic_rx_info_mojave *)skb->data; 50060c140dfSLino Sanfilippo status = le32_to_cpu(info->frame_status); 50160c140dfSLino Sanfilippo /* transport layer */ 50260c140dfSLino Sanfilippo if (status & SLIC_VGBSTAT_XPERR) { 50360c140dfSLino Sanfilippo u32 xerr = status >> SLIC_VGBSTAT_XERRSHFT; 50460c140dfSLino Sanfilippo 50560c140dfSLino Sanfilippo if (xerr == SLIC_VGBSTAT_XCSERR) 50660c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tpcsum); 50760c140dfSLino Sanfilippo if (xerr == SLIC_VGBSTAT_XUFLOW) 50860c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tpoflow); 50960c140dfSLino Sanfilippo if (xerr == SLIC_VGBSTAT_XHLEN) 51060c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_tphlen); 51160c140dfSLino Sanfilippo } 51260c140dfSLino Sanfilippo /* ip layer */ 51360c140dfSLino Sanfilippo if (status & SLIC_VGBSTAT_NETERR) { 51460c140dfSLino Sanfilippo u32 nerr = status >> SLIC_VGBSTAT_NERRSHFT & 51560c140dfSLino Sanfilippo SLIC_VGBSTAT_NERRMSK; 51660c140dfSLino Sanfilippo 51760c140dfSLino Sanfilippo if (nerr == SLIC_VGBSTAT_NCSERR) 51860c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_ipcsum); 51960c140dfSLino Sanfilippo if (nerr == SLIC_VGBSTAT_NUFLOW) 52060c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_iplen); 52160c140dfSLino Sanfilippo if (nerr == SLIC_VGBSTAT_NHLEN) 52260c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_iphlen); 52360c140dfSLino Sanfilippo } 52460c140dfSLino Sanfilippo /* link layer */ 52560c140dfSLino Sanfilippo if (status & SLIC_VGBSTAT_LNKERR) { 52660c140dfSLino Sanfilippo u32 lerr = status & SLIC_VGBSTAT_LERRMSK; 52760c140dfSLino Sanfilippo 52860c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LDEARLY) 52960c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_early); 53060c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LBOFLO) 53160c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_buffoflow); 53260c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LCODERR) 53360c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_lcode); 53460c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LDBLNBL) 53560c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_drbl); 53660c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LCRCERR) 53760c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_crc); 53860c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LOFLO) 53960c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_oflow802); 54060c140dfSLino Sanfilippo if (lerr == SLIC_VGBSTAT_LUFLO) 54160c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_uflow802); 54260c140dfSLino Sanfilippo } 54360c140dfSLino Sanfilippo } 54460c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_errors); 54560c140dfSLino Sanfilippo } 54660c140dfSLino Sanfilippo 54760c140dfSLino Sanfilippo static void slic_handle_receive(struct slic_device *sdev, unsigned int todo, 54860c140dfSLino Sanfilippo unsigned int *done) 54960c140dfSLino Sanfilippo { 55060c140dfSLino Sanfilippo struct slic_rx_queue *rxq = &sdev->rxq; 55160c140dfSLino Sanfilippo struct net_device *dev = sdev->netdev; 55260c140dfSLino Sanfilippo struct slic_rx_buffer *buff; 55360c140dfSLino Sanfilippo struct slic_rx_desc *desc; 55460c140dfSLino Sanfilippo unsigned int frames = 0; 55560c140dfSLino Sanfilippo unsigned int bytes = 0; 55660c140dfSLino Sanfilippo struct sk_buff *skb; 55760c140dfSLino Sanfilippo u32 status; 55860c140dfSLino Sanfilippo u32 len; 55960c140dfSLino Sanfilippo 56060c140dfSLino Sanfilippo while (todo && (rxq->done_idx != rxq->put_idx)) { 56160c140dfSLino Sanfilippo buff = &rxq->rxbuffs[rxq->done_idx]; 56260c140dfSLino Sanfilippo 56360c140dfSLino Sanfilippo skb = buff->skb; 56460c140dfSLino Sanfilippo if (!skb) 56560c140dfSLino Sanfilippo break; 56660c140dfSLino Sanfilippo 56760c140dfSLino Sanfilippo desc = (struct slic_rx_desc *)skb->data; 56860c140dfSLino Sanfilippo 56960c140dfSLino Sanfilippo dma_sync_single_for_cpu(&sdev->pdev->dev, 57060c140dfSLino Sanfilippo dma_unmap_addr(buff, map_addr), 57160c140dfSLino Sanfilippo buff->addr_offset + sizeof(*desc), 57260c140dfSLino Sanfilippo DMA_FROM_DEVICE); 57360c140dfSLino Sanfilippo 57460c140dfSLino Sanfilippo status = le32_to_cpu(desc->status); 57560c140dfSLino Sanfilippo if (!(status & SLIC_IRHDDR_SVALID)) { 57660c140dfSLino Sanfilippo dma_sync_single_for_device(&sdev->pdev->dev, 57760c140dfSLino Sanfilippo dma_unmap_addr(buff, 57860c140dfSLino Sanfilippo map_addr), 57960c140dfSLino Sanfilippo buff->addr_offset + 58060c140dfSLino Sanfilippo sizeof(*desc), 58160c140dfSLino Sanfilippo DMA_FROM_DEVICE); 58260c140dfSLino Sanfilippo break; 58360c140dfSLino Sanfilippo } 58460c140dfSLino Sanfilippo 58560c140dfSLino Sanfilippo buff->skb = NULL; 58660c140dfSLino Sanfilippo 58760c140dfSLino Sanfilippo dma_unmap_single(&sdev->pdev->dev, 58860c140dfSLino Sanfilippo dma_unmap_addr(buff, map_addr), 58960c140dfSLino Sanfilippo dma_unmap_len(buff, map_len), 59060c140dfSLino Sanfilippo DMA_FROM_DEVICE); 59160c140dfSLino Sanfilippo 59260c140dfSLino Sanfilippo /* skip rx descriptor that is placed before the frame data */ 59360c140dfSLino Sanfilippo skb_reserve(skb, SLIC_RX_BUFF_HDR_SIZE); 59460c140dfSLino Sanfilippo 59560c140dfSLino Sanfilippo if (unlikely(status & SLIC_IRHDDR_ERR)) { 59660c140dfSLino Sanfilippo slic_handle_frame_error(sdev, skb); 59760c140dfSLino Sanfilippo dev_kfree_skb_any(skb); 59860c140dfSLino Sanfilippo } else { 59960c140dfSLino Sanfilippo struct ethhdr *eh = (struct ethhdr *)skb->data; 60060c140dfSLino Sanfilippo 60160c140dfSLino Sanfilippo if (is_multicast_ether_addr(eh->h_dest)) 60260c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(&sdev->stats, rx_mcasts); 60360c140dfSLino Sanfilippo 60460c140dfSLino Sanfilippo len = le32_to_cpu(desc->length) & SLIC_IRHDDR_FLEN_MSK; 60560c140dfSLino Sanfilippo skb_put(skb, len); 60660c140dfSLino Sanfilippo skb->protocol = eth_type_trans(skb, dev); 60760c140dfSLino Sanfilippo skb->ip_summed = CHECKSUM_UNNECESSARY; 60860c140dfSLino Sanfilippo 60960c140dfSLino Sanfilippo napi_gro_receive(&sdev->napi, skb); 61060c140dfSLino Sanfilippo 61160c140dfSLino Sanfilippo bytes += len; 61260c140dfSLino Sanfilippo frames++; 61360c140dfSLino Sanfilippo } 61460c140dfSLino Sanfilippo rxq->done_idx = slic_next_queue_idx(rxq->done_idx, rxq->len); 61560c140dfSLino Sanfilippo todo--; 61660c140dfSLino Sanfilippo } 61760c140dfSLino Sanfilippo 61860c140dfSLino Sanfilippo u64_stats_update_begin(&sdev->stats.syncp); 61960c140dfSLino Sanfilippo sdev->stats.rx_bytes += bytes; 62060c140dfSLino Sanfilippo sdev->stats.rx_packets += frames; 62160c140dfSLino Sanfilippo u64_stats_update_end(&sdev->stats.syncp); 62260c140dfSLino Sanfilippo 62360c140dfSLino Sanfilippo slic_refill_rx_queue(sdev, GFP_ATOMIC); 62460c140dfSLino Sanfilippo } 62560c140dfSLino Sanfilippo 62660c140dfSLino Sanfilippo static void slic_handle_link_irq(struct slic_device *sdev) 62760c140dfSLino Sanfilippo { 62860c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 62960c140dfSLino Sanfilippo struct slic_shmem_data *sm_data = sm->shmem_data; 63060c140dfSLino Sanfilippo unsigned int duplex; 63160c140dfSLino Sanfilippo int speed; 63260c140dfSLino Sanfilippo u32 link; 63360c140dfSLino Sanfilippo 63460c140dfSLino Sanfilippo link = le32_to_cpu(sm_data->link); 63560c140dfSLino Sanfilippo 63660c140dfSLino Sanfilippo if (link & SLIC_GIG_LINKUP) { 63760c140dfSLino Sanfilippo if (link & SLIC_GIG_SPEED_1000) 63860c140dfSLino Sanfilippo speed = SPEED_1000; 63960c140dfSLino Sanfilippo else if (link & SLIC_GIG_SPEED_100) 64060c140dfSLino Sanfilippo speed = SPEED_100; 64160c140dfSLino Sanfilippo else 64260c140dfSLino Sanfilippo speed = SPEED_10; 64360c140dfSLino Sanfilippo 64460c140dfSLino Sanfilippo duplex = (link & SLIC_GIG_FULLDUPLEX) ? DUPLEX_FULL : 64560c140dfSLino Sanfilippo DUPLEX_HALF; 64660c140dfSLino Sanfilippo } else { 64760c140dfSLino Sanfilippo duplex = DUPLEX_UNKNOWN; 64860c140dfSLino Sanfilippo speed = SPEED_UNKNOWN; 64960c140dfSLino Sanfilippo } 65060c140dfSLino Sanfilippo slic_configure_link(sdev, speed, duplex); 65160c140dfSLino Sanfilippo } 65260c140dfSLino Sanfilippo 65360c140dfSLino Sanfilippo static void slic_handle_upr_irq(struct slic_device *sdev, u32 irqs) 65460c140dfSLino Sanfilippo { 65560c140dfSLino Sanfilippo struct slic_upr *upr; 65660c140dfSLino Sanfilippo 65760c140dfSLino Sanfilippo /* remove upr that caused this irq (always the first entry in list) */ 65860c140dfSLino Sanfilippo upr = slic_dequeue_upr(sdev); 65960c140dfSLino Sanfilippo if (!upr) { 66060c140dfSLino Sanfilippo netdev_warn(sdev->netdev, "no upr found on list\n"); 66160c140dfSLino Sanfilippo return; 66260c140dfSLino Sanfilippo } 66360c140dfSLino Sanfilippo 66460c140dfSLino Sanfilippo if (upr->type == SLIC_UPR_LSTAT) { 66560c140dfSLino Sanfilippo if (unlikely(irqs & SLIC_ISR_UPCERR_MASK)) { 66660c140dfSLino Sanfilippo /* try again */ 66760c140dfSLino Sanfilippo slic_queue_upr(sdev, upr); 66860c140dfSLino Sanfilippo return; 66960c140dfSLino Sanfilippo } 67060c140dfSLino Sanfilippo slic_handle_link_irq(sdev); 67160c140dfSLino Sanfilippo } 67260c140dfSLino Sanfilippo kfree(upr); 67360c140dfSLino Sanfilippo } 67460c140dfSLino Sanfilippo 67560c140dfSLino Sanfilippo static int slic_handle_link_change(struct slic_device *sdev) 67660c140dfSLino Sanfilippo { 67760c140dfSLino Sanfilippo return slic_new_upr(sdev, SLIC_UPR_LSTAT, sdev->shmem.link_paddr); 67860c140dfSLino Sanfilippo } 67960c140dfSLino Sanfilippo 68060c140dfSLino Sanfilippo static void slic_handle_err_irq(struct slic_device *sdev, u32 isr) 68160c140dfSLino Sanfilippo { 68260c140dfSLino Sanfilippo struct slic_stats *stats = &sdev->stats; 68360c140dfSLino Sanfilippo 68460c140dfSLino Sanfilippo if (isr & SLIC_ISR_RMISS) 68560c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, rx_buff_miss); 68660c140dfSLino Sanfilippo if (isr & SLIC_ISR_XDROP) 68760c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, tx_dropped); 68860c140dfSLino Sanfilippo if (!(isr & (SLIC_ISR_RMISS | SLIC_ISR_XDROP))) 68960c140dfSLino Sanfilippo SLIC_INC_STATS_COUNTER(stats, irq_errs); 69060c140dfSLino Sanfilippo } 69160c140dfSLino Sanfilippo 69260c140dfSLino Sanfilippo static void slic_handle_irq(struct slic_device *sdev, u32 isr, 69360c140dfSLino Sanfilippo unsigned int todo, unsigned int *done) 69460c140dfSLino Sanfilippo { 69560c140dfSLino Sanfilippo if (isr & SLIC_ISR_ERR) 69660c140dfSLino Sanfilippo slic_handle_err_irq(sdev, isr); 69760c140dfSLino Sanfilippo 69860c140dfSLino Sanfilippo if (isr & SLIC_ISR_LEVENT) 69960c140dfSLino Sanfilippo slic_handle_link_change(sdev); 70060c140dfSLino Sanfilippo 70160c140dfSLino Sanfilippo if (isr & SLIC_ISR_UPC_MASK) 70260c140dfSLino Sanfilippo slic_handle_upr_irq(sdev, isr); 70360c140dfSLino Sanfilippo 70460c140dfSLino Sanfilippo if (isr & SLIC_ISR_RCV) 70560c140dfSLino Sanfilippo slic_handle_receive(sdev, todo, done); 70660c140dfSLino Sanfilippo 70760c140dfSLino Sanfilippo if (isr & SLIC_ISR_CMD) 70860c140dfSLino Sanfilippo slic_xmit_complete(sdev); 70960c140dfSLino Sanfilippo } 71060c140dfSLino Sanfilippo 71160c140dfSLino Sanfilippo static int slic_poll(struct napi_struct *napi, int todo) 71260c140dfSLino Sanfilippo { 71360c140dfSLino Sanfilippo struct slic_device *sdev = container_of(napi, struct slic_device, napi); 71460c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 71560c140dfSLino Sanfilippo struct slic_shmem_data *sm_data = sm->shmem_data; 71660c140dfSLino Sanfilippo u32 isr = le32_to_cpu(sm_data->isr); 71760c140dfSLino Sanfilippo int done = 0; 71860c140dfSLino Sanfilippo 71960c140dfSLino Sanfilippo slic_handle_irq(sdev, isr, todo, &done); 72060c140dfSLino Sanfilippo 72160c140dfSLino Sanfilippo if (done < todo) { 72260c140dfSLino Sanfilippo napi_complete_done(napi, done); 72360c140dfSLino Sanfilippo /* reenable irqs */ 72460c140dfSLino Sanfilippo sm_data->isr = 0; 72560c140dfSLino Sanfilippo /* make sure sm_data->isr is cleard before irqs are reenabled */ 72660c140dfSLino Sanfilippo wmb(); 72760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISR, 0); 72860c140dfSLino Sanfilippo slic_flush_write(sdev); 72960c140dfSLino Sanfilippo } 73060c140dfSLino Sanfilippo 73160c140dfSLino Sanfilippo return done; 73260c140dfSLino Sanfilippo } 73360c140dfSLino Sanfilippo 73460c140dfSLino Sanfilippo static irqreturn_t slic_irq(int irq, void *dev_id) 73560c140dfSLino Sanfilippo { 73660c140dfSLino Sanfilippo struct slic_device *sdev = dev_id; 73760c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 73860c140dfSLino Sanfilippo struct slic_shmem_data *sm_data = sm->shmem_data; 73960c140dfSLino Sanfilippo 74060c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ICR, SLIC_ICR_INT_MASK); 74160c140dfSLino Sanfilippo slic_flush_write(sdev); 74260c140dfSLino Sanfilippo /* make sure sm_data->isr is read after ICR_INT_MASK is set */ 74360c140dfSLino Sanfilippo wmb(); 74460c140dfSLino Sanfilippo 74560c140dfSLino Sanfilippo if (!sm_data->isr) { 74660c140dfSLino Sanfilippo dma_rmb(); 74760c140dfSLino Sanfilippo /* spurious interrupt */ 74860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISR, 0); 74960c140dfSLino Sanfilippo slic_flush_write(sdev); 75060c140dfSLino Sanfilippo return IRQ_NONE; 75160c140dfSLino Sanfilippo } 75260c140dfSLino Sanfilippo 75360c140dfSLino Sanfilippo napi_schedule_irqoff(&sdev->napi); 75460c140dfSLino Sanfilippo 75560c140dfSLino Sanfilippo return IRQ_HANDLED; 75660c140dfSLino Sanfilippo } 75760c140dfSLino Sanfilippo 75860c140dfSLino Sanfilippo static void slic_card_reset(struct slic_device *sdev) 75960c140dfSLino Sanfilippo { 76060c140dfSLino Sanfilippo u16 cmd; 76160c140dfSLino Sanfilippo 76260c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RESET, SLIC_RESET_MAGIC); 76360c140dfSLino Sanfilippo /* flush write by means of config space */ 76460c140dfSLino Sanfilippo pci_read_config_word(sdev->pdev, PCI_COMMAND, &cmd); 76560c140dfSLino Sanfilippo mdelay(1); 76660c140dfSLino Sanfilippo } 76760c140dfSLino Sanfilippo 76860c140dfSLino Sanfilippo static int slic_init_stat_queue(struct slic_device *sdev) 76960c140dfSLino Sanfilippo { 77060c140dfSLino Sanfilippo const unsigned int DESC_ALIGN_MASK = SLIC_STATS_DESC_ALIGN - 1; 77160c140dfSLino Sanfilippo struct slic_stat_queue *stq = &sdev->stq; 77260c140dfSLino Sanfilippo struct slic_stat_desc *descs; 77360c140dfSLino Sanfilippo unsigned int misalign; 77460c140dfSLino Sanfilippo unsigned int offset; 77560c140dfSLino Sanfilippo dma_addr_t paddr; 77660c140dfSLino Sanfilippo size_t size; 77760c140dfSLino Sanfilippo int err; 77860c140dfSLino Sanfilippo int i; 77960c140dfSLino Sanfilippo 78060c140dfSLino Sanfilippo stq->len = SLIC_NUM_STAT_DESCS; 78160c140dfSLino Sanfilippo stq->active_array = 0; 78260c140dfSLino Sanfilippo stq->done_idx = 0; 78360c140dfSLino Sanfilippo 78460c140dfSLino Sanfilippo size = stq->len * sizeof(*descs) + DESC_ALIGN_MASK; 78560c140dfSLino Sanfilippo 78660c140dfSLino Sanfilippo for (i = 0; i < SLIC_NUM_STAT_DESC_ARRAYS; i++) { 787750afb08SLuis Chamberlain descs = dma_alloc_coherent(&sdev->pdev->dev, size, &paddr, 78860c140dfSLino Sanfilippo GFP_KERNEL); 78960c140dfSLino Sanfilippo if (!descs) { 79060c140dfSLino Sanfilippo netdev_err(sdev->netdev, 79160c140dfSLino Sanfilippo "failed to allocate status descriptors\n"); 79260c140dfSLino Sanfilippo err = -ENOMEM; 79360c140dfSLino Sanfilippo goto free_descs; 79460c140dfSLino Sanfilippo } 79560c140dfSLino Sanfilippo /* ensure correct alignment */ 79660c140dfSLino Sanfilippo offset = 0; 79760c140dfSLino Sanfilippo misalign = paddr & DESC_ALIGN_MASK; 79860c140dfSLino Sanfilippo if (misalign) { 79960c140dfSLino Sanfilippo offset = SLIC_STATS_DESC_ALIGN - misalign; 80060c140dfSLino Sanfilippo descs += offset; 80160c140dfSLino Sanfilippo paddr += offset; 80260c140dfSLino Sanfilippo } 80360c140dfSLino Sanfilippo 80460c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RBAR, lower_32_bits(paddr) | 80560c140dfSLino Sanfilippo stq->len); 80660c140dfSLino Sanfilippo stq->descs[i] = descs; 80760c140dfSLino Sanfilippo stq->paddr[i] = paddr; 80860c140dfSLino Sanfilippo stq->addr_offset[i] = offset; 80960c140dfSLino Sanfilippo } 81060c140dfSLino Sanfilippo 81160c140dfSLino Sanfilippo stq->mem_size = size; 81260c140dfSLino Sanfilippo 81360c140dfSLino Sanfilippo return 0; 81460c140dfSLino Sanfilippo 81560c140dfSLino Sanfilippo free_descs: 81660c140dfSLino Sanfilippo while (i--) { 81760c140dfSLino Sanfilippo dma_free_coherent(&sdev->pdev->dev, stq->mem_size, 81860c140dfSLino Sanfilippo stq->descs[i] - stq->addr_offset[i], 81960c140dfSLino Sanfilippo stq->paddr[i] - stq->addr_offset[i]); 82060c140dfSLino Sanfilippo } 82160c140dfSLino Sanfilippo 82260c140dfSLino Sanfilippo return err; 82360c140dfSLino Sanfilippo } 82460c140dfSLino Sanfilippo 82560c140dfSLino Sanfilippo static void slic_free_stat_queue(struct slic_device *sdev) 82660c140dfSLino Sanfilippo { 82760c140dfSLino Sanfilippo struct slic_stat_queue *stq = &sdev->stq; 82860c140dfSLino Sanfilippo int i; 82960c140dfSLino Sanfilippo 83060c140dfSLino Sanfilippo for (i = 0; i < SLIC_NUM_STAT_DESC_ARRAYS; i++) { 83160c140dfSLino Sanfilippo dma_free_coherent(&sdev->pdev->dev, stq->mem_size, 83260c140dfSLino Sanfilippo stq->descs[i] - stq->addr_offset[i], 83360c140dfSLino Sanfilippo stq->paddr[i] - stq->addr_offset[i]); 83460c140dfSLino Sanfilippo } 83560c140dfSLino Sanfilippo } 83660c140dfSLino Sanfilippo 83760c140dfSLino Sanfilippo static int slic_init_tx_queue(struct slic_device *sdev) 83860c140dfSLino Sanfilippo { 83960c140dfSLino Sanfilippo struct slic_tx_queue *txq = &sdev->txq; 84060c140dfSLino Sanfilippo struct slic_tx_buffer *buff; 84160c140dfSLino Sanfilippo struct slic_tx_desc *desc; 84260c140dfSLino Sanfilippo unsigned int i; 84360c140dfSLino Sanfilippo int err; 84460c140dfSLino Sanfilippo 84560c140dfSLino Sanfilippo txq->len = SLIC_NUM_TX_DESCS; 84660c140dfSLino Sanfilippo txq->put_idx = 0; 84760c140dfSLino Sanfilippo txq->done_idx = 0; 84860c140dfSLino Sanfilippo 84960c140dfSLino Sanfilippo txq->txbuffs = kcalloc(txq->len, sizeof(*buff), GFP_KERNEL); 85060c140dfSLino Sanfilippo if (!txq->txbuffs) 85160c140dfSLino Sanfilippo return -ENOMEM; 85260c140dfSLino Sanfilippo 85360c140dfSLino Sanfilippo txq->dma_pool = dma_pool_create("slic_pool", &sdev->pdev->dev, 85460c140dfSLino Sanfilippo sizeof(*desc), SLIC_TX_DESC_ALIGN, 85560c140dfSLino Sanfilippo 4096); 85660c140dfSLino Sanfilippo if (!txq->dma_pool) { 85760c140dfSLino Sanfilippo err = -ENOMEM; 85860c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to create dma pool\n"); 85960c140dfSLino Sanfilippo goto free_buffs; 86060c140dfSLino Sanfilippo } 86160c140dfSLino Sanfilippo 86260c140dfSLino Sanfilippo for (i = 0; i < txq->len; i++) { 86360c140dfSLino Sanfilippo buff = &txq->txbuffs[i]; 86460c140dfSLino Sanfilippo desc = dma_pool_zalloc(txq->dma_pool, GFP_KERNEL, 86560c140dfSLino Sanfilippo &buff->desc_paddr); 86660c140dfSLino Sanfilippo if (!desc) { 86760c140dfSLino Sanfilippo netdev_err(sdev->netdev, 86860c140dfSLino Sanfilippo "failed to alloc pool chunk (%i)\n", i); 86960c140dfSLino Sanfilippo err = -ENOMEM; 87060c140dfSLino Sanfilippo goto free_descs; 87160c140dfSLino Sanfilippo } 87260c140dfSLino Sanfilippo 87360c140dfSLino Sanfilippo desc->hnd = cpu_to_le32((u32)(i + 1)); 87460c140dfSLino Sanfilippo desc->cmd = SLIC_CMD_XMT_REQ; 87560c140dfSLino Sanfilippo desc->flags = 0; 87660c140dfSLino Sanfilippo desc->type = cpu_to_le32(SLIC_CMD_TYPE_DUMB); 87760c140dfSLino Sanfilippo buff->desc = desc; 87860c140dfSLino Sanfilippo } 87960c140dfSLino Sanfilippo 88060c140dfSLino Sanfilippo return 0; 88160c140dfSLino Sanfilippo 88260c140dfSLino Sanfilippo free_descs: 88360c140dfSLino Sanfilippo while (i--) { 88460c140dfSLino Sanfilippo buff = &txq->txbuffs[i]; 88560c140dfSLino Sanfilippo dma_pool_free(txq->dma_pool, buff->desc, buff->desc_paddr); 88660c140dfSLino Sanfilippo } 88760c140dfSLino Sanfilippo dma_pool_destroy(txq->dma_pool); 88860c140dfSLino Sanfilippo 88960c140dfSLino Sanfilippo free_buffs: 89060c140dfSLino Sanfilippo kfree(txq->txbuffs); 89160c140dfSLino Sanfilippo 89260c140dfSLino Sanfilippo return err; 89360c140dfSLino Sanfilippo } 89460c140dfSLino Sanfilippo 89560c140dfSLino Sanfilippo static void slic_free_tx_queue(struct slic_device *sdev) 89660c140dfSLino Sanfilippo { 89760c140dfSLino Sanfilippo struct slic_tx_queue *txq = &sdev->txq; 89860c140dfSLino Sanfilippo struct slic_tx_buffer *buff; 89960c140dfSLino Sanfilippo unsigned int i; 90060c140dfSLino Sanfilippo 90160c140dfSLino Sanfilippo for (i = 0; i < txq->len; i++) { 90260c140dfSLino Sanfilippo buff = &txq->txbuffs[i]; 90360c140dfSLino Sanfilippo dma_pool_free(txq->dma_pool, buff->desc, buff->desc_paddr); 90460c140dfSLino Sanfilippo if (!buff->skb) 90560c140dfSLino Sanfilippo continue; 90660c140dfSLino Sanfilippo 90760c140dfSLino Sanfilippo dma_unmap_single(&sdev->pdev->dev, 90860c140dfSLino Sanfilippo dma_unmap_addr(buff, map_addr), 90960c140dfSLino Sanfilippo dma_unmap_len(buff, map_len), DMA_TO_DEVICE); 91060c140dfSLino Sanfilippo consume_skb(buff->skb); 91160c140dfSLino Sanfilippo } 91260c140dfSLino Sanfilippo dma_pool_destroy(txq->dma_pool); 91360c140dfSLino Sanfilippo 91460c140dfSLino Sanfilippo kfree(txq->txbuffs); 91560c140dfSLino Sanfilippo } 91660c140dfSLino Sanfilippo 91760c140dfSLino Sanfilippo static int slic_init_rx_queue(struct slic_device *sdev) 91860c140dfSLino Sanfilippo { 91960c140dfSLino Sanfilippo struct slic_rx_queue *rxq = &sdev->rxq; 92060c140dfSLino Sanfilippo struct slic_rx_buffer *buff; 92160c140dfSLino Sanfilippo 92260c140dfSLino Sanfilippo rxq->len = SLIC_NUM_RX_LES; 92360c140dfSLino Sanfilippo rxq->done_idx = 0; 92460c140dfSLino Sanfilippo rxq->put_idx = 0; 92560c140dfSLino Sanfilippo 92660c140dfSLino Sanfilippo buff = kcalloc(rxq->len, sizeof(*buff), GFP_KERNEL); 92760c140dfSLino Sanfilippo if (!buff) 92860c140dfSLino Sanfilippo return -ENOMEM; 92960c140dfSLino Sanfilippo 93060c140dfSLino Sanfilippo rxq->rxbuffs = buff; 93160c140dfSLino Sanfilippo slic_refill_rx_queue(sdev, GFP_KERNEL); 93260c140dfSLino Sanfilippo 93360c140dfSLino Sanfilippo return 0; 93460c140dfSLino Sanfilippo } 93560c140dfSLino Sanfilippo 93660c140dfSLino Sanfilippo static void slic_free_rx_queue(struct slic_device *sdev) 93760c140dfSLino Sanfilippo { 93860c140dfSLino Sanfilippo struct slic_rx_queue *rxq = &sdev->rxq; 93960c140dfSLino Sanfilippo struct slic_rx_buffer *buff; 94060c140dfSLino Sanfilippo unsigned int i; 94160c140dfSLino Sanfilippo 94260c140dfSLino Sanfilippo /* free rx buffers */ 94360c140dfSLino Sanfilippo for (i = 0; i < rxq->len; i++) { 94460c140dfSLino Sanfilippo buff = &rxq->rxbuffs[i]; 94560c140dfSLino Sanfilippo 94660c140dfSLino Sanfilippo if (!buff->skb) 94760c140dfSLino Sanfilippo continue; 94860c140dfSLino Sanfilippo 94960c140dfSLino Sanfilippo dma_unmap_single(&sdev->pdev->dev, 95060c140dfSLino Sanfilippo dma_unmap_addr(buff, map_addr), 95160c140dfSLino Sanfilippo dma_unmap_len(buff, map_len), 95260c140dfSLino Sanfilippo DMA_FROM_DEVICE); 95360c140dfSLino Sanfilippo consume_skb(buff->skb); 95460c140dfSLino Sanfilippo } 95560c140dfSLino Sanfilippo kfree(rxq->rxbuffs); 95660c140dfSLino Sanfilippo } 95760c140dfSLino Sanfilippo 95860c140dfSLino Sanfilippo static void slic_set_link_autoneg(struct slic_device *sdev) 95960c140dfSLino Sanfilippo { 96060c140dfSLino Sanfilippo unsigned int subid = sdev->pdev->subsystem_device; 96160c140dfSLino Sanfilippo u32 val; 96260c140dfSLino Sanfilippo 96360c140dfSLino Sanfilippo if (sdev->is_fiber) { 96460c140dfSLino Sanfilippo /* We've got a fiber gigabit interface, and register 4 is 96560c140dfSLino Sanfilippo * different in fiber mode than in copper mode. 96660c140dfSLino Sanfilippo */ 96760c140dfSLino Sanfilippo /* advertise FD only @1000 Mb */ 96860c140dfSLino Sanfilippo val = MII_ADVERTISE << 16 | ADVERTISE_1000XFULL | 96960c140dfSLino Sanfilippo ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM; 97060c140dfSLino Sanfilippo /* enable PAUSE frames */ 97160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 97260c140dfSLino Sanfilippo /* reset phy, enable auto-neg */ 97360c140dfSLino Sanfilippo val = MII_BMCR << 16 | BMCR_RESET | BMCR_ANENABLE | 97460c140dfSLino Sanfilippo BMCR_ANRESTART; 97560c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 97660c140dfSLino Sanfilippo } else { /* copper gigabit */ 97760c140dfSLino Sanfilippo /* We've got a copper gigabit interface, and register 4 is 97860c140dfSLino Sanfilippo * different in copper mode than in fiber mode. 97960c140dfSLino Sanfilippo */ 98060c140dfSLino Sanfilippo /* advertise 10/100 Mb modes */ 98160c140dfSLino Sanfilippo val = MII_ADVERTISE << 16 | ADVERTISE_100FULL | 98260c140dfSLino Sanfilippo ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_10HALF; 98360c140dfSLino Sanfilippo /* enable PAUSE frames */ 98460c140dfSLino Sanfilippo val |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; 98560c140dfSLino Sanfilippo /* required by the Cicada PHY */ 98660c140dfSLino Sanfilippo val |= ADVERTISE_CSMA; 98760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 98860c140dfSLino Sanfilippo 98960c140dfSLino Sanfilippo /* advertise FD only @1000 Mb */ 99060c140dfSLino Sanfilippo val = MII_CTRL1000 << 16 | ADVERTISE_1000FULL; 99160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 99260c140dfSLino Sanfilippo 99360c140dfSLino Sanfilippo if (subid != PCI_SUBDEVICE_ID_ALACRITECH_CICADA) { 99460c140dfSLino Sanfilippo /* if a Marvell PHY enable auto crossover */ 99560c140dfSLino Sanfilippo val = SLIC_MIICR_REG_16 | SLIC_MRV_REG16_XOVERON; 99660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 99760c140dfSLino Sanfilippo 99860c140dfSLino Sanfilippo /* reset phy, enable auto-neg */ 99960c140dfSLino Sanfilippo val = MII_BMCR << 16 | BMCR_RESET | BMCR_ANENABLE | 100060c140dfSLino Sanfilippo BMCR_ANRESTART; 100160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 100260c140dfSLino Sanfilippo } else { 100360c140dfSLino Sanfilippo /* enable and restart auto-neg (don't reset) */ 100460c140dfSLino Sanfilippo val = MII_BMCR << 16 | BMCR_ANENABLE | BMCR_ANRESTART; 100560c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 100660c140dfSLino Sanfilippo } 100760c140dfSLino Sanfilippo } 100860c140dfSLino Sanfilippo } 100960c140dfSLino Sanfilippo 101060c140dfSLino Sanfilippo static void slic_set_mac_address(struct slic_device *sdev) 101160c140dfSLino Sanfilippo { 101260c140dfSLino Sanfilippo u8 *addr = sdev->netdev->dev_addr; 101360c140dfSLino Sanfilippo u32 val; 101460c140dfSLino Sanfilippo 101560c140dfSLino Sanfilippo val = addr[5] | addr[4] << 8 | addr[3] << 16 | addr[2] << 24; 101660c140dfSLino Sanfilippo 101760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRADDRAL, val); 101860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRADDRBL, val); 101960c140dfSLino Sanfilippo 102060c140dfSLino Sanfilippo val = addr[0] << 8 | addr[1]; 102160c140dfSLino Sanfilippo 102260c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRADDRAH, val); 102360c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRADDRBH, val); 102460c140dfSLino Sanfilippo slic_flush_write(sdev); 102560c140dfSLino Sanfilippo } 102660c140dfSLino Sanfilippo 102760c140dfSLino Sanfilippo static u32 slic_read_dword_from_firmware(const struct firmware *fw, int *offset) 102860c140dfSLino Sanfilippo { 102960c140dfSLino Sanfilippo int idx = *offset; 103060c140dfSLino Sanfilippo __le32 val; 103160c140dfSLino Sanfilippo 103260c140dfSLino Sanfilippo memcpy(&val, fw->data + *offset, sizeof(val)); 103360c140dfSLino Sanfilippo idx += 4; 103460c140dfSLino Sanfilippo *offset = idx; 103560c140dfSLino Sanfilippo 103660c140dfSLino Sanfilippo return le32_to_cpu(val); 103760c140dfSLino Sanfilippo } 103860c140dfSLino Sanfilippo 103960c140dfSLino Sanfilippo MODULE_FIRMWARE(SLIC_RCV_FIRMWARE_MOJAVE); 104060c140dfSLino Sanfilippo MODULE_FIRMWARE(SLIC_RCV_FIRMWARE_OASIS); 104160c140dfSLino Sanfilippo 104260c140dfSLino Sanfilippo static int slic_load_rcvseq_firmware(struct slic_device *sdev) 104360c140dfSLino Sanfilippo { 104460c140dfSLino Sanfilippo const struct firmware *fw; 104560c140dfSLino Sanfilippo const char *file; 104660c140dfSLino Sanfilippo u32 codelen; 104760c140dfSLino Sanfilippo int idx = 0; 104860c140dfSLino Sanfilippo u32 instr; 104960c140dfSLino Sanfilippo u32 addr; 105060c140dfSLino Sanfilippo int err; 105160c140dfSLino Sanfilippo 105260c140dfSLino Sanfilippo file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_RCV_FIRMWARE_OASIS : 105360c140dfSLino Sanfilippo SLIC_RCV_FIRMWARE_MOJAVE; 105460c140dfSLino Sanfilippo err = request_firmware(&fw, file, &sdev->pdev->dev); 105560c140dfSLino Sanfilippo if (err) { 105660c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 105760c140dfSLino Sanfilippo "failed to load receive sequencer firmware %s\n", file); 105860c140dfSLino Sanfilippo return err; 105960c140dfSLino Sanfilippo } 106060c140dfSLino Sanfilippo /* Do an initial sanity check concerning firmware size now. A further 106160c140dfSLino Sanfilippo * check follows below. 106260c140dfSLino Sanfilippo */ 106360c140dfSLino Sanfilippo if (fw->size < SLIC_FIRMWARE_MIN_SIZE) { 106460c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 106560c140dfSLino Sanfilippo "invalid firmware size %zu (min %u expected)\n", 106660c140dfSLino Sanfilippo fw->size, SLIC_FIRMWARE_MIN_SIZE); 106760c140dfSLino Sanfilippo err = -EINVAL; 106860c140dfSLino Sanfilippo goto release; 106960c140dfSLino Sanfilippo } 107060c140dfSLino Sanfilippo 107160c140dfSLino Sanfilippo codelen = slic_read_dword_from_firmware(fw, &idx); 107260c140dfSLino Sanfilippo 107360c140dfSLino Sanfilippo /* do another sanity check against firmware size */ 107460c140dfSLino Sanfilippo if ((codelen + 4) > fw->size) { 107560c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 107660c140dfSLino Sanfilippo "invalid rcv-sequencer firmware size %zu\n", fw->size); 107760c140dfSLino Sanfilippo err = -EINVAL; 107860c140dfSLino Sanfilippo goto release; 107960c140dfSLino Sanfilippo } 108060c140dfSLino Sanfilippo 108160c140dfSLino Sanfilippo /* download sequencer code to card */ 108260c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RCV_WCS, SLIC_RCVWCS_BEGIN); 108360c140dfSLino Sanfilippo for (addr = 0; addr < codelen; addr++) { 108460c140dfSLino Sanfilippo __le32 val; 108560c140dfSLino Sanfilippo /* write out instruction address */ 108660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RCV_WCS, addr); 108760c140dfSLino Sanfilippo 108860c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 108960c140dfSLino Sanfilippo /* write out the instruction data low addr */ 109060c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RCV_WCS, instr); 109160c140dfSLino Sanfilippo 109260c140dfSLino Sanfilippo val = (__le32)fw->data[idx]; 109360c140dfSLino Sanfilippo instr = le32_to_cpu(val); 109460c140dfSLino Sanfilippo idx++; 109560c140dfSLino Sanfilippo /* write out the instruction data high addr */ 109660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RCV_WCS, instr); 109760c140dfSLino Sanfilippo } 109860c140dfSLino Sanfilippo /* finish download */ 109960c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_RCV_WCS, SLIC_RCVWCS_FINISH); 110060c140dfSLino Sanfilippo slic_flush_write(sdev); 110160c140dfSLino Sanfilippo release: 110260c140dfSLino Sanfilippo release_firmware(fw); 110360c140dfSLino Sanfilippo 110460c140dfSLino Sanfilippo return err; 110560c140dfSLino Sanfilippo } 110660c140dfSLino Sanfilippo 110760c140dfSLino Sanfilippo MODULE_FIRMWARE(SLIC_FIRMWARE_MOJAVE); 110860c140dfSLino Sanfilippo MODULE_FIRMWARE(SLIC_FIRMWARE_OASIS); 110960c140dfSLino Sanfilippo 111060c140dfSLino Sanfilippo static int slic_load_firmware(struct slic_device *sdev) 111160c140dfSLino Sanfilippo { 111260c140dfSLino Sanfilippo u32 sectstart[SLIC_FIRMWARE_MAX_SECTIONS]; 111360c140dfSLino Sanfilippo u32 sectsize[SLIC_FIRMWARE_MAX_SECTIONS]; 111460c140dfSLino Sanfilippo const struct firmware *fw; 111560c140dfSLino Sanfilippo unsigned int datalen; 111660c140dfSLino Sanfilippo const char *file; 111760c140dfSLino Sanfilippo int code_start; 111860c140dfSLino Sanfilippo unsigned int i; 111960c140dfSLino Sanfilippo u32 numsects; 112060c140dfSLino Sanfilippo int idx = 0; 112160c140dfSLino Sanfilippo u32 sect; 112260c140dfSLino Sanfilippo u32 instr; 112360c140dfSLino Sanfilippo u32 addr; 112460c140dfSLino Sanfilippo u32 base; 112560c140dfSLino Sanfilippo int err; 112660c140dfSLino Sanfilippo 112760c140dfSLino Sanfilippo file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_FIRMWARE_OASIS : 112860c140dfSLino Sanfilippo SLIC_FIRMWARE_MOJAVE; 112960c140dfSLino Sanfilippo err = request_firmware(&fw, file, &sdev->pdev->dev); 113060c140dfSLino Sanfilippo if (err) { 113160c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "failed to load firmware %s\n", file); 113260c140dfSLino Sanfilippo return err; 113360c140dfSLino Sanfilippo } 113460c140dfSLino Sanfilippo /* Do an initial sanity check concerning firmware size now. A further 113560c140dfSLino Sanfilippo * check follows below. 113660c140dfSLino Sanfilippo */ 113760c140dfSLino Sanfilippo if (fw->size < SLIC_FIRMWARE_MIN_SIZE) { 113860c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 113960c140dfSLino Sanfilippo "invalid firmware size %zu (min is %u)\n", fw->size, 114060c140dfSLino Sanfilippo SLIC_FIRMWARE_MIN_SIZE); 114160c140dfSLino Sanfilippo err = -EINVAL; 114260c140dfSLino Sanfilippo goto release; 114360c140dfSLino Sanfilippo } 114460c140dfSLino Sanfilippo 114560c140dfSLino Sanfilippo numsects = slic_read_dword_from_firmware(fw, &idx); 114660c140dfSLino Sanfilippo if (numsects == 0 || numsects > SLIC_FIRMWARE_MAX_SECTIONS) { 114760c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 114860c140dfSLino Sanfilippo "invalid number of sections in firmware: %u", numsects); 114960c140dfSLino Sanfilippo err = -EINVAL; 115060c140dfSLino Sanfilippo goto release; 115160c140dfSLino Sanfilippo } 115260c140dfSLino Sanfilippo 115360c140dfSLino Sanfilippo datalen = numsects * 8 + 4; 115460c140dfSLino Sanfilippo for (i = 0; i < numsects; i++) { 115560c140dfSLino Sanfilippo sectsize[i] = slic_read_dword_from_firmware(fw, &idx); 115660c140dfSLino Sanfilippo datalen += sectsize[i]; 115760c140dfSLino Sanfilippo } 115860c140dfSLino Sanfilippo 115960c140dfSLino Sanfilippo /* do another sanity check against firmware size */ 116060c140dfSLino Sanfilippo if (datalen > fw->size) { 116160c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 116260c140dfSLino Sanfilippo "invalid firmware size %zu (expected >= %u)\n", 116360c140dfSLino Sanfilippo fw->size, datalen); 116460c140dfSLino Sanfilippo err = -EINVAL; 116560c140dfSLino Sanfilippo goto release; 116660c140dfSLino Sanfilippo } 116760c140dfSLino Sanfilippo /* get sections */ 116860c140dfSLino Sanfilippo for (i = 0; i < numsects; i++) 116960c140dfSLino Sanfilippo sectstart[i] = slic_read_dword_from_firmware(fw, &idx); 117060c140dfSLino Sanfilippo 117160c140dfSLino Sanfilippo code_start = idx; 117260c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 117360c140dfSLino Sanfilippo 117460c140dfSLino Sanfilippo for (sect = 0; sect < numsects; sect++) { 117560c140dfSLino Sanfilippo unsigned int ssize = sectsize[sect] >> 3; 117660c140dfSLino Sanfilippo 117760c140dfSLino Sanfilippo base = sectstart[sect]; 117860c140dfSLino Sanfilippo 117960c140dfSLino Sanfilippo for (addr = 0; addr < ssize; addr++) { 118060c140dfSLino Sanfilippo /* write out instruction address */ 118160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, base + addr); 118260c140dfSLino Sanfilippo /* write out instruction to low addr */ 118360c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, instr); 118460c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 118560c140dfSLino Sanfilippo /* write out instruction to high addr */ 118660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, instr); 118760c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 118860c140dfSLino Sanfilippo } 118960c140dfSLino Sanfilippo } 119060c140dfSLino Sanfilippo 119160c140dfSLino Sanfilippo idx = code_start; 119260c140dfSLino Sanfilippo 119360c140dfSLino Sanfilippo for (sect = 0; sect < numsects; sect++) { 119460c140dfSLino Sanfilippo unsigned int ssize = sectsize[sect] >> 3; 119560c140dfSLino Sanfilippo 119660c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 119760c140dfSLino Sanfilippo base = sectstart[sect]; 119860c140dfSLino Sanfilippo if (base < 0x8000) 119960c140dfSLino Sanfilippo continue; 120060c140dfSLino Sanfilippo 120160c140dfSLino Sanfilippo for (addr = 0; addr < ssize; addr++) { 120260c140dfSLino Sanfilippo /* write out instruction address */ 120360c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, 120460c140dfSLino Sanfilippo SLIC_WCS_COMPARE | (base + addr)); 120560c140dfSLino Sanfilippo /* write out instruction to low addr */ 120660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, instr); 120760c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 120860c140dfSLino Sanfilippo /* write out instruction to high addr */ 120960c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, instr); 121060c140dfSLino Sanfilippo instr = slic_read_dword_from_firmware(fw, &idx); 121160c140dfSLino Sanfilippo } 121260c140dfSLino Sanfilippo } 121360c140dfSLino Sanfilippo slic_flush_write(sdev); 121460c140dfSLino Sanfilippo mdelay(10); 121560c140dfSLino Sanfilippo /* everything OK, kick off the card */ 121660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WCS, SLIC_WCS_START); 121760c140dfSLino Sanfilippo slic_flush_write(sdev); 121860c140dfSLino Sanfilippo /* wait long enough for ucode to init card and reach the mainloop */ 121960c140dfSLino Sanfilippo mdelay(20); 122060c140dfSLino Sanfilippo release: 122160c140dfSLino Sanfilippo release_firmware(fw); 122260c140dfSLino Sanfilippo 122360c140dfSLino Sanfilippo return err; 122460c140dfSLino Sanfilippo } 122560c140dfSLino Sanfilippo 122660c140dfSLino Sanfilippo static int slic_init_shmem(struct slic_device *sdev) 122760c140dfSLino Sanfilippo { 122860c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 122960c140dfSLino Sanfilippo struct slic_shmem_data *sm_data; 123060c140dfSLino Sanfilippo dma_addr_t paddr; 123160c140dfSLino Sanfilippo 1232750afb08SLuis Chamberlain sm_data = dma_alloc_coherent(&sdev->pdev->dev, sizeof(*sm_data), 123360c140dfSLino Sanfilippo &paddr, GFP_KERNEL); 123460c140dfSLino Sanfilippo if (!sm_data) { 123560c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "failed to allocate shared memory\n"); 123660c140dfSLino Sanfilippo return -ENOMEM; 123760c140dfSLino Sanfilippo } 123860c140dfSLino Sanfilippo 123960c140dfSLino Sanfilippo sm->shmem_data = sm_data; 124060c140dfSLino Sanfilippo sm->isr_paddr = paddr; 124160c140dfSLino Sanfilippo sm->link_paddr = paddr + offsetof(struct slic_shmem_data, link); 124260c140dfSLino Sanfilippo 124360c140dfSLino Sanfilippo return 0; 124460c140dfSLino Sanfilippo } 124560c140dfSLino Sanfilippo 124660c140dfSLino Sanfilippo static void slic_free_shmem(struct slic_device *sdev) 124760c140dfSLino Sanfilippo { 124860c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 124960c140dfSLino Sanfilippo struct slic_shmem_data *sm_data = sm->shmem_data; 125060c140dfSLino Sanfilippo 125160c140dfSLino Sanfilippo dma_free_coherent(&sdev->pdev->dev, sizeof(*sm_data), sm_data, 125260c140dfSLino Sanfilippo sm->isr_paddr); 125360c140dfSLino Sanfilippo } 125460c140dfSLino Sanfilippo 125560c140dfSLino Sanfilippo static int slic_init_iface(struct slic_device *sdev) 125660c140dfSLino Sanfilippo { 125760c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 125860c140dfSLino Sanfilippo int err; 125960c140dfSLino Sanfilippo 126060c140dfSLino Sanfilippo sdev->upr_list.pending = false; 126160c140dfSLino Sanfilippo 126260c140dfSLino Sanfilippo err = slic_init_shmem(sdev); 126360c140dfSLino Sanfilippo if (err) { 126460c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to init shared memory\n"); 126560c140dfSLino Sanfilippo return err; 126660c140dfSLino Sanfilippo } 126760c140dfSLino Sanfilippo 126860c140dfSLino Sanfilippo err = slic_load_firmware(sdev); 126960c140dfSLino Sanfilippo if (err) { 127060c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to load firmware\n"); 127160c140dfSLino Sanfilippo goto free_sm; 127260c140dfSLino Sanfilippo } 127360c140dfSLino Sanfilippo 127460c140dfSLino Sanfilippo err = slic_load_rcvseq_firmware(sdev); 127560c140dfSLino Sanfilippo if (err) { 127660c140dfSLino Sanfilippo netdev_err(sdev->netdev, 127760c140dfSLino Sanfilippo "failed to load firmware for receive sequencer\n"); 127860c140dfSLino Sanfilippo goto free_sm; 127960c140dfSLino Sanfilippo } 128060c140dfSLino Sanfilippo 128160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ICR, SLIC_ICR_INT_OFF); 128260c140dfSLino Sanfilippo slic_flush_write(sdev); 128360c140dfSLino Sanfilippo mdelay(1); 128460c140dfSLino Sanfilippo 128560c140dfSLino Sanfilippo err = slic_init_rx_queue(sdev); 128660c140dfSLino Sanfilippo if (err) { 128760c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to init rx queue: %u\n", err); 128860c140dfSLino Sanfilippo goto free_sm; 128960c140dfSLino Sanfilippo } 129060c140dfSLino Sanfilippo 129160c140dfSLino Sanfilippo err = slic_init_tx_queue(sdev); 129260c140dfSLino Sanfilippo if (err) { 129360c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to init tx queue: %u\n", err); 129460c140dfSLino Sanfilippo goto free_rxq; 129560c140dfSLino Sanfilippo } 129660c140dfSLino Sanfilippo 129760c140dfSLino Sanfilippo err = slic_init_stat_queue(sdev); 129860c140dfSLino Sanfilippo if (err) { 129960c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to init status queue: %u\n", 130060c140dfSLino Sanfilippo err); 130160c140dfSLino Sanfilippo goto free_txq; 130260c140dfSLino Sanfilippo } 130360c140dfSLino Sanfilippo 130460c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISP, lower_32_bits(sm->isr_paddr)); 130560c140dfSLino Sanfilippo napi_enable(&sdev->napi); 130660c140dfSLino Sanfilippo /* disable irq mitigation */ 130760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_INTAGG, 0); 130860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISR, 0); 130960c140dfSLino Sanfilippo slic_flush_write(sdev); 131060c140dfSLino Sanfilippo 131160c140dfSLino Sanfilippo slic_set_mac_address(sdev); 131260c140dfSLino Sanfilippo 131360c140dfSLino Sanfilippo spin_lock_bh(&sdev->link_lock); 131460c140dfSLino Sanfilippo sdev->duplex = DUPLEX_UNKNOWN; 131560c140dfSLino Sanfilippo sdev->speed = SPEED_UNKNOWN; 131660c140dfSLino Sanfilippo spin_unlock_bh(&sdev->link_lock); 131760c140dfSLino Sanfilippo 131860c140dfSLino Sanfilippo slic_set_link_autoneg(sdev); 131960c140dfSLino Sanfilippo 132060c140dfSLino Sanfilippo err = request_irq(sdev->pdev->irq, slic_irq, IRQF_SHARED, DRV_NAME, 132160c140dfSLino Sanfilippo sdev); 132260c140dfSLino Sanfilippo if (err) { 132360c140dfSLino Sanfilippo netdev_err(sdev->netdev, "failed to request irq: %u\n", err); 132460c140dfSLino Sanfilippo goto disable_napi; 132560c140dfSLino Sanfilippo } 132660c140dfSLino Sanfilippo 132760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ICR, SLIC_ICR_INT_ON); 132860c140dfSLino Sanfilippo slic_flush_write(sdev); 132960c140dfSLino Sanfilippo /* request initial link status */ 133060c140dfSLino Sanfilippo err = slic_handle_link_change(sdev); 133160c140dfSLino Sanfilippo if (err) 133260c140dfSLino Sanfilippo netdev_warn(sdev->netdev, 133360c140dfSLino Sanfilippo "failed to set initial link state: %u\n", err); 133460c140dfSLino Sanfilippo return 0; 133560c140dfSLino Sanfilippo 133660c140dfSLino Sanfilippo disable_napi: 133760c140dfSLino Sanfilippo napi_disable(&sdev->napi); 133860c140dfSLino Sanfilippo slic_free_stat_queue(sdev); 133960c140dfSLino Sanfilippo free_txq: 134060c140dfSLino Sanfilippo slic_free_tx_queue(sdev); 134160c140dfSLino Sanfilippo free_rxq: 134260c140dfSLino Sanfilippo slic_free_rx_queue(sdev); 134360c140dfSLino Sanfilippo free_sm: 134460c140dfSLino Sanfilippo slic_free_shmem(sdev); 134560c140dfSLino Sanfilippo slic_card_reset(sdev); 134660c140dfSLino Sanfilippo 134760c140dfSLino Sanfilippo return err; 134860c140dfSLino Sanfilippo } 134960c140dfSLino Sanfilippo 135060c140dfSLino Sanfilippo static int slic_open(struct net_device *dev) 135160c140dfSLino Sanfilippo { 135260c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 135360c140dfSLino Sanfilippo int err; 135460c140dfSLino Sanfilippo 135560c140dfSLino Sanfilippo netif_carrier_off(dev); 135660c140dfSLino Sanfilippo 135760c140dfSLino Sanfilippo err = slic_init_iface(sdev); 135860c140dfSLino Sanfilippo if (err) { 135960c140dfSLino Sanfilippo netdev_err(dev, "failed to initialize interface: %i\n", err); 136060c140dfSLino Sanfilippo return err; 136160c140dfSLino Sanfilippo } 136260c140dfSLino Sanfilippo 136360c140dfSLino Sanfilippo netif_start_queue(dev); 136460c140dfSLino Sanfilippo 136560c140dfSLino Sanfilippo return 0; 136660c140dfSLino Sanfilippo } 136760c140dfSLino Sanfilippo 136860c140dfSLino Sanfilippo static int slic_close(struct net_device *dev) 136960c140dfSLino Sanfilippo { 137060c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 137160c140dfSLino Sanfilippo u32 val; 137260c140dfSLino Sanfilippo 137360c140dfSLino Sanfilippo netif_stop_queue(dev); 137460c140dfSLino Sanfilippo 137560c140dfSLino Sanfilippo /* stop irq handling */ 137660c140dfSLino Sanfilippo napi_disable(&sdev->napi); 137760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ICR, SLIC_ICR_INT_OFF); 137860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISR, 0); 137960c140dfSLino Sanfilippo slic_flush_write(sdev); 138060c140dfSLino Sanfilippo 138160c140dfSLino Sanfilippo free_irq(sdev->pdev->irq, sdev); 138260c140dfSLino Sanfilippo /* turn off RCV and XMT and power down PHY */ 138360c140dfSLino Sanfilippo val = SLIC_GXCR_RESET | SLIC_GXCR_PAUSEEN; 138460c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WXCFG, val); 138560c140dfSLino Sanfilippo 138660c140dfSLino Sanfilippo val = SLIC_GRCR_RESET | SLIC_GRCR_CTLEN | SLIC_GRCR_ADDRAEN | 138760c140dfSLino Sanfilippo SLIC_GRCR_HASHSIZE << SLIC_GRCR_HASHSIZE_SHIFT; 138860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WRCFG, val); 138960c140dfSLino Sanfilippo 139060c140dfSLino Sanfilippo val = MII_BMCR << 16 | BMCR_PDOWN; 139160c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_WPHY, val); 139260c140dfSLino Sanfilippo slic_flush_write(sdev); 139360c140dfSLino Sanfilippo 139460c140dfSLino Sanfilippo slic_clear_upr_list(&sdev->upr_list); 139560c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_QUIESCE, 0); 139660c140dfSLino Sanfilippo 139760c140dfSLino Sanfilippo slic_free_stat_queue(sdev); 139860c140dfSLino Sanfilippo slic_free_tx_queue(sdev); 139960c140dfSLino Sanfilippo slic_free_rx_queue(sdev); 140060c140dfSLino Sanfilippo slic_free_shmem(sdev); 140160c140dfSLino Sanfilippo 140260c140dfSLino Sanfilippo slic_card_reset(sdev); 140360c140dfSLino Sanfilippo netif_carrier_off(dev); 140460c140dfSLino Sanfilippo 140560c140dfSLino Sanfilippo return 0; 140660c140dfSLino Sanfilippo } 140760c140dfSLino Sanfilippo 140860c140dfSLino Sanfilippo static netdev_tx_t slic_xmit(struct sk_buff *skb, struct net_device *dev) 140960c140dfSLino Sanfilippo { 141060c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 141160c140dfSLino Sanfilippo struct slic_tx_queue *txq = &sdev->txq; 141260c140dfSLino Sanfilippo struct slic_tx_buffer *buff; 141360c140dfSLino Sanfilippo struct slic_tx_desc *desc; 141460c140dfSLino Sanfilippo dma_addr_t paddr; 141560c140dfSLino Sanfilippo u32 cbar_val; 141660c140dfSLino Sanfilippo u32 maplen; 141760c140dfSLino Sanfilippo 141860c140dfSLino Sanfilippo if (unlikely(slic_get_free_tx_descs(txq) < SLIC_MAX_REQ_TX_DESCS)) { 141960c140dfSLino Sanfilippo netdev_err(dev, "BUG! not enough tx LEs left: %u\n", 142060c140dfSLino Sanfilippo slic_get_free_tx_descs(txq)); 142160c140dfSLino Sanfilippo return NETDEV_TX_BUSY; 142260c140dfSLino Sanfilippo } 142360c140dfSLino Sanfilippo 142460c140dfSLino Sanfilippo maplen = skb_headlen(skb); 142560c140dfSLino Sanfilippo paddr = dma_map_single(&sdev->pdev->dev, skb->data, maplen, 142660c140dfSLino Sanfilippo DMA_TO_DEVICE); 142760c140dfSLino Sanfilippo if (dma_mapping_error(&sdev->pdev->dev, paddr)) { 142860c140dfSLino Sanfilippo netdev_err(dev, "failed to map tx buffer\n"); 142960c140dfSLino Sanfilippo goto drop_skb; 143060c140dfSLino Sanfilippo } 143160c140dfSLino Sanfilippo 143260c140dfSLino Sanfilippo buff = &txq->txbuffs[txq->put_idx]; 143360c140dfSLino Sanfilippo buff->skb = skb; 143460c140dfSLino Sanfilippo dma_unmap_addr_set(buff, map_addr, paddr); 143560c140dfSLino Sanfilippo dma_unmap_len_set(buff, map_len, maplen); 143660c140dfSLino Sanfilippo 143760c140dfSLino Sanfilippo desc = buff->desc; 143860c140dfSLino Sanfilippo desc->totlen = cpu_to_le32(maplen); 143960c140dfSLino Sanfilippo desc->paddrl = cpu_to_le32(lower_32_bits(paddr)); 144060c140dfSLino Sanfilippo desc->paddrh = cpu_to_le32(upper_32_bits(paddr)); 144160c140dfSLino Sanfilippo desc->len = cpu_to_le32(maplen); 144260c140dfSLino Sanfilippo 144360c140dfSLino Sanfilippo txq->put_idx = slic_next_queue_idx(txq->put_idx, txq->len); 144460c140dfSLino Sanfilippo 144560c140dfSLino Sanfilippo cbar_val = lower_32_bits(buff->desc_paddr) | 1; 144660c140dfSLino Sanfilippo /* complete writes to RAM and DMA before hardware is informed */ 144760c140dfSLino Sanfilippo wmb(); 144860c140dfSLino Sanfilippo 144960c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_CBAR, cbar_val); 145060c140dfSLino Sanfilippo 145160c140dfSLino Sanfilippo if (slic_get_free_tx_descs(txq) < SLIC_MAX_REQ_TX_DESCS) 145260c140dfSLino Sanfilippo netif_stop_queue(dev); 145360c140dfSLino Sanfilippo 145460c140dfSLino Sanfilippo return NETDEV_TX_OK; 145560c140dfSLino Sanfilippo drop_skb: 145660c140dfSLino Sanfilippo dev_kfree_skb_any(skb); 145760c140dfSLino Sanfilippo 145860c140dfSLino Sanfilippo return NETDEV_TX_OK; 145960c140dfSLino Sanfilippo } 146060c140dfSLino Sanfilippo 1461bc1f4470Sstephen hemminger static void slic_get_stats(struct net_device *dev, 146260c140dfSLino Sanfilippo struct rtnl_link_stats64 *lst) 146360c140dfSLino Sanfilippo { 146460c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 146560c140dfSLino Sanfilippo struct slic_stats *stats = &sdev->stats; 146660c140dfSLino Sanfilippo 146760c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_packets, stats, rx_packets); 146860c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->tx_packets, stats, tx_packets); 146960c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_bytes, stats, rx_bytes); 147060c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->tx_bytes, stats, tx_bytes); 147160c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_errors, stats, rx_errors); 147260c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_dropped, stats, rx_buff_miss); 147360c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->tx_dropped, stats, tx_dropped); 147460c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->multicast, stats, rx_mcasts); 147560c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_over_errors, stats, rx_buffoflow); 147660c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_crc_errors, stats, rx_crc); 147760c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->rx_fifo_errors, stats, rx_oflow802); 147860c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(lst->tx_carrier_errors, stats, tx_carrier); 147960c140dfSLino Sanfilippo } 148060c140dfSLino Sanfilippo 148160c140dfSLino Sanfilippo static int slic_get_sset_count(struct net_device *dev, int sset) 148260c140dfSLino Sanfilippo { 148360c140dfSLino Sanfilippo switch (sset) { 148460c140dfSLino Sanfilippo case ETH_SS_STATS: 148560c140dfSLino Sanfilippo return ARRAY_SIZE(slic_stats_strings); 148660c140dfSLino Sanfilippo default: 148760c140dfSLino Sanfilippo return -EOPNOTSUPP; 148860c140dfSLino Sanfilippo } 148960c140dfSLino Sanfilippo } 149060c140dfSLino Sanfilippo 149160c140dfSLino Sanfilippo static void slic_get_ethtool_stats(struct net_device *dev, 149260c140dfSLino Sanfilippo struct ethtool_stats *eth_stats, u64 *data) 149360c140dfSLino Sanfilippo { 149460c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 149560c140dfSLino Sanfilippo struct slic_stats *stats = &sdev->stats; 149660c140dfSLino Sanfilippo 149760c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[0], stats, rx_packets); 149860c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[1], stats, rx_bytes); 149960c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[2], stats, rx_mcasts); 150060c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[3], stats, rx_errors); 150160c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[4], stats, rx_buff_miss); 150260c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[5], stats, rx_tpcsum); 150360c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[6], stats, rx_tpoflow); 150460c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[7], stats, rx_tphlen); 150560c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[8], stats, rx_ipcsum); 150660c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[9], stats, rx_iplen); 150760c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[10], stats, rx_iphlen); 150860c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[11], stats, rx_early); 150960c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[12], stats, rx_buffoflow); 151060c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[13], stats, rx_lcode); 151160c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[14], stats, rx_drbl); 151260c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[15], stats, rx_crc); 151360c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[16], stats, rx_oflow802); 151460c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[17], stats, rx_uflow802); 151560c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[18], stats, tx_packets); 151660c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[19], stats, tx_bytes); 151760c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[20], stats, tx_carrier); 151860c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[21], stats, tx_dropped); 151960c140dfSLino Sanfilippo SLIC_GET_STATS_COUNTER(data[22], stats, irq_errs); 152060c140dfSLino Sanfilippo } 152160c140dfSLino Sanfilippo 152260c140dfSLino Sanfilippo static void slic_get_strings(struct net_device *dev, u32 stringset, u8 *data) 152360c140dfSLino Sanfilippo { 152460c140dfSLino Sanfilippo if (stringset == ETH_SS_STATS) { 152560c140dfSLino Sanfilippo memcpy(data, slic_stats_strings, sizeof(slic_stats_strings)); 152660c140dfSLino Sanfilippo data += sizeof(slic_stats_strings); 152760c140dfSLino Sanfilippo } 152860c140dfSLino Sanfilippo } 152960c140dfSLino Sanfilippo 153060c140dfSLino Sanfilippo static void slic_get_drvinfo(struct net_device *dev, 153160c140dfSLino Sanfilippo struct ethtool_drvinfo *info) 153260c140dfSLino Sanfilippo { 153360c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 153460c140dfSLino Sanfilippo 153560c140dfSLino Sanfilippo strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); 153660c140dfSLino Sanfilippo strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 153760c140dfSLino Sanfilippo strlcpy(info->bus_info, pci_name(sdev->pdev), sizeof(info->bus_info)); 153860c140dfSLino Sanfilippo } 153960c140dfSLino Sanfilippo 154060c140dfSLino Sanfilippo static const struct ethtool_ops slic_ethtool_ops = { 154160c140dfSLino Sanfilippo .get_drvinfo = slic_get_drvinfo, 154260c140dfSLino Sanfilippo .get_link = ethtool_op_get_link, 154360c140dfSLino Sanfilippo .get_strings = slic_get_strings, 154460c140dfSLino Sanfilippo .get_ethtool_stats = slic_get_ethtool_stats, 154560c140dfSLino Sanfilippo .get_sset_count = slic_get_sset_count, 154660c140dfSLino Sanfilippo }; 154760c140dfSLino Sanfilippo 154860c140dfSLino Sanfilippo static const struct net_device_ops slic_netdev_ops = { 154960c140dfSLino Sanfilippo .ndo_open = slic_open, 155060c140dfSLino Sanfilippo .ndo_stop = slic_close, 155160c140dfSLino Sanfilippo .ndo_start_xmit = slic_xmit, 155260c140dfSLino Sanfilippo .ndo_set_mac_address = eth_mac_addr, 155360c140dfSLino Sanfilippo .ndo_get_stats64 = slic_get_stats, 155460c140dfSLino Sanfilippo .ndo_set_rx_mode = slic_set_rx_mode, 155560c140dfSLino Sanfilippo .ndo_validate_addr = eth_validate_addr, 155660c140dfSLino Sanfilippo }; 155760c140dfSLino Sanfilippo 155860c140dfSLino Sanfilippo static u16 slic_eeprom_csum(unsigned char *eeprom, unsigned int len) 155960c140dfSLino Sanfilippo { 156060c140dfSLino Sanfilippo unsigned char *ptr = eeprom; 156160c140dfSLino Sanfilippo u32 csum = 0; 156260c140dfSLino Sanfilippo __le16 data; 156360c140dfSLino Sanfilippo 156460c140dfSLino Sanfilippo while (len > 1) { 156560c140dfSLino Sanfilippo memcpy(&data, ptr, sizeof(data)); 156660c140dfSLino Sanfilippo csum += le16_to_cpu(data); 156760c140dfSLino Sanfilippo ptr += 2; 156860c140dfSLino Sanfilippo len -= 2; 156960c140dfSLino Sanfilippo } 157060c140dfSLino Sanfilippo if (len > 0) 157160c140dfSLino Sanfilippo csum += *(u8 *)ptr; 157260c140dfSLino Sanfilippo while (csum >> 16) 157360c140dfSLino Sanfilippo csum = (csum & 0xFFFF) + ((csum >> 16) & 0xFFFF); 157460c140dfSLino Sanfilippo return ~csum; 157560c140dfSLino Sanfilippo } 157660c140dfSLino Sanfilippo 157760c140dfSLino Sanfilippo /* check eeprom size, magic and checksum */ 157860c140dfSLino Sanfilippo static bool slic_eeprom_valid(unsigned char *eeprom, unsigned int size) 157960c140dfSLino Sanfilippo { 158060c140dfSLino Sanfilippo const unsigned int MAX_SIZE = 128; 158160c140dfSLino Sanfilippo const unsigned int MIN_SIZE = 98; 158260c140dfSLino Sanfilippo __le16 magic; 158360c140dfSLino Sanfilippo __le16 csum; 158460c140dfSLino Sanfilippo 158560c140dfSLino Sanfilippo if (size < MIN_SIZE || size > MAX_SIZE) 158660c140dfSLino Sanfilippo return false; 158760c140dfSLino Sanfilippo memcpy(&magic, eeprom, sizeof(magic)); 158860c140dfSLino Sanfilippo if (le16_to_cpu(magic) != SLIC_EEPROM_MAGIC) 158960c140dfSLino Sanfilippo return false; 159060c140dfSLino Sanfilippo /* cut checksum bytes */ 159160c140dfSLino Sanfilippo size -= 2; 159260c140dfSLino Sanfilippo memcpy(&csum, eeprom + size, sizeof(csum)); 159360c140dfSLino Sanfilippo 159460c140dfSLino Sanfilippo return (le16_to_cpu(csum) == slic_eeprom_csum(eeprom, size)); 159560c140dfSLino Sanfilippo } 159660c140dfSLino Sanfilippo 159760c140dfSLino Sanfilippo static int slic_read_eeprom(struct slic_device *sdev) 159860c140dfSLino Sanfilippo { 159960c140dfSLino Sanfilippo unsigned int devfn = PCI_FUNC(sdev->pdev->devfn); 160060c140dfSLino Sanfilippo struct slic_shmem *sm = &sdev->shmem; 160160c140dfSLino Sanfilippo struct slic_shmem_data *sm_data = sm->shmem_data; 160260c140dfSLino Sanfilippo const unsigned int MAX_LOOPS = 5000; 160360c140dfSLino Sanfilippo unsigned int codesize; 160460c140dfSLino Sanfilippo unsigned char *eeprom; 160560c140dfSLino Sanfilippo struct slic_upr *upr; 160660c140dfSLino Sanfilippo unsigned int i = 0; 160760c140dfSLino Sanfilippo dma_addr_t paddr; 160860c140dfSLino Sanfilippo int err = 0; 160960c140dfSLino Sanfilippo u8 *mac[2]; 161060c140dfSLino Sanfilippo 1611750afb08SLuis Chamberlain eeprom = dma_alloc_coherent(&sdev->pdev->dev, SLIC_EEPROM_SIZE, 161260c140dfSLino Sanfilippo &paddr, GFP_KERNEL); 161360c140dfSLino Sanfilippo if (!eeprom) 161460c140dfSLino Sanfilippo return -ENOMEM; 161560c140dfSLino Sanfilippo 161660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ICR, SLIC_ICR_INT_OFF); 161760c140dfSLino Sanfilippo /* setup ISP temporarily */ 161860c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISP, lower_32_bits(sm->isr_paddr)); 161960c140dfSLino Sanfilippo 162060c140dfSLino Sanfilippo err = slic_new_upr(sdev, SLIC_UPR_CONFIG, paddr); 162160c140dfSLino Sanfilippo if (!err) { 162260c140dfSLino Sanfilippo for (i = 0; i < MAX_LOOPS; i++) { 162360c140dfSLino Sanfilippo if (le32_to_cpu(sm_data->isr) & SLIC_ISR_UPC) 162460c140dfSLino Sanfilippo break; 162560c140dfSLino Sanfilippo mdelay(1); 162660c140dfSLino Sanfilippo } 162760c140dfSLino Sanfilippo if (i == MAX_LOOPS) { 162860c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, 162960c140dfSLino Sanfilippo "timed out while waiting for eeprom data\n"); 163060c140dfSLino Sanfilippo err = -ETIMEDOUT; 163160c140dfSLino Sanfilippo } 163260c140dfSLino Sanfilippo upr = slic_dequeue_upr(sdev); 163360c140dfSLino Sanfilippo kfree(upr); 163460c140dfSLino Sanfilippo } 163560c140dfSLino Sanfilippo 163660c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISP, 0); 163760c140dfSLino Sanfilippo slic_write(sdev, SLIC_REG_ISR, 0); 163860c140dfSLino Sanfilippo slic_flush_write(sdev); 163960c140dfSLino Sanfilippo 164060c140dfSLino Sanfilippo if (err) 164160c140dfSLino Sanfilippo goto free_eeprom; 164260c140dfSLino Sanfilippo 164360c140dfSLino Sanfilippo if (sdev->model == SLIC_MODEL_OASIS) { 164460c140dfSLino Sanfilippo struct slic_oasis_eeprom *oee; 164560c140dfSLino Sanfilippo 164660c140dfSLino Sanfilippo oee = (struct slic_oasis_eeprom *)eeprom; 164760c140dfSLino Sanfilippo mac[0] = oee->mac; 164860c140dfSLino Sanfilippo mac[1] = oee->mac2; 164960c140dfSLino Sanfilippo codesize = le16_to_cpu(oee->eeprom_code_size); 165060c140dfSLino Sanfilippo } else { 165160c140dfSLino Sanfilippo struct slic_mojave_eeprom *mee; 165260c140dfSLino Sanfilippo 165360c140dfSLino Sanfilippo mee = (struct slic_mojave_eeprom *)eeprom; 165460c140dfSLino Sanfilippo mac[0] = mee->mac; 165560c140dfSLino Sanfilippo mac[1] = mee->mac2; 165660c140dfSLino Sanfilippo codesize = le16_to_cpu(mee->eeprom_code_size); 165760c140dfSLino Sanfilippo } 165860c140dfSLino Sanfilippo 165960c140dfSLino Sanfilippo if (!slic_eeprom_valid(eeprom, codesize)) { 166060c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "invalid checksum in eeprom\n"); 166160c140dfSLino Sanfilippo err = -EINVAL; 166260c140dfSLino Sanfilippo goto free_eeprom; 166360c140dfSLino Sanfilippo } 166460c140dfSLino Sanfilippo /* set mac address */ 166560c140dfSLino Sanfilippo ether_addr_copy(sdev->netdev->dev_addr, mac[devfn]); 166660c140dfSLino Sanfilippo free_eeprom: 166760c140dfSLino Sanfilippo dma_free_coherent(&sdev->pdev->dev, SLIC_EEPROM_SIZE, eeprom, paddr); 166860c140dfSLino Sanfilippo 166960c140dfSLino Sanfilippo return err; 167060c140dfSLino Sanfilippo } 167160c140dfSLino Sanfilippo 167260c140dfSLino Sanfilippo static int slic_init(struct slic_device *sdev) 167360c140dfSLino Sanfilippo { 167460c140dfSLino Sanfilippo int err; 167560c140dfSLino Sanfilippo 167660c140dfSLino Sanfilippo spin_lock_init(&sdev->upper_lock); 167760c140dfSLino Sanfilippo spin_lock_init(&sdev->link_lock); 167860c140dfSLino Sanfilippo INIT_LIST_HEAD(&sdev->upr_list.list); 167960c140dfSLino Sanfilippo spin_lock_init(&sdev->upr_list.lock); 168060c140dfSLino Sanfilippo u64_stats_init(&sdev->stats.syncp); 168160c140dfSLino Sanfilippo 168260c140dfSLino Sanfilippo slic_card_reset(sdev); 168360c140dfSLino Sanfilippo 168460c140dfSLino Sanfilippo err = slic_load_firmware(sdev); 168560c140dfSLino Sanfilippo if (err) { 168660c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "failed to load firmware\n"); 168760c140dfSLino Sanfilippo return err; 168860c140dfSLino Sanfilippo } 168960c140dfSLino Sanfilippo 169060c140dfSLino Sanfilippo /* we need the shared memory to read EEPROM so set it up temporarily */ 169160c140dfSLino Sanfilippo err = slic_init_shmem(sdev); 169260c140dfSLino Sanfilippo if (err) { 169360c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "failed to init shared memory\n"); 169460c140dfSLino Sanfilippo return err; 169560c140dfSLino Sanfilippo } 169660c140dfSLino Sanfilippo 169760c140dfSLino Sanfilippo err = slic_read_eeprom(sdev); 169860c140dfSLino Sanfilippo if (err) { 169960c140dfSLino Sanfilippo dev_err(&sdev->pdev->dev, "failed to read eeprom\n"); 170060c140dfSLino Sanfilippo goto free_sm; 170160c140dfSLino Sanfilippo } 170260c140dfSLino Sanfilippo 170360c140dfSLino Sanfilippo slic_card_reset(sdev); 170460c140dfSLino Sanfilippo slic_free_shmem(sdev); 170560c140dfSLino Sanfilippo 170660c140dfSLino Sanfilippo return 0; 170760c140dfSLino Sanfilippo free_sm: 170860c140dfSLino Sanfilippo slic_free_shmem(sdev); 170960c140dfSLino Sanfilippo 171060c140dfSLino Sanfilippo return err; 171160c140dfSLino Sanfilippo } 171260c140dfSLino Sanfilippo 171360c140dfSLino Sanfilippo static bool slic_is_fiber(unsigned short subdev) 171460c140dfSLino Sanfilippo { 171560c140dfSLino Sanfilippo switch (subdev) { 171660c140dfSLino Sanfilippo /* Mojave */ 171760c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_1000X1F: /* fallthrough */ 171860c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_SES1001F: /* fallthrough */ 171960c140dfSLino Sanfilippo /* Oasis */ 172060c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_SEN2002XF: /* fallthrough */ 172160c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_SEN2001XF: /* fallthrough */ 172260c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_SEN2104EF: /* fallthrough */ 172360c140dfSLino Sanfilippo case PCI_SUBDEVICE_ID_ALACRITECH_SEN2102EF: /* fallthrough */ 172460c140dfSLino Sanfilippo return true; 172560c140dfSLino Sanfilippo } 172660c140dfSLino Sanfilippo return false; 172760c140dfSLino Sanfilippo } 172860c140dfSLino Sanfilippo 172960c140dfSLino Sanfilippo static void slic_configure_pci(struct pci_dev *pdev) 173060c140dfSLino Sanfilippo { 173160c140dfSLino Sanfilippo u16 old; 173260c140dfSLino Sanfilippo u16 cmd; 173360c140dfSLino Sanfilippo 173460c140dfSLino Sanfilippo pci_read_config_word(pdev, PCI_COMMAND, &old); 173560c140dfSLino Sanfilippo 173660c140dfSLino Sanfilippo cmd = old | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; 173760c140dfSLino Sanfilippo if (old != cmd) 173860c140dfSLino Sanfilippo pci_write_config_word(pdev, PCI_COMMAND, cmd); 173960c140dfSLino Sanfilippo } 174060c140dfSLino Sanfilippo 174160c140dfSLino Sanfilippo static int slic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 174260c140dfSLino Sanfilippo { 174360c140dfSLino Sanfilippo struct slic_device *sdev; 174460c140dfSLino Sanfilippo struct net_device *dev; 174560c140dfSLino Sanfilippo int err; 174660c140dfSLino Sanfilippo 174760c140dfSLino Sanfilippo err = pci_enable_device(pdev); 174860c140dfSLino Sanfilippo if (err) { 174960c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to enable PCI device\n"); 175060c140dfSLino Sanfilippo return err; 175160c140dfSLino Sanfilippo } 175260c140dfSLino Sanfilippo 175360c140dfSLino Sanfilippo pci_set_master(pdev); 175460c140dfSLino Sanfilippo pci_try_set_mwi(pdev); 175560c140dfSLino Sanfilippo 175660c140dfSLino Sanfilippo slic_configure_pci(pdev); 175760c140dfSLino Sanfilippo 175860c140dfSLino Sanfilippo err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 175960c140dfSLino Sanfilippo if (err) { 176060c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to setup DMA\n"); 176160c140dfSLino Sanfilippo goto disable; 176260c140dfSLino Sanfilippo } 176360c140dfSLino Sanfilippo 176460c140dfSLino Sanfilippo dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 176560c140dfSLino Sanfilippo 176660c140dfSLino Sanfilippo err = pci_request_regions(pdev, DRV_NAME); 176760c140dfSLino Sanfilippo if (err) { 176860c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to obtain PCI regions\n"); 176960c140dfSLino Sanfilippo goto disable; 177060c140dfSLino Sanfilippo } 177160c140dfSLino Sanfilippo 177260c140dfSLino Sanfilippo dev = alloc_etherdev(sizeof(*sdev)); 177360c140dfSLino Sanfilippo if (!dev) { 177460c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to alloc ethernet device\n"); 177560c140dfSLino Sanfilippo err = -ENOMEM; 177660c140dfSLino Sanfilippo goto free_regions; 177760c140dfSLino Sanfilippo } 177860c140dfSLino Sanfilippo 177960c140dfSLino Sanfilippo SET_NETDEV_DEV(dev, &pdev->dev); 178060c140dfSLino Sanfilippo pci_set_drvdata(pdev, dev); 178160c140dfSLino Sanfilippo dev->irq = pdev->irq; 178260c140dfSLino Sanfilippo dev->netdev_ops = &slic_netdev_ops; 178360c140dfSLino Sanfilippo dev->hw_features = NETIF_F_RXCSUM; 178460c140dfSLino Sanfilippo dev->features |= dev->hw_features; 178560c140dfSLino Sanfilippo 178660c140dfSLino Sanfilippo dev->ethtool_ops = &slic_ethtool_ops; 178760c140dfSLino Sanfilippo 178860c140dfSLino Sanfilippo sdev = netdev_priv(dev); 178960c140dfSLino Sanfilippo sdev->model = (pdev->device == PCI_DEVICE_ID_ALACRITECH_OASIS) ? 179060c140dfSLino Sanfilippo SLIC_MODEL_OASIS : SLIC_MODEL_MOJAVE; 179160c140dfSLino Sanfilippo sdev->is_fiber = slic_is_fiber(pdev->subsystem_device); 179260c140dfSLino Sanfilippo sdev->pdev = pdev; 179360c140dfSLino Sanfilippo sdev->netdev = dev; 1794*4bdc0d67SChristoph Hellwig sdev->regs = ioremap(pci_resource_start(pdev, 0), 179560c140dfSLino Sanfilippo pci_resource_len(pdev, 0)); 179660c140dfSLino Sanfilippo if (!sdev->regs) { 179760c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to map registers\n"); 179860c140dfSLino Sanfilippo err = -ENOMEM; 179960c140dfSLino Sanfilippo goto free_netdev; 180060c140dfSLino Sanfilippo } 180160c140dfSLino Sanfilippo 180260c140dfSLino Sanfilippo err = slic_init(sdev); 180360c140dfSLino Sanfilippo if (err) { 180460c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to initialize driver\n"); 180560c140dfSLino Sanfilippo goto unmap; 180660c140dfSLino Sanfilippo } 180760c140dfSLino Sanfilippo 180860c140dfSLino Sanfilippo netif_napi_add(dev, &sdev->napi, slic_poll, SLIC_NAPI_WEIGHT); 180960c140dfSLino Sanfilippo netif_carrier_off(dev); 181060c140dfSLino Sanfilippo 181160c140dfSLino Sanfilippo err = register_netdev(dev); 181260c140dfSLino Sanfilippo if (err) { 181360c140dfSLino Sanfilippo dev_err(&pdev->dev, "failed to register net device: %i\n", err); 181460c140dfSLino Sanfilippo goto unmap; 181560c140dfSLino Sanfilippo } 181660c140dfSLino Sanfilippo 181760c140dfSLino Sanfilippo return 0; 181860c140dfSLino Sanfilippo 181960c140dfSLino Sanfilippo unmap: 182060c140dfSLino Sanfilippo iounmap(sdev->regs); 182160c140dfSLino Sanfilippo free_netdev: 182260c140dfSLino Sanfilippo free_netdev(dev); 182360c140dfSLino Sanfilippo free_regions: 182460c140dfSLino Sanfilippo pci_release_regions(pdev); 182560c140dfSLino Sanfilippo disable: 182660c140dfSLino Sanfilippo pci_disable_device(pdev); 182760c140dfSLino Sanfilippo 182860c140dfSLino Sanfilippo return err; 182960c140dfSLino Sanfilippo } 183060c140dfSLino Sanfilippo 183160c140dfSLino Sanfilippo static void slic_remove(struct pci_dev *pdev) 183260c140dfSLino Sanfilippo { 183360c140dfSLino Sanfilippo struct net_device *dev = pci_get_drvdata(pdev); 183460c140dfSLino Sanfilippo struct slic_device *sdev = netdev_priv(dev); 183560c140dfSLino Sanfilippo 183660c140dfSLino Sanfilippo unregister_netdev(dev); 183760c140dfSLino Sanfilippo iounmap(sdev->regs); 183860c140dfSLino Sanfilippo free_netdev(dev); 183960c140dfSLino Sanfilippo pci_release_regions(pdev); 184060c140dfSLino Sanfilippo pci_disable_device(pdev); 184160c140dfSLino Sanfilippo } 184260c140dfSLino Sanfilippo 184360c140dfSLino Sanfilippo static struct pci_driver slic_driver = { 184460c140dfSLino Sanfilippo .name = DRV_NAME, 184560c140dfSLino Sanfilippo .id_table = slic_id_tbl, 184660c140dfSLino Sanfilippo .probe = slic_probe, 184760c140dfSLino Sanfilippo .remove = slic_remove, 184860c140dfSLino Sanfilippo }; 184960c140dfSLino Sanfilippo 18503f0dd6b7STobias Klauser module_pci_driver(slic_driver); 185160c140dfSLino Sanfilippo 185260c140dfSLino Sanfilippo MODULE_DESCRIPTION("Alacritech non-accelerated SLIC driver"); 185360c140dfSLino Sanfilippo MODULE_AUTHOR("Lino Sanfilippo <LinoSanfilippo@gmx.de>"); 185460c140dfSLino Sanfilippo MODULE_LICENSE("GPL"); 185560c140dfSLino Sanfilippo MODULE_VERSION(DRV_VERSION); 1856