From bcc9736c6c201b0992c9d0a5b5a30c35138e5782 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Date: Sat, 11 Jun 2011 03:26:31 -0700 Subject: ks8*/ksz8*: Move the Micrel drivers Move the Micrel drivers into drivers/net/ethernet/micrel/ and make the necessary Kconfig and Makefile changes. CC: Ben Dooks <ben@simtec.co.uk> CC: Tristram Ha <Tristram.Ha@micrel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> --- drivers/net/ethernet/micrel/Kconfig | 64 + drivers/net/ethernet/micrel/Makefile | 9 + drivers/net/ethernet/micrel/ks8695net.c | 1656 +++++++ drivers/net/ethernet/micrel/ks8695net.h | 107 + drivers/net/ethernet/micrel/ks8842.c | 1284 ++++++ drivers/net/ethernet/micrel/ks8851.c | 1737 +++++++ drivers/net/ethernet/micrel/ks8851.h | 309 ++ drivers/net/ethernet/micrel/ks8851_mll.c | 1680 +++++++ drivers/net/ethernet/micrel/ksz884x.c | 7289 ++++++++++++++++++++++++++++++ 9 files changed, 14135 insertions(+) create mode 100644 drivers/net/ethernet/micrel/Kconfig create mode 100644 drivers/net/ethernet/micrel/Makefile create mode 100644 drivers/net/ethernet/micrel/ks8695net.c create mode 100644 drivers/net/ethernet/micrel/ks8695net.h create mode 100644 drivers/net/ethernet/micrel/ks8842.c create mode 100644 drivers/net/ethernet/micrel/ks8851.c create mode 100644 drivers/net/ethernet/micrel/ks8851.h create mode 100644 drivers/net/ethernet/micrel/ks8851_mll.c create mode 100644 drivers/net/ethernet/micrel/ksz884x.c (limited to 'drivers/net/ethernet/micrel') diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig new file mode 100644 index 000000000000..4227de6d11f2 --- /dev/null +++ b/drivers/net/ethernet/micrel/Kconfig @@ -0,0 +1,64 @@ +# +# Micrel device configuration +# + +config NET_VENDOR_MICREL + bool "Micrel devices" + depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \ + (ARM && ARCH_KS8695) + ---help--- + If you have a network (Ethernet) card belonging to this class, say Y + and read the Ethernet-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about Micrel devices. If you say Y, you will be asked + for your specific card in the following questions. + +if NET_VENDOR_MICREL + +config ARM_KS8695_ETHER + tristate "KS8695 Ethernet support" + depends on ARM && ARCH_KS8695 + select MII + ---help--- + If you wish to compile a kernel for the KS8695 and want to + use the internal ethernet then you should answer Y to this. + +config KS8842 + tristate "Micrel KSZ8841/42 with generic bus interface" + depends on HAS_IOMEM && DMA_ENGINE + ---help--- + This platform driver is for KSZ8841(1-port) / KS8842(2-port) + ethernet switch chip (managed, VLAN, QoS) from Micrel or + Timberdale(FPGA). + +config KS8851 + tristate "Micrel KS8851 SPI" + depends on SPI + select MII + select CRC32 + ---help--- + SPI driver for Micrel KS8851 SPI attached network chip. + +config KS8851_MLL + tristate "Micrel KS8851 MLL" + depends on HAS_IOMEM + select MII + ---help--- + This platform driver is for Micrel KS8851 Address/data bus + multiplexed network chip. + +config KSZ884X_PCI + tristate "Micrel KSZ8841/2 PCI" + depends on PCI + select MII + select CRC32 + ---help--- + This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip. + + To compile this driver as a module, choose M here. The module + will be called ksz884x. + +endif # NET_VENDOR_MICREL diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile new file mode 100644 index 000000000000..c83e4bc50c73 --- /dev/null +++ b/drivers/net/ethernet/micrel/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the Micrel network device drivers. +# + +obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o +obj-$(CONFIG_KS8842) += ks8842.o +obj-$(CONFIG_KS8851) += ks8851.o +obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o +obj-$(CONFIG_KSZ884X_PCI) += ksz884x.o diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c new file mode 100644 index 000000000000..c827a6097d02 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -0,0 +1,1656 @@ +/* + * Micrel KS8695 (Centaur) Ethernet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Copyright 2008 Simtec Electronics + * Daniel Silverstone <dsilvers@simtec.co.uk> + * Vincent Sanders <vince@simtec.co.uk> + */ + +#include <linux/dma-mapping.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> +#include <linux/crc32.h> +#include <linux/mii.h> +#include <linux/ethtool.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/slab.h> + +#include <asm/irq.h> + +#include <mach/regs-switch.h> +#include <mach/regs-misc.h> +#include <asm/mach/irq.h> +#include <mach/regs-irq.h> + +#include "ks8695net.h" + +#define MODULENAME "ks8695_ether" +#define MODULEVERSION "1.02" + +/* + * Transmit and device reset timeout, default 5 seconds. + */ +static int watchdog = 5000; + +/* Hardware structures */ + +/** + * struct rx_ring_desc - Receive descriptor ring element + * @status: The status of the descriptor element (E.g. who owns it) + * @length: The number of bytes in the block pointed to by data_ptr + * @data_ptr: The physical address of the data block to receive into + * @next_desc: The physical address of the next descriptor element. + */ +struct rx_ring_desc { + __le32 status; + __le32 length; + __le32 data_ptr; + __le32 next_desc; +}; + +/** + * struct tx_ring_desc - Transmit descriptor ring element + * @owner: Who owns the descriptor + * @status: The number of bytes in the block pointed to by data_ptr + * @data_ptr: The physical address of the data block to receive into + * @next_desc: The physical address of the next descriptor element. + */ +struct tx_ring_desc { + __le32 owner; + __le32 status; + __le32 data_ptr; + __le32 next_desc; +}; + +/** + * struct ks8695_skbuff - sk_buff wrapper for rx/tx rings. + * @skb: The buffer in the ring + * @dma_ptr: The mapped DMA pointer of the buffer + * @length: The number of bytes mapped to dma_ptr + */ +struct ks8695_skbuff { + struct sk_buff *skb; + dma_addr_t dma_ptr; + u32 length; +}; + +/* Private device structure */ + +#define MAX_TX_DESC 8 +#define MAX_TX_DESC_MASK 0x7 +#define MAX_RX_DESC 16 +#define MAX_RX_DESC_MASK 0xf + +/*napi_weight have better more than rx DMA buffers*/ +#define NAPI_WEIGHT 64 + +#define MAX_RXBUF_SIZE 0x700 + +#define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC) +#define RX_RING_DMA_SIZE (sizeof(struct rx_ring_desc) * MAX_RX_DESC) +#define RING_DMA_SIZE (TX_RING_DMA_SIZE + RX_RING_DMA_SIZE) + +/** + * enum ks8695_dtype - Device type + * @KS8695_DTYPE_WAN: This device is a WAN interface + * @KS8695_DTYPE_LAN: This device is a LAN interface + * @KS8695_DTYPE_HPNA: This device is an HPNA interface + */ +enum ks8695_dtype { + KS8695_DTYPE_WAN, + KS8695_DTYPE_LAN, + KS8695_DTYPE_HPNA, +}; + +/** + * struct ks8695_priv - Private data for the KS8695 Ethernet + * @in_suspend: Flag to indicate if we're suspending/resuming + * @ndev: The net_device for this interface + * @dev: The platform device object for this interface + * @dtype: The type of this device + * @io_regs: The ioremapped registers for this interface + * @napi : Add support NAPI for Rx + * @rx_irq_name: The textual name of the RX IRQ from the platform data + * @tx_irq_name: The textual name of the TX IRQ from the platform data + * @link_irq_name: The textual name of the link IRQ from the + * platform data if available + * @rx_irq: The IRQ number for the RX IRQ + * @tx_irq: The IRQ number for the TX IRQ + * @link_irq: The IRQ number for the link IRQ if available + * @regs_req: The resource request for the registers region + * @phyiface_req: The resource request for the phy/switch region + * if available + * @phyiface_regs: The ioremapped registers for the phy/switch if available + * @ring_base: The base pointer of the dma coherent memory for the rings + * @ring_base_dma: The DMA mapped equivalent of ring_base + * @tx_ring: The pointer in ring_base of the TX ring + * @tx_ring_used: The number of slots in the TX ring which are occupied + * @tx_ring_next_slot: The next slot to fill in the TX ring + * @tx_ring_dma: The DMA mapped equivalent of tx_ring + * @tx_buffers: The sk_buff mappings for the TX ring + * @txq_lock: A lock to protect the tx_buffers tx_ring_used etc variables + * @rx_ring: The pointer in ring_base of the RX ring + * @rx_ring_dma: The DMA mapped equivalent of rx_ring + * @rx_buffers: The sk_buff mappings for the RX ring + * @next_rx_desc_read: The next RX descriptor to read from on IRQ + * @rx_lock: A lock to protect Rx irq function + * @msg_enable: The flags for which messages to emit + */ +struct ks8695_priv { + int in_suspend; + struct net_device *ndev; + struct device *dev; + enum ks8695_dtype dtype; + void __iomem *io_regs; + + struct napi_struct napi; + + const char *rx_irq_name, *tx_irq_name, *link_irq_name; + int rx_irq, tx_irq, link_irq; + + struct resource *regs_req, *phyiface_req; + void __iomem *phyiface_regs; + + void *ring_base; + dma_addr_t ring_base_dma; + + struct tx_ring_desc *tx_ring; + int tx_ring_used; + int tx_ring_next_slot; + dma_addr_t tx_ring_dma; + struct ks8695_skbuff tx_buffers[MAX_TX_DESC]; + spinlock_t txq_lock; + + struct rx_ring_desc *rx_ring; + dma_addr_t rx_ring_dma; + struct ks8695_skbuff rx_buffers[MAX_RX_DESC]; + int next_rx_desc_read; + spinlock_t rx_lock; + + int msg_enable; +}; + +/* Register access */ + +/** + * ks8695_readreg - Read from a KS8695 ethernet register + * @ksp: The device to read from + * @reg: The register to read + */ +static inline u32 +ks8695_readreg(struct ks8695_priv *ksp, int reg) +{ + return readl(ksp->io_regs + reg); +} + +/** + * ks8695_writereg - Write to a KS8695 ethernet register + * @ksp: The device to write to + * @reg: The register to write + * @value: The value to write to the register + */ +static inline void +ks8695_writereg(struct ks8695_priv *ksp, int reg, u32 value) +{ + writel(value, ksp->io_regs + reg); +} + +/* Utility functions */ + +/** + * ks8695_port_type - Retrieve port-type as user-friendly string + * @ksp: The device to return the type for + * + * Returns a string indicating which of the WAN, LAN or HPNA + * ports this device is likely to represent. + */ +static const char * +ks8695_port_type(struct ks8695_priv *ksp) +{ + switch (ksp->dtype) { + case KS8695_DTYPE_LAN: + return "LAN"; + case KS8695_DTYPE_WAN: + return "WAN"; + case KS8695_DTYPE_HPNA: + return "HPNA"; + } + + return "UNKNOWN"; +} + +/** + * ks8695_update_mac - Update the MAC registers in the device + * @ksp: The device to update + * + * Updates the MAC registers in the KS8695 device from the address in the + * net_device structure associated with this interface. + */ +static void +ks8695_update_mac(struct ks8695_priv *ksp) +{ + /* Update the HW with the MAC from the net_device */ + struct net_device *ndev = ksp->ndev; + u32 machigh, maclow; + + maclow = ((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) | + (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5] << 0)); + machigh = ((ndev->dev_addr[0] << 8) | (ndev->dev_addr[1] << 0)); + + ks8695_writereg(ksp, KS8695_MAL, maclow); + ks8695_writereg(ksp, KS8695_MAH, machigh); + +} + +/** + * ks8695_refill_rxbuffers - Re-fill the RX buffer ring + * @ksp: The device to refill + * + * Iterates the RX ring of the device looking for empty slots. + * For each empty slot, we allocate and map a new SKB and give it + * to the hardware. + * This can be called from interrupt context safely. + */ +static void +ks8695_refill_rxbuffers(struct ks8695_priv *ksp) +{ + /* Run around the RX ring, filling in any missing sk_buff's */ + int buff_n; + + for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) { + if (!ksp->rx_buffers[buff_n].skb) { + struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE); + dma_addr_t mapping; + + ksp->rx_buffers[buff_n].skb = skb; + if (skb == NULL) { + /* Failed to allocate one, perhaps + * we'll try again later. + */ + break; + } + + mapping = dma_map_single(ksp->dev, skb->data, + MAX_RXBUF_SIZE, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(ksp->dev, mapping))) { + /* Failed to DMA map this SKB, try later */ + dev_kfree_skb_irq(skb); + ksp->rx_buffers[buff_n].skb = NULL; + break; + } + ksp->rx_buffers[buff_n].dma_ptr = mapping; + skb->dev = ksp->ndev; + ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE; + + /* Record this into the DMA ring */ + ksp->rx_ring[buff_n].data_ptr = cpu_to_le32(mapping); + ksp->rx_ring[buff_n].length = + cpu_to_le32(MAX_RXBUF_SIZE); + + wmb(); + + /* And give ownership over to the hardware */ + ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); + } + } +} + +/* Maximum number of multicast addresses which the KS8695 HW supports */ +#define KS8695_NR_ADDRESSES 16 + +/** + * ks8695_init_partial_multicast - Init the mcast addr registers + * @ksp: The device to initialise + * @addr: The multicast address list to use + * @nr_addr: The number of addresses in the list + * + * This routine is a helper for ks8695_set_multicast - it writes + * the additional-address registers in the KS8695 ethernet device + * and cleans up any others left behind. + */ +static void +ks8695_init_partial_multicast(struct ks8695_priv *ksp, + struct net_device *ndev) +{ + u32 low, high; + int i; + struct netdev_hw_addr *ha; + + i = 0; + netdev_for_each_mc_addr(ha, ndev) { + /* Ran out of space in chip? */ + BUG_ON(i == KS8695_NR_ADDRESSES); + + low = (ha->addr[2] << 24) | (ha->addr[3] << 16) | + (ha->addr[4] << 8) | (ha->addr[5]); + high = (ha->addr[0] << 8) | (ha->addr[1]); + + ks8695_writereg(ksp, KS8695_AAL_(i), low); + ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high); + i++; + } + + /* Clear the remaining Additional Station Addresses */ + for (; i < KS8695_NR_ADDRESSES; i++) { + ks8695_writereg(ksp, KS8695_AAL_(i), 0); + ks8695_writereg(ksp, KS8695_AAH_(i), 0); + } +} + +/* Interrupt handling */ + +/** + * ks8695_tx_irq - Transmit IRQ handler + * @irq: The IRQ which went off (ignored) + * @dev_id: The net_device for the interrupt + * + * Process the TX ring, clearing out any transmitted slots. + * Allows the net_device to pass us new packets once slots are + * freed. + */ +static irqreturn_t +ks8695_tx_irq(int irq, void *dev_id) +{ + struct net_device *ndev = (struct net_device *)dev_id; + struct ks8695_priv *ksp = netdev_priv(ndev); + int buff_n; + + for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) { + if (ksp->tx_buffers[buff_n].skb && + !(ksp->tx_ring[buff_n].owner & cpu_to_le32(TDES_OWN))) { + rmb(); + /* An SKB which is not owned by HW is present */ + /* Update the stats for the net_device */ + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += ksp->tx_buffers[buff_n].length; + + /* Free the packet from the ring */ + ksp->tx_ring[buff_n].data_ptr = 0; + + /* Free the sk_buff */ + dma_unmap_single(ksp->dev, + ksp->tx_buffers[buff_n].dma_ptr, + ksp->tx_buffers[buff_n].length, + DMA_TO_DEVICE); + dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb); + ksp->tx_buffers[buff_n].skb = NULL; + ksp->tx_ring_used--; + } + } + + netif_wake_queue(ndev); + + return IRQ_HANDLED; +} + +/** + * ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit + * @ksp: Private data for the KS8695 Ethernet + * + * For KS8695 document: + * Interrupt Enable Register (offset 0xE204) + * Bit29 : WAN MAC Receive Interrupt Enable + * Bit16 : LAN MAC Receive Interrupt Enable + * Interrupt Status Register (Offset 0xF208) + * Bit29: WAN MAC Receive Status + * Bit16: LAN MAC Receive Status + * So, this Rx interrrupt enable/status bit number is equal + * as Rx IRQ number. + */ +static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp) +{ + return ksp->rx_irq; +} + +/** + * ks8695_rx_irq - Receive IRQ handler + * @irq: The IRQ which went off (ignored) + * @dev_id: The net_device for the interrupt + * + * Inform NAPI that packet reception needs to be scheduled + */ + +static irqreturn_t +ks8695_rx_irq(int irq, void *dev_id) +{ + struct net_device *ndev = (struct net_device *)dev_id; + struct ks8695_priv *ksp = netdev_priv(ndev); + + spin_lock(&ksp->rx_lock); + + if (napi_schedule_prep(&ksp->napi)) { + unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN); + unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp); + /*disable rx interrupt*/ + status &= ~mask_bit; + writel(status , KS8695_IRQ_VA + KS8695_INTEN); + __napi_schedule(&ksp->napi); + } + + spin_unlock(&ksp->rx_lock); + return IRQ_HANDLED; +} + +/** + * ks8695_rx - Receive packets called by NAPI poll method + * @ksp: Private data for the KS8695 Ethernet + * @budget: Number of packets allowed to process + */ +static int ks8695_rx(struct ks8695_priv *ksp, int budget) +{ + struct net_device *ndev = ksp->ndev; + struct sk_buff *skb; + int buff_n; + u32 flags; + int pktlen; + int received = 0; + + buff_n = ksp->next_rx_desc_read; + while (received < budget + && ksp->rx_buffers[buff_n].skb + && (!(ksp->rx_ring[buff_n].status & + cpu_to_le32(RDES_OWN)))) { + rmb(); + flags = le32_to_cpu(ksp->rx_ring[buff_n].status); + + /* Found an SKB which we own, this means we + * received a packet + */ + if ((flags & (RDES_FS | RDES_LS)) != + (RDES_FS | RDES_LS)) { + /* This packet is not the first and + * the last segment. Therefore it is + * a "spanning" packet and we can't + * handle it + */ + goto rx_failure; + } + + if (flags & (RDES_ES | RDES_RE)) { + /* It's an error packet */ + ndev->stats.rx_errors++; + if (flags & RDES_TL) + ndev->stats.rx_length_errors++; + if (flags & RDES_RF) + ndev->stats.rx_length_errors++; + if (flags & RDES_CE) + ndev->stats.rx_crc_errors++; + if (flags & RDES_RE) + ndev->stats.rx_missed_errors++; + + goto rx_failure; + } + + pktlen = flags & RDES_FLEN; + pktlen -= 4; /* Drop the CRC */ + + /* Retrieve the sk_buff */ + skb = ksp->rx_buffers[buff_n].skb; + + /* Clear it from the ring */ + ksp->rx_buffers[buff_n].skb = NULL; + ksp->rx_ring[buff_n].data_ptr = 0; + + /* Unmap the SKB */ + dma_unmap_single(ksp->dev, + ksp->rx_buffers[buff_n].dma_ptr, + ksp->rx_buffers[buff_n].length, + DMA_FROM_DEVICE); + + /* Relinquish the SKB to the network layer */ + skb_put(skb, pktlen); + skb->protocol = eth_type_trans(skb, ndev); + netif_receive_skb(skb); + + /* Record stats */ + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += pktlen; + goto rx_finished; + +rx_failure: + /* This ring entry is an error, but we can + * re-use the skb + */ + /* Give the ring entry back to the hardware */ + ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); +rx_finished: + received++; + buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; + } + + /* And note which RX descriptor we last did */ + ksp->next_rx_desc_read = buff_n; + + /* And refill the buffers */ + ks8695_refill_rxbuffers(ksp); + + /* Kick the RX DMA engine, in case it became suspended */ + ks8695_writereg(ksp, KS8695_DRSC, 0); + + return received; +} + + +/** + * ks8695_poll - Receive packet by NAPI poll method + * @ksp: Private data for the KS8695 Ethernet + * @budget: The remaining number packets for network subsystem + * + * Invoked by the network core when it requests for new + * packets from the driver + */ +static int ks8695_poll(struct napi_struct *napi, int budget) +{ + struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi); + unsigned long work_done; + + unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN); + unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp); + + work_done = ks8695_rx(ksp, budget); + + if (work_done < budget) { + unsigned long flags; + spin_lock_irqsave(&ksp->rx_lock, flags); + __napi_complete(napi); + /*enable rx interrupt*/ + writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); + spin_unlock_irqrestore(&ksp->rx_lock, flags); + } + return work_done; +} + +/** + * ks8695_link_irq - Link change IRQ handler + * @irq: The IRQ which went off (ignored) + * @dev_id: The net_device for the interrupt + * + * The WAN interface can generate an IRQ when the link changes, + * report this to the net layer and the user. + */ +static irqreturn_t +ks8695_link_irq(int irq, void *dev_id) +{ + struct net_device *ndev = (struct net_device *)dev_id; + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + if (ctrl & WMC_WLS) { + netif_carrier_on(ndev); + if (netif_msg_link(ksp)) + dev_info(ksp->dev, + "%s: Link is now up (10%sMbps/%s-duplex)\n", + ndev->name, + (ctrl & WMC_WSS) ? "0" : "", + (ctrl & WMC_WDS) ? "Full" : "Half"); + } else { + netif_carrier_off(ndev); + if (netif_msg_link(ksp)) + dev_info(ksp->dev, "%s: Link is now down.\n", + ndev->name); + } + + return IRQ_HANDLED; +} + + +/* KS8695 Device functions */ + +/** + * ks8695_reset - Reset a KS8695 ethernet interface + * @ksp: The interface to reset + * + * Perform an engine reset of the interface and re-program it + * with sensible defaults. + */ +static void +ks8695_reset(struct ks8695_priv *ksp) +{ + int reset_timeout = watchdog; + /* Issue the reset via the TX DMA control register */ + ks8695_writereg(ksp, KS8695_DTXC, DTXC_TRST); + while (reset_timeout--) { + if (!(ks8695_readreg(ksp, KS8695_DTXC) & DTXC_TRST)) + break; + msleep(1); + } + + if (reset_timeout < 0) { + dev_crit(ksp->dev, + "Timeout waiting for DMA engines to reset\n"); + /* And blithely carry on */ + } + + /* Definitely wait long enough before attempting to program + * the engines + */ + msleep(10); + + /* RX: unicast and broadcast */ + ks8695_writereg(ksp, KS8695_DRXC, DRXC_RU | DRXC_RB); + /* TX: pad and add CRC */ + ks8695_writereg(ksp, KS8695_DTXC, DTXC_TEP | DTXC_TAC); +} + +/** + * ks8695_shutdown - Shut down a KS8695 ethernet interface + * @ksp: The interface to shut down + * + * This disables packet RX/TX, cleans up IRQs, drains the rings, + * and basically places the interface into a clean shutdown + * state. + */ +static void +ks8695_shutdown(struct ks8695_priv *ksp) +{ + u32 ctrl; + int buff_n; + + /* Disable packet transmission */ + ctrl = ks8695_readreg(ksp, KS8695_DTXC); + ks8695_writereg(ksp, KS8695_DTXC, ctrl & ~DTXC_TE); + + /* Disable packet reception */ + ctrl = ks8695_readreg(ksp, KS8695_DRXC); + ks8695_writereg(ksp, KS8695_DRXC, ctrl & ~DRXC_RE); + + /* Release the IRQs */ + free_irq(ksp->rx_irq, ksp->ndev); + free_irq(ksp->tx_irq, ksp->ndev); + if (ksp->link_irq != -1) + free_irq(ksp->link_irq, ksp->ndev); + + /* Throw away any pending TX packets */ + for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) { + if (ksp->tx_buffers[buff_n].skb) { + /* Remove this SKB from the TX ring */ + ksp->tx_ring[buff_n].owner = 0; + ksp->tx_ring[buff_n].status = 0; + ksp->tx_ring[buff_n].data_ptr = 0; + + /* Unmap and bin this SKB */ + dma_unmap_single(ksp->dev, + ksp->tx_buffers[buff_n].dma_ptr, + ksp->tx_buffers[buff_n].length, + DMA_TO_DEVICE); + dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb); + ksp->tx_buffers[buff_n].skb = NULL; + } + } + + /* Purge the RX buffers */ + for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) { + if (ksp->rx_buffers[buff_n].skb) { + /* Remove the SKB from the RX ring */ + ksp->rx_ring[buff_n].status = 0; + ksp->rx_ring[buff_n].data_ptr = 0; + + /* Unmap and bin the SKB */ + dma_unmap_single(ksp->dev, + ksp->rx_buffers[buff_n].dma_ptr, + ksp->rx_buffers[buff_n].length, + DMA_FROM_DEVICE); + dev_kfree_skb_irq(ksp->rx_buffers[buff_n].skb); + ksp->rx_buffers[buff_n].skb = NULL; + } + } +} + + +/** + * ks8695_setup_irq - IRQ setup helper function + * @irq: The IRQ number to claim + * @irq_name: The name to give the IRQ claimant + * @handler: The function to call to handle the IRQ + * @ndev: The net_device to pass in as the dev_id argument to the handler + * + * Return 0 on success. + */ +static int +ks8695_setup_irq(int irq, const char *irq_name, + irq_handler_t handler, struct net_device *ndev) +{ + int ret; + + ret = request_irq(irq, handler, IRQF_SHARED, irq_name, ndev); + + if (ret) { + dev_err(&ndev->dev, "failure to request IRQ %d\n", irq); + return ret; + } + + return 0; +} + +/** + * ks8695_init_net - Initialise a KS8695 ethernet interface + * @ksp: The interface to initialise + * + * This routine fills the RX ring, initialises the DMA engines, + * allocates the IRQs and then starts the packet TX and RX + * engines. + */ +static int +ks8695_init_net(struct ks8695_priv *ksp) +{ + int ret; + u32 ctrl; + + ks8695_refill_rxbuffers(ksp); + + /* Initialise the DMA engines */ + ks8695_writereg(ksp, KS8695_RDLB, (u32) ksp->rx_ring_dma); + ks8695_writereg(ksp, KS8695_TDLB, (u32) ksp->tx_ring_dma); + + /* Request the IRQs */ + ret = ks8695_setup_irq(ksp->rx_irq, ksp->rx_irq_name, + ks8695_rx_irq, ksp->ndev); + if (ret) + return ret; + ret = ks8695_setup_irq(ksp->tx_irq, ksp->tx_irq_name, + ks8695_tx_irq, ksp->ndev); + if (ret) + return ret; + if (ksp->link_irq != -1) { + ret = ks8695_setup_irq(ksp->link_irq, ksp->link_irq_name, + ks8695_link_irq, ksp->ndev); + if (ret) + return ret; + } + + /* Set up the ring indices */ + ksp->next_rx_desc_read = 0; + ksp->tx_ring_next_slot = 0; + ksp->tx_ring_used = 0; + + /* Bring up transmission */ + ctrl = ks8695_readreg(ksp, KS8695_DTXC); + /* Enable packet transmission */ + ks8695_writereg(ksp, KS8695_DTXC, ctrl | DTXC_TE); + + /* Bring up the reception */ + ctrl = ks8695_readreg(ksp, KS8695_DRXC); + /* Enable packet reception */ + ks8695_writereg(ksp, KS8695_DRXC, ctrl | DRXC_RE); + /* And start the DMA engine */ + ks8695_writereg(ksp, KS8695_DRSC, 0); + + /* All done */ + return 0; +} + +/** + * ks8695_release_device - HW resource release for KS8695 e-net + * @ksp: The device to be freed + * + * This unallocates io memory regions, dma-coherent regions etc + * which were allocated in ks8695_probe. + */ +static void +ks8695_release_device(struct ks8695_priv *ksp) +{ + /* Unmap the registers */ + iounmap(ksp->io_regs); + if (ksp->phyiface_regs) + iounmap(ksp->phyiface_regs); + + /* And release the request */ + release_resource(ksp->regs_req); + kfree(ksp->regs_req); + if (ksp->phyiface_req) { + release_resource(ksp->phyiface_req); + kfree(ksp->phyiface_req); + } + + /* Free the ring buffers */ + dma_free_coherent(ksp->dev, RING_DMA_SIZE, + ksp->ring_base, ksp->ring_base_dma); +} + +/* Ethtool support */ + +/** + * ks8695_get_msglevel - Get the messages enabled for emission + * @ndev: The network device to read from + */ +static u32 +ks8695_get_msglevel(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + + return ksp->msg_enable; +} + +/** + * ks8695_set_msglevel - Set the messages enabled for emission + * @ndev: The network device to configure + * @value: The messages to set for emission + */ +static void +ks8695_set_msglevel(struct net_device *ndev, u32 value) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + + ksp->msg_enable = value; +} + +/** + * ks8695_wan_get_settings - Get device-specific settings. + * @ndev: The network device to read settings from + * @cmd: The ethtool structure to read into + */ +static int +ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + /* All ports on the KS8695 support these... */ + cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_TP | SUPPORTED_MII); + cmd->transceiver = XCVR_INTERNAL; + + cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; + cmd->port = PORT_MII; + cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); + cmd->phy_address = 0; + + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + if ((ctrl & WMC_WAND) == 0) { + /* auto-negotiation is enabled */ + cmd->advertising |= ADVERTISED_Autoneg; + if (ctrl & WMC_WANA100F) + cmd->advertising |= ADVERTISED_100baseT_Full; + if (ctrl & WMC_WANA100H) + cmd->advertising |= ADVERTISED_100baseT_Half; + if (ctrl & WMC_WANA10F) + cmd->advertising |= ADVERTISED_10baseT_Full; + if (ctrl & WMC_WANA10H) + cmd->advertising |= ADVERTISED_10baseT_Half; + if (ctrl & WMC_WANAP) + cmd->advertising |= ADVERTISED_Pause; + cmd->autoneg = AUTONEG_ENABLE; + + ethtool_cmd_speed_set(cmd, + (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10); + cmd->duplex = (ctrl & WMC_WDS) ? + DUPLEX_FULL : DUPLEX_HALF; + } else { + /* auto-negotiation is disabled */ + cmd->autoneg = AUTONEG_DISABLE; + + ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ? + SPEED_100 : SPEED_10)); + cmd->duplex = (ctrl & WMC_WANFF) ? + DUPLEX_FULL : DUPLEX_HALF; + } + + return 0; +} + +/** + * ks8695_wan_set_settings - Set device-specific settings. + * @ndev: The network device to configure + * @cmd: The settings to configure + */ +static int +ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + if ((cmd->speed != SPEED_10) && (cmd->speed != SPEED_100)) + return -EINVAL; + if ((cmd->duplex != DUPLEX_HALF) && (cmd->duplex != DUPLEX_FULL)) + return -EINVAL; + if (cmd->port != PORT_MII) + return -EINVAL; + if (cmd->transceiver != XCVR_INTERNAL) + return -EINVAL; + if ((cmd->autoneg != AUTONEG_DISABLE) && + (cmd->autoneg != AUTONEG_ENABLE)) + return -EINVAL; + + if (cmd->autoneg == AUTONEG_ENABLE) { + if ((cmd->advertising & (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full)) == 0) + return -EINVAL; + + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + + ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | + WMC_WANA10F | WMC_WANA10H); + if (cmd->advertising & ADVERTISED_100baseT_Full) + ctrl |= WMC_WANA100F; + if (cmd->advertising & ADVERTISED_100baseT_Half) + ctrl |= WMC_WANA100H; + if (cmd->advertising & ADVERTISED_10baseT_Full) + ctrl |= WMC_WANA10F; + if (cmd->advertising & ADVERTISED_10baseT_Half) + ctrl |= WMC_WANA10H; + + /* force a re-negotiation */ + ctrl |= WMC_WANR; + writel(ctrl, ksp->phyiface_regs + KS8695_WMC); + } else { + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + + /* disable auto-negotiation */ + ctrl |= WMC_WAND; + ctrl &= ~(WMC_WANF100 | WMC_WANFF); + + if (cmd->speed == SPEED_100) + ctrl |= WMC_WANF100; + if (cmd->duplex == DUPLEX_FULL) + ctrl |= WMC_WANFF; + + writel(ctrl, ksp->phyiface_regs + KS8695_WMC); + } + + return 0; +} + +/** + * ks8695_wan_nwayreset - Restart the autonegotiation on the port. + * @ndev: The network device to restart autoneotiation on + */ +static int +ks8695_wan_nwayreset(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + + if ((ctrl & WMC_WAND) == 0) + writel(ctrl | WMC_WANR, + ksp->phyiface_regs + KS8695_WMC); + else + /* auto-negotiation not enabled */ + return -EINVAL; + + return 0; +} + +/** + * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising + * @ndev: The device to retrieve settings from + * @param: The structure to fill out with the information + */ +static void +ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + ctrl = readl(ksp->phyiface_regs + KS8695_WMC); + + /* advertise Pause */ + param->autoneg = (ctrl & WMC_WANAP); + + /* current Rx Flow-control */ + ctrl = ks8695_readreg(ksp, KS8695_DRXC); + param->rx_pause = (ctrl & DRXC_RFCE); + + /* current Tx Flow-control */ + ctrl = ks8695_readreg(ksp, KS8695_DTXC); + param->tx_pause = (ctrl & DTXC_TFCE); +} + +/** + * ks8695_get_drvinfo - Retrieve driver information + * @ndev: The network device to retrieve info about + * @info: The info structure to fill out. + */ +static void +ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) +{ + strlcpy(info->driver, MODULENAME, sizeof(info->driver)); + strlcpy(info->version, MODULEVERSION, sizeof(info->version)); + strlcpy(info->bus_info, dev_name(ndev->dev.parent), + sizeof(info->bus_info)); +} + +static const struct ethtool_ops ks8695_ethtool_ops = { + .get_msglevel = ks8695_get_msglevel, + .set_msglevel = ks8695_set_msglevel, + .get_drvinfo = ks8695_get_drvinfo, +}; + +static const struct ethtool_ops ks8695_wan_ethtool_ops = { + .get_msglevel = ks8695_get_msglevel, + .set_msglevel = ks8695_set_msglevel, + .get_settings = ks8695_wan_get_settings, + .set_settings = ks8695_wan_set_settings, + .nway_reset = ks8695_wan_nwayreset, + .get_link = ethtool_op_get_link, + .get_pauseparam = ks8695_wan_get_pause, + .get_drvinfo = ks8695_get_drvinfo, +}; + +/* Network device interface functions */ + +/** + * ks8695_set_mac - Update MAC in net dev and HW + * @ndev: The network device to update + * @addr: The new MAC address to set + */ +static int +ks8695_set_mac(struct net_device *ndev, void *addr) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + struct sockaddr *address = addr; + + if (!is_valid_ether_addr(address->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len); + + ks8695_update_mac(ksp); + + dev_dbg(ksp->dev, "%s: Updated MAC address to %pM\n", + ndev->name, ndev->dev_addr); + + return 0; +} + +/** + * ks8695_set_multicast - Set up the multicast behaviour of the interface + * @ndev: The net_device to configure + * + * This routine, called by the net layer, configures promiscuity + * and multicast reception behaviour for the interface. + */ +static void +ks8695_set_multicast(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + u32 ctrl; + + ctrl = ks8695_readreg(ksp, KS8695_DRXC); + + if (ndev->flags & IFF_PROMISC) { + /* enable promiscuous mode */ + ctrl |= DRXC_RA; + } else if (ndev->flags & ~IFF_PROMISC) { + /* disable promiscuous mode */ + ctrl &= ~DRXC_RA; + } + + if (ndev->flags & IFF_ALLMULTI) { + /* enable all multicast mode */ + ctrl |= DRXC_RM; + } else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) { + /* more specific multicast addresses than can be + * handled in hardware + */ + ctrl |= DRXC_RM; + } else { + /* enable specific multicasts */ + ctrl &= ~DRXC_RM; + ks8695_init_partial_multicast(ksp, ndev); + } + + ks8695_writereg(ksp, KS8695_DRXC, ctrl); +} + +/** + * ks8695_timeout - Handle a network tx/rx timeout. + * @ndev: The net_device which timed out. + * + * A network transaction timed out, reset the device. + */ +static void +ks8695_timeout(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + + netif_stop_queue(ndev); + ks8695_shutdown(ksp); + + ks8695_reset(ksp); + + ks8695_update_mac(ksp); + + /* We ignore the return from this since it managed to init + * before it probably will be okay to init again. + */ + ks8695_init_net(ksp); + + /* Reconfigure promiscuity etc */ + ks8695_set_multicast(ndev); + + /* And start the TX queue once more */ + netif_start_queue(ndev); +} + +/** + * ks8695_start_xmit - Start a packet transmission + * @skb: The packet to transmit + * @ndev: The network device to send the packet on + * + * This routine, called by the net layer, takes ownership of the + * sk_buff and adds it to the TX ring. It then kicks the TX DMA + * engine to ensure transmission begins. + */ +static int +ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + int buff_n; + dma_addr_t dmap; + + spin_lock_irq(&ksp->txq_lock); + + if (ksp->tx_ring_used == MAX_TX_DESC) { + /* Somehow we got entered when we have no room */ + spin_unlock_irq(&ksp->txq_lock); + return NETDEV_TX_BUSY; + } + + buff_n = ksp->tx_ring_next_slot; + + BUG_ON(ksp->tx_buffers[buff_n].skb); + + dmap = dma_map_single(ksp->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(ksp->dev, dmap))) { + /* Failed to DMA map this SKB, give it back for now */ + spin_unlock_irq(&ksp->txq_lock); + dev_dbg(ksp->dev, "%s: Could not map DMA memory for "\ + "transmission, trying later\n", ndev->name); + return NETDEV_TX_BUSY; + } + + ksp->tx_buffers[buff_n].dma_ptr = dmap; + /* Mapped okay, store the buffer pointer and length for later */ + ksp->tx_buffers[buff_n].skb = skb; + ksp->tx_buffers[buff_n].length = skb->len; + + /* Fill out the TX descriptor */ + ksp->tx_ring[buff_n].data_ptr = + cpu_to_le32(ksp->tx_buffers[buff_n].dma_ptr); + ksp->tx_ring[buff_n].status = + cpu_to_le32(TDES_IC | TDES_FS | TDES_LS | + (skb->len & TDES_TBS)); + + wmb(); + + /* Hand it over to the hardware */ + ksp->tx_ring[buff_n].owner = cpu_to_le32(TDES_OWN); + + if (++ksp->tx_ring_used == MAX_TX_DESC) + netif_stop_queue(ndev); + + /* Kick the TX DMA in case it decided to go IDLE */ + ks8695_writereg(ksp, KS8695_DTSC, 0); + + /* And update the next ring slot */ + ksp->tx_ring_next_slot = (buff_n + 1) & MAX_TX_DESC_MASK; + + spin_unlock_irq(&ksp->txq_lock); + return NETDEV_TX_OK; +} + +/** + * ks8695_stop - Stop (shutdown) a KS8695 ethernet interface + * @ndev: The net_device to stop + * + * This disables the TX queue and cleans up a KS8695 ethernet + * device. + */ +static int +ks8695_stop(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + + netif_stop_queue(ndev); + napi_disable(&ksp->napi); + + ks8695_shutdown(ksp); + + return 0; +} + +/** + * ks8695_open - Open (bring up) a KS8695 ethernet interface + * @ndev: The net_device to open + * + * This resets, configures the MAC, initialises the RX ring and + * DMA engines and starts the TX queue for a KS8695 ethernet + * device. + */ +static int +ks8695_open(struct net_device *ndev) +{ + struct ks8695_priv *ksp = netdev_priv(ndev); + int ret; + + if (!is_valid_ether_addr(ndev->dev_addr)) + return -EADDRNOTAVAIL; + + ks8695_reset(ksp); + + ks8695_update_mac(ksp); + + ret = ks8695_init_net(ksp); + if (ret) { + ks8695_shutdown(ksp); + return ret; + } + + napi_enable(&ksp->napi); + netif_start_queue(ndev); + + return 0; +} + +/* Platform device driver */ + +/** + * ks8695_init_switch - Init LAN switch to known good defaults. + * @ksp: The device to initialise + * + * This initialises the LAN switch in the KS8695 to a known-good + * set of defaults. + */ +static void __devinit +ks8695_init_switch(struct ks8695_priv *ksp) +{ + u32 ctrl; + + /* Default value for SEC0 according to datasheet */ + ctrl = 0x40819e00; + + /* LED0 = Speed LED1 = Link/Activity */ + ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S); + ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY); + + /* Enable Switch */ + ctrl |= SEC0_ENABLE; + + writel(ctrl, ksp->phyiface_regs + KS8695_SEC0); + + /* Defaults for SEC1 */ + writel(0x9400100, ksp->phyiface_regs + KS8695_SEC1); +} + +/** + * ks8695_init_wan_phy - Initialise the WAN PHY to sensible defaults + * @ksp: The device to initialise + * + * This initialises a KS8695's WAN phy to sensible values for + * autonegotiation etc. + */ +static void __devinit +ks8695_init_wan_phy(struct ks8695_priv *ksp) +{ + u32 ctrl; + + /* Support auto-negotiation */ + ctrl = (WMC_WANAP | WMC_WANA100F | WMC_WANA100H | + WMC_WANA10F | WMC_WANA10H); + + /* LED0 = Activity , LED1 = Link */ + ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK); + + /* Restart Auto-negotiation */ + ctrl |= WMC_WANR; + + writel(ctrl, ksp->phyiface_regs + KS8695_WMC); + + writel(0, ksp->phyiface_regs + KS8695_WPPM); + writel(0, ksp->phyiface_regs + KS8695_PPS); +} + +static const struct net_device_ops ks8695_netdev_ops = { + .ndo_open = ks8695_open, + .ndo_stop = ks8695_stop, + .ndo_start_xmit = ks8695_start_xmit, + .ndo_tx_timeout = ks8695_timeout, + .ndo_set_mac_address = ks8695_set_mac, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = ks8695_set_multicast, +}; + +/** + * ks8695_probe - Probe and initialise a KS8695 ethernet interface + * @pdev: The platform device to probe + * + * Initialise a KS8695 ethernet device from platform data. + * + * This driver requires at least one IORESOURCE_MEM for the + * registers and two IORESOURCE_IRQ for the RX and TX IRQs + * respectively. It can optionally take an additional + * IORESOURCE_MEM for the switch or phy in the case of the lan or + * wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan + * port. + */ +static int __devinit +ks8695_probe(struct platform_device *pdev) +{ + struct ks8695_priv *ksp; + struct net_device *ndev; + struct resource *regs_res, *phyiface_res; + struct resource *rxirq_res, *txirq_res, *linkirq_res; + int ret = 0; + int buff_n; + u32 machigh, maclow; + + /* Initialise a net_device */ + ndev = alloc_etherdev(sizeof(struct ks8695_priv)); + if (!ndev) { + dev_err(&pdev->dev, "could not allocate device.\n"); + return -ENOMEM; + } + + SET_NETDEV_DEV(ndev, &pdev->dev); + + dev_dbg(&pdev->dev, "ks8695_probe() called\n"); + + /* Configure our private structure a little */ + ksp = netdev_priv(ndev); + + ksp->dev = &pdev->dev; + ksp->ndev = ndev; + ksp->msg_enable = NETIF_MSG_LINK; + + /* Retrieve resources */ + regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + phyiface_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + + rxirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + txirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + linkirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 2); + + if (!(regs_res && rxirq_res && txirq_res)) { + dev_err(ksp->dev, "insufficient resources\n"); + ret = -ENOENT; + goto failure; + } + + ksp->regs_req = request_mem_region(regs_res->start, + resource_size(regs_res), + pdev->name); + + if (!ksp->regs_req) { + dev_err(ksp->dev, "cannot claim register space\n"); + ret = -EIO; + goto failure; + } + + ksp->io_regs = ioremap(regs_res->start, resource_size(regs_res)); + + if (!ksp->io_regs) { + dev_err(ksp->dev, "failed to ioremap registers\n"); + ret = -EINVAL; + goto failure; + } + + if (phyiface_res) { + ksp->phyiface_req = + request_mem_region(phyiface_res->start, + resource_size(phyiface_res), + phyiface_res->name); + + if (!ksp->phyiface_req) { + dev_err(ksp->dev, + "cannot claim switch register space\n"); + ret = -EIO; + goto failure; + } + + ksp->phyiface_regs = ioremap(phyiface_res->start, + resource_size(phyiface_res)); + + if (!ksp->phyiface_regs) { + dev_err(ksp->dev, + "failed to ioremap switch registers\n"); + ret = -EINVAL; + goto failure; + } + } + + ksp->rx_irq = rxirq_res->start; + ksp->rx_irq_name = rxirq_res->name ? rxirq_res->name : "Ethernet RX"; + ksp->tx_irq = txirq_res->start; + ksp->tx_irq_name = txirq_res->name ? txirq_res->name : "Ethernet TX"; + ksp->link_irq = (linkirq_res ? linkirq_res->start : -1); + ksp->link_irq_name = (linkirq_res && linkirq_res->name) ? + linkirq_res->name : "Ethernet Link"; + + /* driver system setup */ + ndev->netdev_ops = &ks8695_netdev_ops; + ndev->watchdog_timeo = msecs_to_jiffies(watchdog); + + netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); + + /* Retrieve the default MAC addr from the chip. */ + /* The bootloader should have left it in there for us. */ + + machigh = ks8695_readreg(ksp, KS8695_MAH); + maclow = ks8695_readreg(ksp, KS8695_MAL); + + ndev->dev_addr[0] = (machigh >> 8) & 0xFF; + ndev->dev_addr[1] = machigh & 0xFF; + ndev->dev_addr[2] = (maclow >> 24) & 0xFF; + ndev->dev_addr[3] = (maclow >> 16) & 0xFF; + ndev->dev_addr[4] = (maclow >> 8) & 0xFF; + ndev->dev_addr[5] = maclow & 0xFF; + + if (!is_valid_ether_addr(ndev->dev_addr)) + dev_warn(ksp->dev, "%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", ndev->name); + + /* In order to be efficient memory-wise, we allocate both + * rings in one go. + */ + ksp->ring_base = dma_alloc_coherent(&pdev->dev, RING_DMA_SIZE, + &ksp->ring_base_dma, GFP_KERNEL); + if (!ksp->ring_base) { + ret = -ENOMEM; + goto failure; + } + + /* Specify the TX DMA ring buffer */ + ksp->tx_ring = ksp->ring_base; + ksp->tx_ring_dma = ksp->ring_base_dma; + + /* And initialise the queue's lock */ + spin_lock_init(&ksp->txq_lock); + spin_lock_init(&ksp->rx_lock); + + /* Specify the RX DMA ring buffer */ + ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE; + ksp->rx_ring_dma = ksp->ring_base_dma + TX_RING_DMA_SIZE; + + /* Zero the descriptor rings */ + memset(ksp->tx_ring, 0, TX_RING_DMA_SIZE); + memset(ksp->rx_ring, 0, RX_RING_DMA_SIZE); + + /* Build the rings */ + for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) { + ksp->tx_ring[buff_n].next_desc = + cpu_to_le32(ksp->tx_ring_dma + + (sizeof(struct tx_ring_desc) * + ((buff_n + 1) & MAX_TX_DESC_MASK))); + } + + for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) { + ksp->rx_ring[buff_n].next_desc = + cpu_to_le32(ksp->rx_ring_dma + + (sizeof(struct rx_ring_desc) * + ((buff_n + 1) & MAX_RX_DESC_MASK))); + } + + /* Initialise the port (physically) */ + if (ksp->phyiface_regs && ksp->link_irq == -1) { + ks8695_init_switch(ksp); + ksp->dtype = KS8695_DTYPE_LAN; + SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); + } else if (ksp->phyiface_regs && ksp->link_irq != -1) { + ks8695_init_wan_phy(ksp); + ksp->dtype = KS8695_DTYPE_WAN; + SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops); + } else { + /* No initialisation since HPNA does not have a PHY */ + ksp->dtype = KS8695_DTYPE_HPNA; + SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops); + } + + /* And bring up the net_device with the net core */ + platform_set_drvdata(pdev, ndev); + ret = register_netdev(ndev); + + if (ret == 0) { + dev_info(ksp->dev, "ks8695 ethernet (%s) MAC: %pM\n", + ks8695_port_type(ksp), ndev->dev_addr); + } else { + /* Report the failure to register the net_device */ + dev_err(ksp->dev, "ks8695net: failed to register netdev.\n"); + goto failure; + } + + /* All is well */ + return 0; + + /* Error exit path */ +failure: + ks8695_release_device(ksp); + free_netdev(ndev); + + return ret; +} + +/** + * ks8695_drv_suspend - Suspend a KS8695 ethernet platform device. + * @pdev: The device to suspend + * @state: The suspend state + * + * This routine detaches and shuts down a KS8695 ethernet device. + */ +static int +ks8695_drv_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct ks8695_priv *ksp = netdev_priv(ndev); + + ksp->in_suspend = 1; + + if (netif_running(ndev)) { + netif_device_detach(ndev); + ks8695_shutdown(ksp); + } + + return 0; +} + +/** + * ks8695_drv_resume - Resume a KS8695 ethernet platform device. + * @pdev: The device to resume + * + * This routine re-initialises and re-attaches a KS8695 ethernet + * device. + */ +static int +ks8695_drv_resume(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct ks8695_priv *ksp = netdev_priv(ndev); + + if (netif_running(ndev)) { + ks8695_reset(ksp); + ks8695_init_net(ksp); + ks8695_set_multicast(ndev); + netif_device_attach(ndev); + } + + ksp->in_suspend = 0; + + return 0; +} + +/** + * ks8695_drv_remove - Remove a KS8695 net device on driver unload. + * @pdev: The platform device to remove + * + * This unregisters and releases a KS8695 ethernet device. + */ +static int __devexit +ks8695_drv_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct ks8695_priv *ksp = netdev_priv(ndev); + + platform_set_drvdata(pdev, NULL); + netif_napi_del(&ksp->napi); + + unregister_netdev(ndev); + ks8695_release_device(ksp); + free_netdev(ndev); + + dev_dbg(&pdev->dev, "released and freed device\n"); + return 0; +} + +static struct platform_driver ks8695_driver = { + .driver = { + .name = MODULENAME, + .owner = THIS_MODULE, + }, + .probe = ks8695_probe, + .remove = __devexit_p(ks8695_drv_remove), + .suspend = ks8695_drv_suspend, + .resume = ks8695_drv_resume, +}; + +/* Module interface */ + +static int __init +ks8695_init(void) +{ + printk(KERN_INFO "%s Ethernet driver, V%s\n", + MODULENAME, MODULEVERSION); + + return platform_driver_register(&ks8695_driver); +} + +static void __exit +ks8695_cleanup(void) +{ + platform_driver_unregister(&ks8695_driver); +} + +module_init(ks8695_init); +module_exit(ks8695_cleanup); + +MODULE_AUTHOR("Simtec Electronics"); +MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" MODULENAME); + +module_param(watchdog, int, 0400); +MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); diff --git a/drivers/net/ethernet/micrel/ks8695net.h b/drivers/net/ethernet/micrel/ks8695net.h new file mode 100644 index 000000000000..80eff6ea5163 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8695net.h @@ -0,0 +1,107 @@ +/* + * Micrel KS8695 (Centaur) Ethernet. + * + * Copyright 2008 Simtec Electronics + * Daniel Silverstone <dsilvers@simtec.co.uk> + * Vincent Sanders <vince@simtec.co.uk> + */ + +#ifndef KS8695NET_H +#define KS8695NET_H + +/* Receive descriptor flags */ +#define RDES_OWN (1 << 31) /* Ownership */ +#define RDES_FS (1 << 30) /* First Descriptor */ +#define RDES_LS (1 << 29) /* Last Descriptor */ +#define RDES_IPE (1 << 28) /* IP Checksum error */ +#define RDES_TCPE (1 << 27) /* TCP Checksum error */ +#define RDES_UDPE (1 << 26) /* UDP Checksum error */ +#define RDES_ES (1 << 25) /* Error summary */ +#define RDES_MF (1 << 24) /* Multicast Frame */ +#define RDES_RE (1 << 19) /* MII Error reported */ +#define RDES_TL (1 << 18) /* Frame too Long */ +#define RDES_RF (1 << 17) /* Runt Frame */ +#define RDES_CE (1 << 16) /* CRC error */ +#define RDES_FT (1 << 15) /* Frame Type */ +#define RDES_FLEN (0x7ff) /* Frame Length */ + +#define RDES_RER (1 << 25) /* Receive End of Ring */ +#define RDES_RBS (0x7ff) /* Receive Buffer Size */ + +/* Transmit descriptor flags */ + +#define TDES_OWN (1 << 31) /* Ownership */ + +#define TDES_IC (1 << 31) /* Interrupt on Completion */ +#define TDES_FS (1 << 30) /* First Segment */ +#define TDES_LS (1 << 29) /* Last Segment */ +#define TDES_IPCKG (1 << 28) /* IP Checksum generate */ +#define TDES_TCPCKG (1 << 27) /* TCP Checksum generate */ +#define TDES_UDPCKG (1 << 26) /* UDP Checksum generate */ +#define TDES_TER (1 << 25) /* Transmit End of Ring */ +#define TDES_TBS (0x7ff) /* Transmit Buffer Size */ + +/* + * Network controller register offsets + */ +#define KS8695_DTXC (0x00) /* DMA Transmit Control */ +#define KS8695_DRXC (0x04) /* DMA Receive Control */ +#define KS8695_DTSC (0x08) /* DMA Transmit Start Command */ +#define KS8695_DRSC (0x0c) /* DMA Receive Start Command */ +#define KS8695_TDLB (0x10) /* Transmit Descriptor List + * Base Address + */ +#define KS8695_RDLB (0x14) /* Receive Descriptor List + * Base Address + */ +#define KS8695_MAL (0x18) /* MAC Station Address Low */ +#define KS8695_MAH (0x1c) /* MAC Station Address High */ +#define KS8695_AAL_(n) (0x80 + ((n)*8)) /* MAC Additional + * Station Address + * (0..15) Low + */ +#define KS8695_AAH_(n) (0x84 + ((n)*8)) /* MAC Additional + * Station Address + * (0..15) High + */ + + +/* DMA Transmit Control Register */ +#define DTXC_TRST (1 << 31) /* Soft Reset */ +#define DTXC_TBS (0x3f << 24) /* Transmit Burst Size */ +#define DTXC_TUCG (1 << 18) /* Transmit UDP + * Checksum Generate + */ +#define DTXC_TTCG (1 << 17) /* Transmit TCP + * Checksum Generate + */ +#define DTXC_TICG (1 << 16) /* Transmit IP + * Checksum Generate + */ +#define DTXC_TFCE (1 << 9) /* Transmit Flow + * Control Enable + */ +#define DTXC_TLB (1 << 8) /* Loopback mode */ +#define DTXC_TEP (1 << 2) /* Transmit Enable Padding */ +#define DTXC_TAC (1 << 1) /* Transmit Add CRC */ +#define DTXC_TE (1 << 0) /* TX Enable */ + +/* DMA Receive Control Register */ +#define DRXC_RBS (0x3f << 24) /* Receive Burst Size */ +#define DRXC_RUCC (1 << 18) /* Receive UDP Checksum check */ +#define DRXC_RTCG (1 << 17) /* Receive TCP Checksum check */ +#define DRXC_RICG (1 << 16) /* Receive IP Checksum check */ +#define DRXC_RFCE (1 << 9) /* Receive Flow Control + * Enable + */ +#define DRXC_RB (1 << 6) /* Receive Broadcast */ +#define DRXC_RM (1 << 5) /* Receive Multicast */ +#define DRXC_RU (1 << 4) /* Receive Unicast */ +#define DRXC_RERR (1 << 3) /* Receive Error Frame */ +#define DRXC_RA (1 << 2) /* Receive All */ +#define DRXC_RE (1 << 0) /* RX Enable */ + +/* Additional Station Address High */ +#define AAH_E (1 << 31) /* Address Enabled */ + +#endif /* KS8695NET_H */ diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c new file mode 100644 index 000000000000..4a6ae057e3b1 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -0,0 +1,1284 @@ +/* + * ks8842.c timberdale KS8842 ethernet driver + * Copyright (c) 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * The Micrel KS8842 behind the timberdale FPGA + * The genuine Micrel KS8841/42 device with ISA 16/32bit bus interface + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/ks8842.h> +#include <linux/dmaengine.h> +#include <linux/dma-mapping.h> +#include <linux/scatterlist.h> + +#define DRV_NAME "ks8842" + +/* Timberdale specific Registers */ +#define REG_TIMB_RST 0x1c +#define REG_TIMB_FIFO 0x20 +#define REG_TIMB_ISR 0x24 +#define REG_TIMB_IER 0x28 +#define REG_TIMB_IAR 0x2C +#define REQ_TIMB_DMA_RESUME 0x30 + +/* KS8842 registers */ + +#define REG_SELECT_BANK 0x0e + +/* bank 0 registers */ +#define REG_QRFCR 0x04 + +/* bank 2 registers */ +#define REG_MARL 0x00 +#define REG_MARM 0x02 +#define REG_MARH 0x04 + +/* bank 3 registers */ +#define REG_GRR 0x06 + +/* bank 16 registers */ +#define REG_TXCR 0x00 +#define REG_TXSR 0x02 +#define REG_RXCR 0x04 +#define REG_TXMIR 0x08 +#define REG_RXMIR 0x0A + +/* bank 17 registers */ +#define REG_TXQCR 0x00 +#define REG_RXQCR 0x02 +#define REG_TXFDPR 0x04 +#define REG_RXFDPR 0x06 +#define REG_QMU_DATA_LO 0x08 +#define REG_QMU_DATA_HI 0x0A + +/* bank 18 registers */ +#define REG_IER 0x00 +#define IRQ_LINK_CHANGE 0x8000 +#define IRQ_TX 0x4000 +#define IRQ_RX 0x2000 +#define IRQ_RX_OVERRUN 0x0800 +#define IRQ_TX_STOPPED 0x0200 +#define IRQ_RX_STOPPED 0x0100 +#define IRQ_RX_ERROR 0x0080 +#define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \ + IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) +/* When running via timberdale in DMA mode, the RX interrupt should be + enabled in the KS8842, but not in the FPGA IP, since the IP handles + RX DMA internally. + TX interrupts are not needed it is handled by the FPGA the driver is + notified via DMA callbacks. +*/ +#define ENABLED_IRQS_DMA_IP (IRQ_LINK_CHANGE | IRQ_RX_STOPPED | \ + IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) +#define ENABLED_IRQS_DMA (ENABLED_IRQS_DMA_IP | IRQ_RX) +#define REG_ISR 0x02 +#define REG_RXSR 0x04 +#define RXSR_VALID 0x8000 +#define RXSR_BROADCAST 0x80 +#define RXSR_MULTICAST 0x40 +#define RXSR_UNICAST 0x20 +#define RXSR_FRAMETYPE 0x08 +#define RXSR_TOO_LONG 0x04 +#define RXSR_RUNT 0x02 +#define RXSR_CRC_ERROR 0x01 +#define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR) + +/* bank 32 registers */ +#define REG_SW_ID_AND_ENABLE 0x00 +#define REG_SGCR1 0x02 +#define REG_SGCR2 0x04 +#define REG_SGCR3 0x06 + +/* bank 39 registers */ +#define REG_MACAR1 0x00 +#define REG_MACAR2 0x02 +#define REG_MACAR3 0x04 + +/* bank 45 registers */ +#define REG_P1MBCR 0x00 +#define REG_P1MBSR 0x02 + +/* bank 46 registers */ +#define REG_P2MBCR 0x00 +#define REG_P2MBSR 0x02 + +/* bank 48 registers */ +#define REG_P1CR2 0x02 + +/* bank 49 registers */ +#define REG_P1CR4 0x02 +#define REG_P1SR 0x04 + +/* flags passed by platform_device for configuration */ +#define MICREL_KS884X 0x01 /* 0=Timeberdale(FPGA), 1=Micrel */ +#define KS884X_16BIT 0x02 /* 1=16bit, 0=32bit */ + +#define DMA_BUFFER_SIZE 2048 + +struct ks8842_tx_dma_ctl { + struct dma_chan *chan; + struct dma_async_tx_descriptor *adesc; + void *buf; + struct scatterlist sg; + int channel; +}; + +struct ks8842_rx_dma_ctl { + struct dma_chan *chan; + struct dma_async_tx_descriptor *adesc; + struct sk_buff *skb; + struct scatterlist sg; + struct tasklet_struct tasklet; + int channel; +}; + +#define KS8842_USE_DMA(adapter) (((adapter)->dma_tx.channel != -1) && \ + ((adapter)->dma_rx.channel != -1)) + +struct ks8842_adapter { + void __iomem *hw_addr; + int irq; + unsigned long conf_flags; /* copy of platform_device config */ + struct tasklet_struct tasklet; + spinlock_t lock; /* spinlock to be interrupt safe */ + struct work_struct timeout_work; + struct net_device *netdev; + struct device *dev; + struct ks8842_tx_dma_ctl dma_tx; + struct ks8842_rx_dma_ctl dma_rx; +}; + +static void ks8842_dma_rx_cb(void *data); +static void ks8842_dma_tx_cb(void *data); + +static inline void ks8842_resume_dma(struct ks8842_adapter *adapter) +{ + iowrite32(1, adapter->hw_addr + REQ_TIMB_DMA_RESUME); +} + +static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank) +{ + iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK); +} + +static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank, + u8 value, int offset) +{ + ks8842_select_bank(adapter, bank); + iowrite8(value, adapter->hw_addr + offset); +} + +static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank, + u16 value, int offset) +{ + ks8842_select_bank(adapter, bank); + iowrite16(value, adapter->hw_addr + offset); +} + +static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank, + u16 bits, int offset) +{ + u16 reg; + ks8842_select_bank(adapter, bank); + reg = ioread16(adapter->hw_addr + offset); + reg |= bits; + iowrite16(reg, adapter->hw_addr + offset); +} + +static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank, + u16 bits, int offset) +{ + u16 reg; + ks8842_select_bank(adapter, bank); + reg = ioread16(adapter->hw_addr + offset); + reg &= ~bits; + iowrite16(reg, adapter->hw_addr + offset); +} + +static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank, + u32 value, int offset) +{ + ks8842_select_bank(adapter, bank); + iowrite32(value, adapter->hw_addr + offset); +} + +static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank, + int offset) +{ + ks8842_select_bank(adapter, bank); + return ioread8(adapter->hw_addr + offset); +} + +static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank, + int offset) +{ + ks8842_select_bank(adapter, bank); + return ioread16(adapter->hw_addr + offset); +} + +static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank, + int offset) +{ + ks8842_select_bank(adapter, bank); + return ioread32(adapter->hw_addr + offset); +} + +static void ks8842_reset(struct ks8842_adapter *adapter) +{ + if (adapter->conf_flags & MICREL_KS884X) { + ks8842_write16(adapter, 3, 1, REG_GRR); + msleep(10); + iowrite16(0, adapter->hw_addr + REG_GRR); + } else { + /* The KS8842 goes haywire when doing softare reset + * a work around in the timberdale IP is implemented to + * do a hardware reset instead + ks8842_write16(adapter, 3, 1, REG_GRR); + msleep(10); + iowrite16(0, adapter->hw_addr + REG_GRR); + */ + iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST); + msleep(20); + } +} + +static void ks8842_update_link_status(struct net_device *netdev, + struct ks8842_adapter *adapter) +{ + /* check the status of the link */ + if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) { + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } else { + netif_stop_queue(netdev); + netif_carrier_off(netdev); + } +} + +static void ks8842_enable_tx(struct ks8842_adapter *adapter) +{ + ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR); +} + +static void ks8842_disable_tx(struct ks8842_adapter *adapter) +{ + ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR); +} + +static void ks8842_enable_rx(struct ks8842_adapter *adapter) +{ + ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR); +} + +static void ks8842_disable_rx(struct ks8842_adapter *adapter) +{ + ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR); +} + +static void ks8842_reset_hw(struct ks8842_adapter *adapter) +{ + /* reset the HW */ + ks8842_reset(adapter); + + /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */ + ks8842_write16(adapter, 16, 0x000E, REG_TXCR); + + /* enable the receiver, uni + multi + broadcast + flow ctrl + + crc strip */ + ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400, + REG_RXCR); + + /* TX frame pointer autoincrement */ + ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR); + + /* RX frame pointer autoincrement */ + ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR); + + /* RX 2 kb high watermark */ + ks8842_write16(adapter, 0, 0x1000, REG_QRFCR); + + /* aggressive back off in half duplex */ + ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1); + + /* enable no excessive collison drop */ + ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2); + + /* Enable port 1 force flow control / back pressure / transmit / recv */ + ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2); + + /* restart port auto-negotiation */ + ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4); + + /* Enable the transmitter */ + ks8842_enable_tx(adapter); + + /* Enable the receiver */ + ks8842_enable_rx(adapter); + + /* clear all interrupts */ + ks8842_write16(adapter, 18, 0xffff, REG_ISR); + + /* enable interrupts */ + if (KS8842_USE_DMA(adapter)) { + /* When running in DMA Mode the RX interrupt is not enabled in + timberdale because RX data is received by DMA callbacks + it must still be enabled in the KS8842 because it indicates + to timberdale when there is RX data for it's DMA FIFOs */ + iowrite16(ENABLED_IRQS_DMA_IP, adapter->hw_addr + REG_TIMB_IER); + ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER); + } else { + if (!(adapter->conf_flags & MICREL_KS884X)) + iowrite16(ENABLED_IRQS, + adapter->hw_addr + REG_TIMB_IER); + ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); + } + /* enable the switch */ + ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE); +} + +static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest) +{ + int i; + u16 mac; + + for (i = 0; i < ETH_ALEN; i++) + dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i); + + if (adapter->conf_flags & MICREL_KS884X) { + /* + the sequence of saving mac addr between MAC and Switch is + different. + */ + + mac = ks8842_read16(adapter, 2, REG_MARL); + ks8842_write16(adapter, 39, mac, REG_MACAR3); + mac = ks8842_read16(adapter, 2, REG_MARM); + ks8842_write16(adapter, 39, mac, REG_MACAR2); + mac = ks8842_read16(adapter, 2, REG_MARH); + ks8842_write16(adapter, 39, mac, REG_MACAR1); + } else { + + /* make sure the switch port uses the same MAC as the QMU */ + mac = ks8842_read16(adapter, 2, REG_MARL); + ks8842_write16(adapter, 39, mac, REG_MACAR1); + mac = ks8842_read16(adapter, 2, REG_MARM); + ks8842_write16(adapter, 39, mac, REG_MACAR2); + mac = ks8842_read16(adapter, 2, REG_MARH); + ks8842_write16(adapter, 39, mac, REG_MACAR3); + } +} + +static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac) +{ + unsigned long flags; + unsigned i; + + spin_lock_irqsave(&adapter->lock, flags); + for (i = 0; i < ETH_ALEN; i++) { + ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i); + if (!(adapter->conf_flags & MICREL_KS884X)) + ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1], + REG_MACAR1 + i); + } + + if (adapter->conf_flags & MICREL_KS884X) { + /* + the sequence of saving mac addr between MAC and Switch is + different. + */ + + u16 mac; + + mac = ks8842_read16(adapter, 2, REG_MARL); + ks8842_write16(adapter, 39, mac, REG_MACAR3); + mac = ks8842_read16(adapter, 2, REG_MARM); + ks8842_write16(adapter, 39, mac, REG_MACAR2); + mac = ks8842_read16(adapter, 2, REG_MARH); + ks8842_write16(adapter, 39, mac, REG_MACAR1); + } + spin_unlock_irqrestore(&adapter->lock, flags); +} + +static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter) +{ + return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff; +} + +static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx; + u8 *buf = ctl->buf; + + if (ctl->adesc) { + netdev_dbg(netdev, "%s: TX ongoing\n", __func__); + /* transfer ongoing */ + return NETDEV_TX_BUSY; + } + + sg_dma_len(&ctl->sg) = skb->len + sizeof(u32); + + /* copy data to the TX buffer */ + /* the control word, enable IRQ, port 1 and the length */ + *buf++ = 0x00; + *buf++ = 0x01; /* Port 1 */ + *buf++ = skb->len & 0xff; + *buf++ = (skb->len >> 8) & 0xff; + skb_copy_from_linear_data(skb, buf, skb->len); + + dma_sync_single_range_for_device(adapter->dev, + sg_dma_address(&ctl->sg), 0, sg_dma_len(&ctl->sg), + DMA_TO_DEVICE); + + /* make sure the length is a multiple of 4 */ + if (sg_dma_len(&ctl->sg) % 4) + sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4; + + ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, + &ctl->sg, 1, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); + if (!ctl->adesc) + return NETDEV_TX_BUSY; + + ctl->adesc->callback_param = netdev; + ctl->adesc->callback = ks8842_dma_tx_cb; + ctl->adesc->tx_submit(ctl->adesc); + + netdev->stats.tx_bytes += skb->len; + + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} + +static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + int len = skb->len; + + netdev_dbg(netdev, "%s: len %u head %p data %p tail %p end %p\n", + __func__, skb->len, skb->head, skb->data, + skb_tail_pointer(skb), skb_end_pointer(skb)); + + /* check FIFO buffer space, we need space for CRC and command bits */ + if (ks8842_tx_fifo_space(adapter) < len + 8) + return NETDEV_TX_BUSY; + + if (adapter->conf_flags & KS884X_16BIT) { + u16 *ptr16 = (u16 *)skb->data; + ks8842_write16(adapter, 17, 0x8000 | 0x100, REG_QMU_DATA_LO); + ks8842_write16(adapter, 17, (u16)len, REG_QMU_DATA_HI); + netdev->stats.tx_bytes += len; + + /* copy buffer */ + while (len > 0) { + iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_LO); + iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_HI); + len -= sizeof(u32); + } + } else { + + u32 *ptr = (u32 *)skb->data; + u32 ctrl; + /* the control word, enable IRQ, port 1 and the length */ + ctrl = 0x8000 | 0x100 | (len << 16); + ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO); + + netdev->stats.tx_bytes += len; + + /* copy buffer */ + while (len > 0) { + iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO); + len -= sizeof(u32); + ptr++; + } + } + + /* enqueue packet */ + ks8842_write16(adapter, 17, 1, REG_TXQCR); + + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} + +static void ks8842_update_rx_err_counters(struct net_device *netdev, u32 status) +{ + netdev_dbg(netdev, "RX error, status: %x\n", status); + + netdev->stats.rx_errors++; + if (status & RXSR_TOO_LONG) + netdev->stats.rx_length_errors++; + if (status & RXSR_CRC_ERROR) + netdev->stats.rx_crc_errors++; + if (status & RXSR_RUNT) + netdev->stats.rx_frame_errors++; +} + +static void ks8842_update_rx_counters(struct net_device *netdev, u32 status, + int len) +{ + netdev_dbg(netdev, "RX packet, len: %d\n", len); + + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += len; + if (status & RXSR_MULTICAST) + netdev->stats.multicast++; +} + +static int __ks8842_start_new_rx_dma(struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx; + struct scatterlist *sg = &ctl->sg; + int err; + + ctl->skb = netdev_alloc_skb(netdev, DMA_BUFFER_SIZE); + if (ctl->skb) { + sg_init_table(sg, 1); + sg_dma_address(sg) = dma_map_single(adapter->dev, + ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE); + err = dma_mapping_error(adapter->dev, sg_dma_address(sg)); + if (unlikely(err)) { + sg_dma_address(sg) = 0; + goto out; + } + + sg_dma_len(sg) = DMA_BUFFER_SIZE; + + ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, + sg, 1, DMA_FROM_DEVICE, + DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); + + if (!ctl->adesc) + goto out; + + ctl->adesc->callback_param = netdev; + ctl->adesc->callback = ks8842_dma_rx_cb; + ctl->adesc->tx_submit(ctl->adesc); + } else { + err = -ENOMEM; + sg_dma_address(sg) = 0; + goto out; + } + + return err; +out: + if (sg_dma_address(sg)) + dma_unmap_single(adapter->dev, sg_dma_address(sg), + DMA_BUFFER_SIZE, DMA_FROM_DEVICE); + sg_dma_address(sg) = 0; + if (ctl->skb) + dev_kfree_skb(ctl->skb); + + ctl->skb = NULL; + + printk(KERN_ERR DRV_NAME": Failed to start RX DMA: %d\n", err); + return err; +} + +static void ks8842_rx_frame_dma_tasklet(unsigned long arg) +{ + struct net_device *netdev = (struct net_device *)arg; + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx; + struct sk_buff *skb = ctl->skb; + dma_addr_t addr = sg_dma_address(&ctl->sg); + u32 status; + + ctl->adesc = NULL; + + /* kick next transfer going */ + __ks8842_start_new_rx_dma(netdev); + + /* now handle the data we got */ + dma_unmap_single(adapter->dev, addr, DMA_BUFFER_SIZE, DMA_FROM_DEVICE); + + status = *((u32 *)skb->data); + + netdev_dbg(netdev, "%s - rx_data: status: %x\n", + __func__, status & 0xffff); + + /* check the status */ + if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { + int len = (status >> 16) & 0x7ff; + + ks8842_update_rx_counters(netdev, status, len); + + /* reserve 4 bytes which is the status word */ + skb_reserve(skb, 4); + skb_put(skb, len); + + skb->protocol = eth_type_trans(skb, netdev); + netif_rx(skb); + } else { + ks8842_update_rx_err_counters(netdev, status); + dev_kfree_skb(skb); + } +} + +static void ks8842_rx_frame(struct net_device *netdev, + struct ks8842_adapter *adapter) +{ + u32 status; + int len; + + if (adapter->conf_flags & KS884X_16BIT) { + status = ks8842_read16(adapter, 17, REG_QMU_DATA_LO); + len = ks8842_read16(adapter, 17, REG_QMU_DATA_HI); + netdev_dbg(netdev, "%s - rx_data: status: %x\n", + __func__, status); + } else { + status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO); + len = (status >> 16) & 0x7ff; + status &= 0xffff; + netdev_dbg(netdev, "%s - rx_data: status: %x\n", + __func__, status); + } + + /* check the status */ + if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { + struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len + 3); + + if (skb) { + + ks8842_update_rx_counters(netdev, status, len); + + if (adapter->conf_flags & KS884X_16BIT) { + u16 *data16 = (u16 *)skb_put(skb, len); + ks8842_select_bank(adapter, 17); + while (len > 0) { + *data16++ = ioread16(adapter->hw_addr + + REG_QMU_DATA_LO); + *data16++ = ioread16(adapter->hw_addr + + REG_QMU_DATA_HI); + len -= sizeof(u32); + } + } else { + u32 *data = (u32 *)skb_put(skb, len); + + ks8842_select_bank(adapter, 17); + while (len > 0) { + *data++ = ioread32(adapter->hw_addr + + REG_QMU_DATA_LO); + len -= sizeof(u32); + } + } + skb->protocol = eth_type_trans(skb, netdev); + netif_rx(skb); + } else + netdev->stats.rx_dropped++; + } else + ks8842_update_rx_err_counters(netdev, status); + + /* set high watermark to 3K */ + ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR); + + /* release the frame */ + ks8842_write16(adapter, 17, 0x01, REG_RXQCR); + + /* set high watermark to 2K */ + ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR); +} + +void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) +{ + u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; + netdev_dbg(netdev, "%s Entry - rx_data: %d\n", __func__, rx_data); + while (rx_data) { + ks8842_rx_frame(netdev, adapter); + rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; + } +} + +void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) +{ + u16 sr = ks8842_read16(adapter, 16, REG_TXSR); + netdev_dbg(netdev, "%s - entry, sr: %x\n", __func__, sr); + netdev->stats.tx_packets++; + if (netif_queue_stopped(netdev)) + netif_wake_queue(netdev); +} + +void ks8842_handle_rx_overrun(struct net_device *netdev, + struct ks8842_adapter *adapter) +{ + netdev_dbg(netdev, "%s: entry\n", __func__); + netdev->stats.rx_errors++; + netdev->stats.rx_fifo_errors++; +} + +void ks8842_tasklet(unsigned long arg) +{ + struct net_device *netdev = (struct net_device *)arg; + struct ks8842_adapter *adapter = netdev_priv(netdev); + u16 isr; + unsigned long flags; + u16 entry_bank; + + /* read current bank to be able to set it back */ + spin_lock_irqsave(&adapter->lock, flags); + entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); + spin_unlock_irqrestore(&adapter->lock, flags); + + isr = ks8842_read16(adapter, 18, REG_ISR); + netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr); + + /* when running in DMA mode, do not ack RX interrupts, it is handled + internally by timberdale, otherwise it's DMA FIFO:s would stop + */ + if (KS8842_USE_DMA(adapter)) + isr &= ~IRQ_RX; + + /* Ack */ + ks8842_write16(adapter, 18, isr, REG_ISR); + + if (!(adapter->conf_flags & MICREL_KS884X)) + /* Ack in the timberdale IP as well */ + iowrite32(0x1, adapter->hw_addr + REG_TIMB_IAR); + + if (!netif_running(netdev)) + return; + + if (isr & IRQ_LINK_CHANGE) + ks8842_update_link_status(netdev, adapter); + + /* should not get IRQ_RX when running DMA mode */ + if (isr & (IRQ_RX | IRQ_RX_ERROR) && !KS8842_USE_DMA(adapter)) + ks8842_handle_rx(netdev, adapter); + + /* should only happen when in PIO mode */ + if (isr & IRQ_TX) + ks8842_handle_tx(netdev, adapter); + + if (isr & IRQ_RX_OVERRUN) + ks8842_handle_rx_overrun(netdev, adapter); + + if (isr & IRQ_TX_STOPPED) { + ks8842_disable_tx(adapter); + ks8842_enable_tx(adapter); + } + + if (isr & IRQ_RX_STOPPED) { + ks8842_disable_rx(adapter); + ks8842_enable_rx(adapter); + } + + /* re-enable interrupts, put back the bank selection register */ + spin_lock_irqsave(&adapter->lock, flags); + if (KS8842_USE_DMA(adapter)) + ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER); + else + ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); + iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); + + /* Make sure timberdale continues DMA operations, they are stopped while + we are handling the ks8842 because we might change bank */ + if (KS8842_USE_DMA(adapter)) + ks8842_resume_dma(adapter); + + spin_unlock_irqrestore(&adapter->lock, flags); +} + +static irqreturn_t ks8842_irq(int irq, void *devid) +{ + struct net_device *netdev = devid; + struct ks8842_adapter *adapter = netdev_priv(netdev); + u16 isr; + u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); + irqreturn_t ret = IRQ_NONE; + + isr = ks8842_read16(adapter, 18, REG_ISR); + netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr); + + if (isr) { + if (KS8842_USE_DMA(adapter)) + /* disable all but RX IRQ, since the FPGA relies on it*/ + ks8842_write16(adapter, 18, IRQ_RX, REG_IER); + else + /* disable IRQ */ + ks8842_write16(adapter, 18, 0x00, REG_IER); + + /* schedule tasklet */ + tasklet_schedule(&adapter->tasklet); + + ret = IRQ_HANDLED; + } + + iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); + + /* After an interrupt, tell timberdale to continue DMA operations. + DMA is disabled while we are handling the ks8842 because we might + change bank */ + ks8842_resume_dma(adapter); + + return ret; +} + +static void ks8842_dma_rx_cb(void *data) +{ + struct net_device *netdev = data; + struct ks8842_adapter *adapter = netdev_priv(netdev); + + netdev_dbg(netdev, "RX DMA finished\n"); + /* schedule tasklet */ + if (adapter->dma_rx.adesc) + tasklet_schedule(&adapter->dma_rx.tasklet); +} + +static void ks8842_dma_tx_cb(void *data) +{ + struct net_device *netdev = data; + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx; + + netdev_dbg(netdev, "TX DMA finished\n"); + + if (!ctl->adesc) + return; + + netdev->stats.tx_packets++; + ctl->adesc = NULL; + + if (netif_queue_stopped(netdev)) + netif_wake_queue(netdev); +} + +static void ks8842_stop_dma(struct ks8842_adapter *adapter) +{ + struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; + struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; + + tx_ctl->adesc = NULL; + if (tx_ctl->chan) + tx_ctl->chan->device->device_control(tx_ctl->chan, + DMA_TERMINATE_ALL, 0); + + rx_ctl->adesc = NULL; + if (rx_ctl->chan) + rx_ctl->chan->device->device_control(rx_ctl->chan, + DMA_TERMINATE_ALL, 0); + + if (sg_dma_address(&rx_ctl->sg)) + dma_unmap_single(adapter->dev, sg_dma_address(&rx_ctl->sg), + DMA_BUFFER_SIZE, DMA_FROM_DEVICE); + sg_dma_address(&rx_ctl->sg) = 0; + + dev_kfree_skb(rx_ctl->skb); + rx_ctl->skb = NULL; +} + +static void ks8842_dealloc_dma_bufs(struct ks8842_adapter *adapter) +{ + struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; + struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; + + ks8842_stop_dma(adapter); + + if (tx_ctl->chan) + dma_release_channel(tx_ctl->chan); + tx_ctl->chan = NULL; + + if (rx_ctl->chan) + dma_release_channel(rx_ctl->chan); + rx_ctl->chan = NULL; + + tasklet_kill(&rx_ctl->tasklet); + + if (sg_dma_address(&tx_ctl->sg)) + dma_unmap_single(adapter->dev, sg_dma_address(&tx_ctl->sg), + DMA_BUFFER_SIZE, DMA_TO_DEVICE); + sg_dma_address(&tx_ctl->sg) = 0; + + kfree(tx_ctl->buf); + tx_ctl->buf = NULL; +} + +static bool ks8842_dma_filter_fn(struct dma_chan *chan, void *filter_param) +{ + return chan->chan_id == (long)filter_param; +} + +static int ks8842_alloc_dma_bufs(struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; + struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; + int err; + + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_PRIVATE, mask); + + sg_init_table(&tx_ctl->sg, 1); + + tx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn, + (void *)(long)tx_ctl->channel); + if (!tx_ctl->chan) { + err = -ENODEV; + goto err; + } + + /* allocate DMA buffer */ + tx_ctl->buf = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL); + if (!tx_ctl->buf) { + err = -ENOMEM; + goto err; + } + + sg_dma_address(&tx_ctl->sg) = dma_map_single(adapter->dev, + tx_ctl->buf, DMA_BUFFER_SIZE, DMA_TO_DEVICE); + err = dma_mapping_error(adapter->dev, + sg_dma_address(&tx_ctl->sg)); + if (err) { + sg_dma_address(&tx_ctl->sg) = 0; + goto err; + } + + rx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn, + (void *)(long)rx_ctl->channel); + if (!rx_ctl->chan) { + err = -ENODEV; + goto err; + } + + tasklet_init(&rx_ctl->tasklet, ks8842_rx_frame_dma_tasklet, + (unsigned long)netdev); + + return 0; +err: + ks8842_dealloc_dma_bufs(adapter); + return err; +} + +/* Netdevice operations */ + +static int ks8842_open(struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + int err; + + netdev_dbg(netdev, "%s - entry\n", __func__); + + if (KS8842_USE_DMA(adapter)) { + err = ks8842_alloc_dma_bufs(netdev); + + if (!err) { + /* start RX dma */ + err = __ks8842_start_new_rx_dma(netdev); + if (err) + ks8842_dealloc_dma_bufs(adapter); + } + + if (err) { + printk(KERN_WARNING DRV_NAME + ": Failed to initiate DMA, running PIO\n"); + ks8842_dealloc_dma_bufs(adapter); + adapter->dma_rx.channel = -1; + adapter->dma_tx.channel = -1; + } + } + + /* reset the HW */ + ks8842_reset_hw(adapter); + + ks8842_write_mac_addr(adapter, netdev->dev_addr); + + ks8842_update_link_status(netdev, adapter); + + err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME, + netdev); + if (err) { + pr_err("Failed to request IRQ: %d: %d\n", adapter->irq, err); + return err; + } + + return 0; +} + +static int ks8842_close(struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + + netdev_dbg(netdev, "%s - entry\n", __func__); + + cancel_work_sync(&adapter->timeout_work); + + if (KS8842_USE_DMA(adapter)) + ks8842_dealloc_dma_bufs(adapter); + + /* free the irq */ + free_irq(adapter->irq, netdev); + + /* disable the switch */ + ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE); + + return 0; +} + +static netdev_tx_t ks8842_xmit_frame(struct sk_buff *skb, + struct net_device *netdev) +{ + int ret; + struct ks8842_adapter *adapter = netdev_priv(netdev); + + netdev_dbg(netdev, "%s: entry\n", __func__); + + if (KS8842_USE_DMA(adapter)) { + unsigned long flags; + ret = ks8842_tx_frame_dma(skb, netdev); + /* for now only allow one transfer at the time */ + spin_lock_irqsave(&adapter->lock, flags); + if (adapter->dma_tx.adesc) + netif_stop_queue(netdev); + spin_unlock_irqrestore(&adapter->lock, flags); + return ret; + } + + ret = ks8842_tx_frame(skb, netdev); + + if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8) + netif_stop_queue(netdev); + + return ret; +} + +static int ks8842_set_mac(struct net_device *netdev, void *p) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct sockaddr *addr = p; + char *mac = (u8 *)addr->sa_data; + + netdev_dbg(netdev, "%s: entry\n", __func__); + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(netdev->dev_addr, mac, netdev->addr_len); + + ks8842_write_mac_addr(adapter, mac); + return 0; +} + +static void ks8842_tx_timeout_work(struct work_struct *work) +{ + struct ks8842_adapter *adapter = + container_of(work, struct ks8842_adapter, timeout_work); + struct net_device *netdev = adapter->netdev; + unsigned long flags; + + netdev_dbg(netdev, "%s: entry\n", __func__); + + spin_lock_irqsave(&adapter->lock, flags); + + if (KS8842_USE_DMA(adapter)) + ks8842_stop_dma(adapter); + + /* disable interrupts */ + ks8842_write16(adapter, 18, 0, REG_IER); + ks8842_write16(adapter, 18, 0xFFFF, REG_ISR); + + netif_stop_queue(netdev); + + spin_unlock_irqrestore(&adapter->lock, flags); + + ks8842_reset_hw(adapter); + + ks8842_write_mac_addr(adapter, netdev->dev_addr); + + ks8842_update_link_status(netdev, adapter); + + if (KS8842_USE_DMA(adapter)) + __ks8842_start_new_rx_dma(netdev); +} + +static void ks8842_tx_timeout(struct net_device *netdev) +{ + struct ks8842_adapter *adapter = netdev_priv(netdev); + + netdev_dbg(netdev, "%s: entry\n", __func__); + + schedule_work(&adapter->timeout_work); +} + +static const struct net_device_ops ks8842_netdev_ops = { + .ndo_open = ks8842_open, + .ndo_stop = ks8842_close, + .ndo_start_xmit = ks8842_xmit_frame, + .ndo_set_mac_address = ks8842_set_mac, + .ndo_tx_timeout = ks8842_tx_timeout, + .ndo_validate_addr = eth_validate_addr +}; + +static const struct ethtool_ops ks8842_ethtool_ops = { + .get_link = ethtool_op_get_link, +}; + +static int __devinit ks8842_probe(struct platform_device *pdev) +{ + int err = -ENOMEM; + struct resource *iomem; + struct net_device *netdev; + struct ks8842_adapter *adapter; + struct ks8842_platform_data *pdata = pdev->dev.platform_data; + u16 id; + unsigned i; + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) + goto err_mem_region; + + netdev = alloc_etherdev(sizeof(struct ks8842_adapter)); + if (!netdev) + goto err_alloc_etherdev; + + SET_NETDEV_DEV(netdev, &pdev->dev); + + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + INIT_WORK(&adapter->timeout_work, ks8842_tx_timeout_work); + adapter->hw_addr = ioremap(iomem->start, resource_size(iomem)); + adapter->conf_flags = iomem->flags; + + if (!adapter->hw_addr) + goto err_ioremap; + + adapter->irq = platform_get_irq(pdev, 0); + if (adapter->irq < 0) { + err = adapter->irq; + goto err_get_irq; + } + + adapter->dev = (pdev->dev.parent) ? pdev->dev.parent : &pdev->dev; + + /* DMA is only supported when accessed via timberdale */ + if (!(adapter->conf_flags & MICREL_KS884X) && pdata && + (pdata->tx_dma_channel != -1) && + (pdata->rx_dma_channel != -1)) { + adapter->dma_rx.channel = pdata->rx_dma_channel; + adapter->dma_tx.channel = pdata->tx_dma_channel; + } else { + adapter->dma_rx.channel = -1; + adapter->dma_tx.channel = -1; + } + + tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev); + spin_lock_init(&adapter->lock); + + netdev->netdev_ops = &ks8842_netdev_ops; + netdev->ethtool_ops = &ks8842_ethtool_ops; + + /* Check if a mac address was given */ + i = netdev->addr_len; + if (pdata) { + for (i = 0; i < netdev->addr_len; i++) + if (pdata->macaddr[i] != 0) + break; + + if (i < netdev->addr_len) + /* an address was passed, use it */ + memcpy(netdev->dev_addr, pdata->macaddr, + netdev->addr_len); + } + + if (i == netdev->addr_len) { + ks8842_read_mac_addr(adapter, netdev->dev_addr); + + if (!is_valid_ether_addr(netdev->dev_addr)) + random_ether_addr(netdev->dev_addr); + } + + id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE); + + strcpy(netdev->name, "eth%d"); + err = register_netdev(netdev); + if (err) + goto err_register; + + platform_set_drvdata(pdev, netdev); + + pr_info("Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n", + (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); + + return 0; + +err_register: +err_get_irq: + iounmap(adapter->hw_addr); +err_ioremap: + free_netdev(netdev); +err_alloc_etherdev: + release_mem_region(iomem->start, resource_size(iomem)); +err_mem_region: + return err; +} + +static int __devexit ks8842_remove(struct platform_device *pdev) +{ + struct net_device *netdev = platform_get_drvdata(pdev); + struct ks8842_adapter *adapter = netdev_priv(netdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + unregister_netdev(netdev); + tasklet_kill(&adapter->tasklet); + iounmap(adapter->hw_addr); + free_netdev(netdev); + release_mem_region(iomem->start, resource_size(iomem)); + platform_set_drvdata(pdev, NULL); + return 0; +} + + +static struct platform_driver ks8842_platform_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ks8842_probe, + .remove = ks8842_remove, +}; + +static int __init ks8842_init(void) +{ + return platform_driver_register(&ks8842_platform_driver); +} + +static void __exit ks8842_exit(void) +{ + platform_driver_unregister(&ks8842_platform_driver); +} + +module_init(ks8842_init); +module_exit(ks8842_exit); + +MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver"); +MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:ks8842"); + diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c new file mode 100644 index 000000000000..f56743a28fc0 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -0,0 +1,1737 @@ +/* drivers/net/ks8851.c + * + * Copyright 2009 Simtec Electronics + * http://www.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define DEBUG + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/cache.h> +#include <linux/crc32.h> +#include <linux/mii.h> + +#include <linux/spi/spi.h> + +#include "ks8851.h" + +/** + * struct ks8851_rxctrl - KS8851 driver rx control + * @mchash: Multicast hash-table data. + * @rxcr1: KS_RXCR1 register setting + * @rxcr2: KS_RXCR2 register setting + * + * Representation of the settings needs to control the receive filtering + * such as the multicast hash-filter and the receive register settings. This + * is used to make the job of working out if the receive settings change and + * then issuing the new settings to the worker that will send the necessary + * commands. + */ +struct ks8851_rxctrl { + u16 mchash[4]; + u16 rxcr1; + u16 rxcr2; +}; + +/** + * union ks8851_tx_hdr - tx header data + * @txb: The header as bytes + * @txw: The header as 16bit, little-endian words + * + * A dual representation of the tx header data to allow + * access to individual bytes, and to allow 16bit accesses + * with 16bit alignment. + */ +union ks8851_tx_hdr { + u8 txb[6]; + __le16 txw[3]; +}; + +/** + * struct ks8851_net - KS8851 driver private data + * @netdev: The network device we're bound to + * @spidev: The spi device we're bound to. + * @lock: Lock to ensure that the device is not accessed when busy. + * @statelock: Lock on this structure for tx list. + * @mii: The MII state information for the mii calls. + * @rxctrl: RX settings for @rxctrl_work. + * @tx_work: Work queue for tx packets + * @irq_work: Work queue for servicing interrupts + * @rxctrl_work: Work queue for updating RX mode and multicast lists + * @txq: Queue of packets for transmission. + * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. + * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. + * @txh: Space for generating packet TX header in DMA-able data + * @rxd: Space for receiving SPI data, in DMA-able space. + * @txd: Space for transmitting SPI data, in DMA-able space. + * @msg_enable: The message flags controlling driver output (see ethtool). + * @fid: Incrementing frame id tag. + * @rc_ier: Cached copy of KS_IER. + * @rc_ccr: Cached copy of KS_CCR. + * @rc_rxqcr: Cached copy of KS_RXQCR. + * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom + * + * The @lock ensures that the chip is protected when certain operations are + * in progress. When the read or write packet transfer is in progress, most + * of the chip registers are not ccessible until the transfer is finished and + * the DMA has been de-asserted. + * + * The @statelock is used to protect information in the structure which may + * need to be accessed via several sources, such as the network driver layer + * or one of the work queues. + * + * We align the buffers we may use for rx/tx to ensure that if the SPI driver + * wants to DMA map them, it will not have any problems with data the driver + * modifies. + */ +struct ks8851_net { + struct net_device *netdev; + struct spi_device *spidev; + struct mutex lock; + spinlock_t statelock; + + union ks8851_tx_hdr txh ____cacheline_aligned; + u8 rxd[8]; + u8 txd[8]; + + u32 msg_enable ____cacheline_aligned; + u16 tx_space; + u8 fid; + + u16 rc_ier; + u16 rc_rxqcr; + u16 rc_ccr; + u16 eeprom_size; + + struct mii_if_info mii; + struct ks8851_rxctrl rxctrl; + + struct work_struct tx_work; + struct work_struct irq_work; + struct work_struct rxctrl_work; + + struct sk_buff_head txq; + + struct spi_message spi_msg1; + struct spi_message spi_msg2; + struct spi_transfer spi_xfer1; + struct spi_transfer spi_xfer2[2]; +}; + +static int msg_enable; + +/* shift for byte-enable data */ +#define BYTE_EN(_x) ((_x) << 2) + +/* turn register number and byte-enable mask into data for start of packet */ +#define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) + +/* SPI register read/write calls. + * + * All these calls issue SPI transactions to access the chip's registers. They + * all require that the necessary lock is held to prevent accesses when the + * chip is busy transferring packet data (RX/TX FIFO accesses). + */ + +/** + * ks8851_wrreg16 - write 16bit register value to chip + * @ks: The chip state + * @reg: The register address + * @val: The value to write + * + * Issue a write to put the value @val into the register specified in @reg. + */ +static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) +{ + struct spi_transfer *xfer = &ks->spi_xfer1; + struct spi_message *msg = &ks->spi_msg1; + __le16 txb[2]; + int ret; + + txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); + txb[1] = cpu_to_le16(val); + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 4; + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "spi_sync() failed\n"); +} + +/** + * ks8851_wrreg8 - write 8bit register value to chip + * @ks: The chip state + * @reg: The register address + * @val: The value to write + * + * Issue a write to put the value @val into the register specified in @reg. + */ +static void ks8851_wrreg8(struct ks8851_net *ks, unsigned reg, unsigned val) +{ + struct spi_transfer *xfer = &ks->spi_xfer1; + struct spi_message *msg = &ks->spi_msg1; + __le16 txb[2]; + int ret; + int bit; + + bit = 1 << (reg & 3); + + txb[0] = cpu_to_le16(MK_OP(bit, reg) | KS_SPIOP_WR); + txb[1] = val; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 3; + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "spi_sync() failed\n"); +} + +/** + * ks8851_rx_1msg - select whether to use one or two messages for spi read + * @ks: The device structure + * + * Return whether to generate a single message with a tx and rx buffer + * supplied to spi_sync(), or alternatively send the tx and rx buffers + * as separate messages. + * + * Depending on the hardware in use, a single message may be more efficient + * on interrupts or work done by the driver. + * + * This currently always returns true until we add some per-device data passed + * from the platform code to specify which mode is better. + */ +static inline bool ks8851_rx_1msg(struct ks8851_net *ks) +{ + return true; +} + +/** + * ks8851_rdreg - issue read register command and return the data + * @ks: The device state + * @op: The register address and byte enables in message format. + * @rxb: The RX buffer to return the result into + * @rxl: The length of data expected. + * + * This is the low level read call that issues the necessary spi message(s) + * to read data from the register specified in @op. + */ +static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, + u8 *rxb, unsigned rxl) +{ + struct spi_transfer *xfer; + struct spi_message *msg; + __le16 *txb = (__le16 *)ks->txd; + u8 *trx = ks->rxd; + int ret; + + txb[0] = cpu_to_le16(op | KS_SPIOP_RD); + + if (ks8851_rx_1msg(ks)) { + msg = &ks->spi_msg1; + xfer = &ks->spi_xfer1; + + xfer->tx_buf = txb; + xfer->rx_buf = trx; + xfer->len = rxl + 2; + } else { + msg = &ks->spi_msg2; + xfer = ks->spi_xfer2; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 2; + + xfer++; + xfer->tx_buf = NULL; + xfer->rx_buf = trx; + xfer->len = rxl; + } + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "read: spi_sync() failed\n"); + else if (ks8851_rx_1msg(ks)) + memcpy(rxb, trx + 2, rxl); + else + memcpy(rxb, trx, rxl); +} + +/** + * ks8851_rdreg8 - read 8 bit register from device + * @ks: The chip information + * @reg: The register address + * + * Read a 8bit register from the chip, returning the result +*/ +static unsigned ks8851_rdreg8(struct ks8851_net *ks, unsigned reg) +{ + u8 rxb[1]; + + ks8851_rdreg(ks, MK_OP(1 << (reg & 3), reg), rxb, 1); + return rxb[0]; +} + +/** + * ks8851_rdreg16 - read 16 bit register from device + * @ks: The chip information + * @reg: The register address + * + * Read a 16bit register from the chip, returning the result +*/ +static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) +{ + __le16 rx = 0; + + ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); + return le16_to_cpu(rx); +} + +/** + * ks8851_rdreg32 - read 32 bit register from device + * @ks: The chip information + * @reg: The register address + * + * Read a 32bit register from the chip. + * + * Note, this read requires the address be aligned to 4 bytes. +*/ +static unsigned ks8851_rdreg32(struct ks8851_net *ks, unsigned reg) +{ + __le32 rx = 0; + + WARN_ON(reg & 3); + + ks8851_rdreg(ks, MK_OP(0xf, reg), (u8 *)&rx, 4); + return le32_to_cpu(rx); +} + +/** + * ks8851_soft_reset - issue one of the soft reset to the device + * @ks: The device state. + * @op: The bit(s) to set in the GRR + * + * Issue the relevant soft-reset command to the device's GRR register + * specified by @op. + * + * Note, the delays are in there as a caution to ensure that the reset + * has time to take effect and then complete. Since the datasheet does + * not currently specify the exact sequence, we have chosen something + * that seems to work with our device. + */ +static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op) +{ + ks8851_wrreg16(ks, KS_GRR, op); + mdelay(1); /* wait a short time to effect reset */ + ks8851_wrreg16(ks, KS_GRR, 0); + mdelay(1); /* wait for condition to clear */ +} + +/** + * ks8851_write_mac_addr - write mac address to device registers + * @dev: The network device + * + * Update the KS8851 MAC address registers from the address in @dev. + * + * This call assumes that the chip is not running, so there is no need to + * shutdown the RXQ process whilst setting this. +*/ +static int ks8851_write_mac_addr(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + int i; + + mutex_lock(&ks->lock); + + for (i = 0; i < ETH_ALEN; i++) + ks8851_wrreg8(ks, KS_MAR(i), dev->dev_addr[i]); + + mutex_unlock(&ks->lock); + + return 0; +} + +/** + * ks8851_init_mac - initialise the mac address + * @ks: The device structure + * + * Get or create the initial mac address for the device and then set that + * into the station address register. Currently we assume that the device + * does not have a valid mac address in it, and so we use random_ether_addr() + * to create a new one. + * + * In future, the driver should check to see if the device has an EEPROM + * attached and whether that has a valid ethernet address in it. + */ +static void ks8851_init_mac(struct ks8851_net *ks) +{ + struct net_device *dev = ks->netdev; + + random_ether_addr(dev->dev_addr); + ks8851_write_mac_addr(dev); +} + +/** + * ks8851_irq - device interrupt handler + * @irq: Interrupt number passed from the IRQ hnalder. + * @pw: The private word passed to register_irq(), our struct ks8851_net. + * + * Disable the interrupt from happening again until we've processed the + * current status by scheduling ks8851_irq_work(). + */ +static irqreturn_t ks8851_irq(int irq, void *pw) +{ + struct ks8851_net *ks = pw; + + disable_irq_nosync(irq); + schedule_work(&ks->irq_work); + return IRQ_HANDLED; +} + +/** + * ks8851_rdfifo - read data from the receive fifo + * @ks: The device state. + * @buff: The buffer address + * @len: The length of the data to read + * + * Issue an RXQ FIFO read command and read the @len amount of data from + * the FIFO into the buffer specified by @buff. + */ +static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) +{ + struct spi_transfer *xfer = ks->spi_xfer2; + struct spi_message *msg = &ks->spi_msg2; + u8 txb[1]; + int ret; + + netif_dbg(ks, rx_status, ks->netdev, + "%s: %d@%p\n", __func__, len, buff); + + /* set the operation we're issuing */ + txb[0] = KS_SPIOP_RXFIFO; + + xfer->tx_buf = txb; + xfer->rx_buf = NULL; + xfer->len = 1; + + xfer++; + xfer->rx_buf = buff; + xfer->tx_buf = NULL; + xfer->len = len; + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); +} + +/** + * ks8851_dbg_dumpkkt - dump initial packet contents to debug + * @ks: The device state + * @rxpkt: The data for the received packet + * + * Dump the initial data from the packet to dev_dbg(). +*/ +static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) +{ + netdev_dbg(ks->netdev, + "pkt %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", + rxpkt[4], rxpkt[5], rxpkt[6], rxpkt[7], + rxpkt[8], rxpkt[9], rxpkt[10], rxpkt[11], + rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); +} + +/** + * ks8851_rx_pkts - receive packets from the host + * @ks: The device information. + * + * This is called from the IRQ work queue when the system detects that there + * are packets in the receive queue. Find out how many packets there are and + * read them from the FIFO. + */ +static void ks8851_rx_pkts(struct ks8851_net *ks) +{ + struct sk_buff *skb; + unsigned rxfc; + unsigned rxlen; + unsigned rxstat; + u32 rxh; + u8 *rxpkt; + + rxfc = ks8851_rdreg8(ks, KS_RXFC); + + netif_dbg(ks, rx_status, ks->netdev, + "%s: %d packets\n", __func__, rxfc); + + /* Currently we're issuing a read per packet, but we could possibly + * improve the code by issuing a single read, getting the receive + * header, allocating the packet and then reading the packet data + * out in one go. + * + * This form of operation would require us to hold the SPI bus' + * chipselect low during the entie transaction to avoid any + * reset to the data stream coming from the chip. + */ + + for (; rxfc != 0; rxfc--) { + rxh = ks8851_rdreg32(ks, KS_RXFHSR); + rxstat = rxh & 0xffff; + rxlen = rxh >> 16; + + netif_dbg(ks, rx_status, ks->netdev, + "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); + + /* the length of the packet includes the 32bit CRC */ + + /* set dma read address */ + ks8851_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI | 0x00); + + /* start the packet dma process, and set auto-dequeue rx */ + ks8851_wrreg16(ks, KS_RXQCR, + ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); + + if (rxlen > 4) { + unsigned int rxalign; + + rxlen -= 4; + rxalign = ALIGN(rxlen, 4); + skb = netdev_alloc_skb_ip_align(ks->netdev, rxalign); + if (skb) { + + /* 4 bytes of status header + 4 bytes of + * garbage: we put them before ethernet + * header, so that they are copied, + * but ignored. + */ + + rxpkt = skb_put(skb, rxlen) - 8; + + ks8851_rdfifo(ks, rxpkt, rxalign + 8); + + if (netif_msg_pktdata(ks)) + ks8851_dbg_dumpkkt(ks, rxpkt); + + skb->protocol = eth_type_trans(skb, ks->netdev); + netif_rx(skb); + + ks->netdev->stats.rx_packets++; + ks->netdev->stats.rx_bytes += rxlen; + } + } + + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + } +} + +/** + * ks8851_irq_work - work queue handler for dealing with interrupt requests + * @work: The work structure that was scheduled by schedule_work() + * + * This is the handler invoked when the ks8851_irq() is called to find out + * what happened, as we cannot allow ourselves to sleep whilst waiting for + * anything other process has the chip's lock. + * + * Read the interrupt status, work out what needs to be done and then clear + * any of the interrupts that are not needed. + */ +static void ks8851_irq_work(struct work_struct *work) +{ + struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work); + unsigned status; + unsigned handled = 0; + + mutex_lock(&ks->lock); + + status = ks8851_rdreg16(ks, KS_ISR); + + netif_dbg(ks, intr, ks->netdev, + "%s: status 0x%04x\n", __func__, status); + + if (status & IRQ_LCI) { + /* should do something about checking link status */ + handled |= IRQ_LCI; + } + + if (status & IRQ_LDI) { + u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); + pmecr &= ~PMECR_WKEVT_MASK; + ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); + + handled |= IRQ_LDI; + } + + if (status & IRQ_RXPSI) + handled |= IRQ_RXPSI; + + if (status & IRQ_TXI) { + handled |= IRQ_TXI; + + /* no lock here, tx queue should have been stopped */ + + /* update our idea of how much tx space is available to the + * system */ + ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); + + netif_dbg(ks, intr, ks->netdev, + "%s: txspace %d\n", __func__, ks->tx_space); + } + + if (status & IRQ_RXI) + handled |= IRQ_RXI; + + if (status & IRQ_SPIBEI) { + dev_err(&ks->spidev->dev, "%s: spi bus error\n", __func__); + handled |= IRQ_SPIBEI; + } + + ks8851_wrreg16(ks, KS_ISR, handled); + + if (status & IRQ_RXI) { + /* the datasheet says to disable the rx interrupt during + * packet read-out, however we're masking the interrupt + * from the device so do not bother masking just the RX + * from the device. */ + + ks8851_rx_pkts(ks); + } + + /* if something stopped the rx process, probably due to wanting + * to change the rx settings, then do something about restarting + * it. */ + if (status & IRQ_RXPSI) { + struct ks8851_rxctrl *rxc = &ks->rxctrl; + + /* update the multicast hash table */ + ks8851_wrreg16(ks, KS_MAHTR0, rxc->mchash[0]); + ks8851_wrreg16(ks, KS_MAHTR1, rxc->mchash[1]); + ks8851_wrreg16(ks, KS_MAHTR2, rxc->mchash[2]); + ks8851_wrreg16(ks, KS_MAHTR3, rxc->mchash[3]); + + ks8851_wrreg16(ks, KS_RXCR2, rxc->rxcr2); + ks8851_wrreg16(ks, KS_RXCR1, rxc->rxcr1); + } + + mutex_unlock(&ks->lock); + + if (status & IRQ_TXI) + netif_wake_queue(ks->netdev); + + enable_irq(ks->netdev->irq); +} + +/** + * calc_txlen - calculate size of message to send packet + * @len: Length of data + * + * Returns the size of the TXFIFO message needed to send + * this packet. + */ +static inline unsigned calc_txlen(unsigned len) +{ + return ALIGN(len + 4, 4); +} + +/** + * ks8851_wrpkt - write packet to TX FIFO + * @ks: The device state. + * @txp: The sk_buff to transmit. + * @irq: IRQ on completion of the packet. + * + * Send the @txp to the chip. This means creating the relevant packet header + * specifying the length of the packet and the other information the chip + * needs, such as IRQ on completion. Send the header and the packet data to + * the device. + */ +static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) +{ + struct spi_transfer *xfer = ks->spi_xfer2; + struct spi_message *msg = &ks->spi_msg2; + unsigned fid = 0; + int ret; + + netif_dbg(ks, tx_queued, ks->netdev, "%s: skb %p, %d@%p, irq %d\n", + __func__, txp, txp->len, txp->data, irq); + + fid = ks->fid++; + fid &= TXFR_TXFID_MASK; + + if (irq) + fid |= TXFR_TXIC; /* irq on completion */ + + /* start header at txb[1] to align txw entries */ + ks->txh.txb[1] = KS_SPIOP_TXFIFO; + ks->txh.txw[1] = cpu_to_le16(fid); + ks->txh.txw[2] = cpu_to_le16(txp->len); + + xfer->tx_buf = &ks->txh.txb[1]; + xfer->rx_buf = NULL; + xfer->len = 5; + + xfer++; + xfer->tx_buf = txp->data; + xfer->rx_buf = NULL; + xfer->len = ALIGN(txp->len, 4); + + ret = spi_sync(ks->spidev, msg); + if (ret < 0) + netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); +} + +/** + * ks8851_done_tx - update and then free skbuff after transmitting + * @ks: The device state + * @txb: The buffer transmitted + */ +static void ks8851_done_tx(struct ks8851_net *ks, struct sk_buff *txb) +{ + struct net_device *dev = ks->netdev; + + dev->stats.tx_bytes += txb->len; + dev->stats.tx_packets++; + + dev_kfree_skb(txb); +} + +/** + * ks8851_tx_work - process tx packet(s) + * @work: The work strucutre what was scheduled. + * + * This is called when a number of packets have been scheduled for + * transmission and need to be sent to the device. + */ +static void ks8851_tx_work(struct work_struct *work) +{ + struct ks8851_net *ks = container_of(work, struct ks8851_net, tx_work); + struct sk_buff *txb; + bool last = skb_queue_empty(&ks->txq); + + mutex_lock(&ks->lock); + + while (!last) { + txb = skb_dequeue(&ks->txq); + last = skb_queue_empty(&ks->txq); + + if (txb != NULL) { + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); + ks8851_wrpkt(ks, txb, last); + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); + + ks8851_done_tx(ks, txb); + } + } + + mutex_unlock(&ks->lock); +} + +/** + * ks8851_set_powermode - set power mode of the device + * @ks: The device state + * @pwrmode: The power mode value to write to KS_PMECR. + * + * Change the power mode of the chip. + */ +static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode) +{ + unsigned pmecr; + + netif_dbg(ks, hw, ks->netdev, "setting power mode %d\n", pwrmode); + + pmecr = ks8851_rdreg16(ks, KS_PMECR); + pmecr &= ~PMECR_PM_MASK; + pmecr |= pwrmode; + + ks8851_wrreg16(ks, KS_PMECR, pmecr); +} + +/** + * ks8851_net_open - open network device + * @dev: The network device being opened. + * + * Called when the network device is marked active, such as a user executing + * 'ifconfig up' on the device. + */ +static int ks8851_net_open(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + + /* lock the card, even if we may not actually be doing anything + * else at the moment */ + mutex_lock(&ks->lock); + + netif_dbg(ks, ifup, ks->netdev, "opening\n"); + + /* bring chip out of any power saving mode it was in */ + ks8851_set_powermode(ks, PMECR_PM_NORMAL); + + /* issue a soft reset to the RX/TX QMU to put it into a known + * state. */ + ks8851_soft_reset(ks, GRR_QMU); + + /* setup transmission parameters */ + + ks8851_wrreg16(ks, KS_TXCR, (TXCR_TXE | /* enable transmit process */ + TXCR_TXPE | /* pad to min length */ + TXCR_TXCRC | /* add CRC */ + TXCR_TXFCE)); /* enable flow control */ + + /* auto-increment tx data, reset tx pointer */ + ks8851_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI); + + /* setup receiver control */ + + ks8851_wrreg16(ks, KS_RXCR1, (RXCR1_RXPAFMA | /* from mac filter */ + RXCR1_RXFCE | /* enable flow control */ + RXCR1_RXBE | /* broadcast enable */ + RXCR1_RXUE | /* unicast enable */ + RXCR1_RXE)); /* enable rx block */ + + /* transfer entire frames out in one go */ + ks8851_wrreg16(ks, KS_RXCR2, RXCR2_SRDBL_FRAME); + + /* set receive counter timeouts */ + ks8851_wrreg16(ks, KS_RXDTTR, 1000); /* 1ms after first frame to IRQ */ + ks8851_wrreg16(ks, KS_RXDBCTR, 4096); /* >4Kbytes in buffer to IRQ */ + ks8851_wrreg16(ks, KS_RXFCTR, 10); /* 10 frames to IRQ */ + + ks->rc_rxqcr = (RXQCR_RXFCTE | /* IRQ on frame count exceeded */ + RXQCR_RXDBCTE | /* IRQ on byte count exceeded */ + RXQCR_RXDTTE); /* IRQ on time exceeded */ + + ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + + /* clear then enable interrupts */ + +#define STD_IRQ (IRQ_LCI | /* Link Change */ \ + IRQ_TXI | /* TX done */ \ + IRQ_RXI | /* RX done */ \ + IRQ_SPIBEI | /* SPI bus error */ \ + IRQ_TXPSI | /* TX process stop */ \ + IRQ_RXPSI) /* RX process stop */ + + ks->rc_ier = STD_IRQ; + ks8851_wrreg16(ks, KS_ISR, STD_IRQ); + ks8851_wrreg16(ks, KS_IER, STD_IRQ); + + netif_start_queue(ks->netdev); + + netif_dbg(ks, ifup, ks->netdev, "network device up\n"); + + mutex_unlock(&ks->lock); + return 0; +} + +/** + * ks8851_net_stop - close network device + * @dev: The device being closed. + * + * Called to close down a network device which has been active. Cancell any + * work, shutdown the RX and TX process and then place the chip into a low + * power state whilst it is not being used. + */ +static int ks8851_net_stop(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + + netif_info(ks, ifdown, dev, "shutting down\n"); + + netif_stop_queue(dev); + + mutex_lock(&ks->lock); + + /* stop any outstanding work */ + flush_work(&ks->irq_work); + flush_work(&ks->tx_work); + flush_work(&ks->rxctrl_work); + + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); + + /* shutdown RX process */ + ks8851_wrreg16(ks, KS_RXCR1, 0x0000); + + /* shutdown TX process */ + ks8851_wrreg16(ks, KS_TXCR, 0x0000); + + /* set powermode to soft power down to save power */ + ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); + + /* ensure any queued tx buffers are dumped */ + while (!skb_queue_empty(&ks->txq)) { + struct sk_buff *txb = skb_dequeue(&ks->txq); + + netif_dbg(ks, ifdown, ks->netdev, + "%s: freeing txb %p\n", __func__, txb); + + dev_kfree_skb(txb); + } + + mutex_unlock(&ks->lock); + return 0; +} + +/** + * ks8851_start_xmit - transmit packet + * @skb: The buffer to transmit + * @dev: The device used to transmit the packet. + * + * Called by the network layer to transmit the @skb. Queue the packet for + * the device and schedule the necessary work to transmit the packet when + * it is free. + * + * We do this to firstly avoid sleeping with the network device locked, + * and secondly so we can round up more than one packet to transmit which + * means we can try and avoid generating too many transmit done interrupts. + */ +static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + unsigned needed = calc_txlen(skb->len); + netdev_tx_t ret = NETDEV_TX_OK; + + netif_dbg(ks, tx_queued, ks->netdev, + "%s: skb %p, %d@%p\n", __func__, skb, skb->len, skb->data); + + spin_lock(&ks->statelock); + + if (needed > ks->tx_space) { + netif_stop_queue(dev); + ret = NETDEV_TX_BUSY; + } else { + ks->tx_space -= needed; + skb_queue_tail(&ks->txq, skb); + } + + spin_unlock(&ks->statelock); + schedule_work(&ks->tx_work); + + return ret; +} + +/** + * ks8851_rxctrl_work - work handler to change rx mode + * @work: The work structure this belongs to. + * + * Lock the device and issue the necessary changes to the receive mode from + * the network device layer. This is done so that we can do this without + * having to sleep whilst holding the network device lock. + * + * Since the recommendation from Micrel is that the RXQ is shutdown whilst the + * receive parameters are programmed, we issue a write to disable the RXQ and + * then wait for the interrupt handler to be triggered once the RXQ shutdown is + * complete. The interrupt handler then writes the new values into the chip. + */ +static void ks8851_rxctrl_work(struct work_struct *work) +{ + struct ks8851_net *ks = container_of(work, struct ks8851_net, rxctrl_work); + + mutex_lock(&ks->lock); + + /* need to shutdown RXQ before modifying filter parameters */ + ks8851_wrreg16(ks, KS_RXCR1, 0x00); + + mutex_unlock(&ks->lock); +} + +static void ks8851_set_rx_mode(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + struct ks8851_rxctrl rxctrl; + + memset(&rxctrl, 0, sizeof(rxctrl)); + + if (dev->flags & IFF_PROMISC) { + /* interface to receive everything */ + + rxctrl.rxcr1 = RXCR1_RXAE | RXCR1_RXINVF; + } else if (dev->flags & IFF_ALLMULTI) { + /* accept all multicast packets */ + + rxctrl.rxcr1 = (RXCR1_RXME | RXCR1_RXAE | + RXCR1_RXPAFMA | RXCR1_RXMAFMA); + } else if (dev->flags & IFF_MULTICAST && !netdev_mc_empty(dev)) { + struct netdev_hw_addr *ha; + u32 crc; + + /* accept some multicast */ + + netdev_for_each_mc_addr(ha, dev) { + crc = ether_crc(ETH_ALEN, ha->addr); + crc >>= (32 - 6); /* get top six bits */ + + rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); + } + + rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA; + } else { + /* just accept broadcast / unicast */ + rxctrl.rxcr1 = RXCR1_RXPAFMA; + } + + rxctrl.rxcr1 |= (RXCR1_RXUE | /* unicast enable */ + RXCR1_RXBE | /* broadcast enable */ + RXCR1_RXE | /* RX process enable */ + RXCR1_RXFCE); /* enable flow control */ + + rxctrl.rxcr2 |= RXCR2_SRDBL_FRAME; + + /* schedule work to do the actual set of the data if needed */ + + spin_lock(&ks->statelock); + + if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) { + memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl)); + schedule_work(&ks->rxctrl_work); + } + + spin_unlock(&ks->statelock); +} + +static int ks8851_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *sa = addr; + + if (netif_running(dev)) + return -EBUSY; + + if (!is_valid_ether_addr(sa->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); + return ks8851_write_mac_addr(dev); +} + +static int ks8851_net_ioctl(struct net_device *dev, struct ifreq *req, int cmd) +{ + struct ks8851_net *ks = netdev_priv(dev); + + if (!netif_running(dev)) + return -EINVAL; + + return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL); +} + +static const struct net_device_ops ks8851_netdev_ops = { + .ndo_open = ks8851_net_open, + .ndo_stop = ks8851_net_stop, + .ndo_do_ioctl = ks8851_net_ioctl, + .ndo_start_xmit = ks8851_start_xmit, + .ndo_set_mac_address = ks8851_set_mac_address, + .ndo_set_rx_mode = ks8851_set_rx_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + +/* Companion eeprom access */ + +enum { /* EEPROM programming states */ + EEPROM_CONTROL, + EEPROM_ADDRESS, + EEPROM_DATA, + EEPROM_COMPLETE +}; + +/** + * ks8851_eeprom_read - read a 16bits word in ks8851 companion EEPROM + * @dev: The network device the PHY is on. + * @addr: EEPROM address to read + * + * eeprom_size: used to define the data coding length. Can be changed + * through debug-fs. + * + * Programs a read on the EEPROM using ks8851 EEPROM SW access feature. + * Warning: The READ feature is not supported on ks8851 revision 0. + * + * Rough programming model: + * - on period start: set clock high and read value on bus + * - on period / 2: set clock low and program value on bus + * - start on period / 2 + */ +unsigned int ks8851_eeprom_read(struct net_device *dev, unsigned int addr) +{ + struct ks8851_net *ks = netdev_priv(dev); + int eepcr; + int ctrl = EEPROM_OP_READ; + int state = EEPROM_CONTROL; + int bit_count = EEPROM_OP_LEN - 1; + unsigned int data = 0; + int dummy; + unsigned int addr_len; + + addr_len = (ks->eeprom_size == 128) ? 6 : 8; + + /* start transaction: chip select high, authorize write */ + mutex_lock(&ks->lock); + eepcr = EEPCR_EESA | EEPCR_EESRWA; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + eepcr |= EEPCR_EECS; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + while (state != EEPROM_COMPLETE) { + /* falling clock period starts... */ + /* set EED_IO pin for control and address */ + eepcr &= ~EEPCR_EEDO; + switch (state) { + case EEPROM_CONTROL: + eepcr |= ((ctrl >> bit_count) & 1) << 2; + if (bit_count-- <= 0) { + bit_count = addr_len - 1; + state = EEPROM_ADDRESS; + } + break; + case EEPROM_ADDRESS: + eepcr |= ((addr >> bit_count) & 1) << 2; + bit_count--; + break; + case EEPROM_DATA: + /* Change to receive mode */ + eepcr &= ~EEPCR_EESRWA; + break; + } + + /* lower clock */ + eepcr &= ~EEPCR_EESCK; + + mutex_lock(&ks->lock); + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + /* waitread period / 2 */ + udelay(EEPROM_SK_PERIOD / 2); + + /* rising clock period starts... */ + + /* raise clock */ + mutex_lock(&ks->lock); + eepcr |= EEPCR_EESCK; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + /* Manage read */ + switch (state) { + case EEPROM_ADDRESS: + if (bit_count < 0) { + bit_count = EEPROM_DATA_LEN - 1; + state = EEPROM_DATA; + } + break; + case EEPROM_DATA: + mutex_lock(&ks->lock); + dummy = ks8851_rdreg16(ks, KS_EEPCR); + mutex_unlock(&ks->lock); + data |= ((dummy >> EEPCR_EESB_OFFSET) & 1) << bit_count; + if (bit_count-- <= 0) + state = EEPROM_COMPLETE; + break; + } + + /* wait period / 2 */ + udelay(EEPROM_SK_PERIOD / 2); + } + + /* close transaction */ + mutex_lock(&ks->lock); + eepcr &= ~EEPCR_EECS; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + eepcr = 0; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + return data; +} + +/** + * ks8851_eeprom_write - write a 16bits word in ks8851 companion EEPROM + * @dev: The network device the PHY is on. + * @op: operand (can be WRITE, EWEN, EWDS) + * @addr: EEPROM address to write + * @data: data to write + * + * eeprom_size: used to define the data coding length. Can be changed + * through debug-fs. + * + * Programs a write on the EEPROM using ks8851 EEPROM SW access feature. + * + * Note that a write enable is required before writing data. + * + * Rough programming model: + * - on period start: set clock high + * - on period / 2: set clock low and program value on bus + * - start on period / 2 + */ +void ks8851_eeprom_write(struct net_device *dev, unsigned int op, + unsigned int addr, unsigned int data) +{ + struct ks8851_net *ks = netdev_priv(dev); + int eepcr; + int state = EEPROM_CONTROL; + int bit_count = EEPROM_OP_LEN - 1; + unsigned int addr_len; + + addr_len = (ks->eeprom_size == 128) ? 6 : 8; + + switch (op) { + case EEPROM_OP_EWEN: + addr = 0x30; + break; + case EEPROM_OP_EWDS: + addr = 0; + break; + } + + /* start transaction: chip select high, authorize write */ + mutex_lock(&ks->lock); + eepcr = EEPCR_EESA | EEPCR_EESRWA; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + eepcr |= EEPCR_EECS; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + while (state != EEPROM_COMPLETE) { + /* falling clock period starts... */ + /* set EED_IO pin for control and address */ + eepcr &= ~EEPCR_EEDO; + switch (state) { + case EEPROM_CONTROL: + eepcr |= ((op >> bit_count) & 1) << 2; + if (bit_count-- <= 0) { + bit_count = addr_len - 1; + state = EEPROM_ADDRESS; + } + break; + case EEPROM_ADDRESS: + eepcr |= ((addr >> bit_count) & 1) << 2; + if (bit_count-- <= 0) { + if (op == EEPROM_OP_WRITE) { + bit_count = EEPROM_DATA_LEN - 1; + state = EEPROM_DATA; + } else { + state = EEPROM_COMPLETE; + } + } + break; + case EEPROM_DATA: + eepcr |= ((data >> bit_count) & 1) << 2; + if (bit_count-- <= 0) + state = EEPROM_COMPLETE; + break; + } + + /* lower clock */ + eepcr &= ~EEPCR_EESCK; + + mutex_lock(&ks->lock); + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + /* wait period / 2 */ + udelay(EEPROM_SK_PERIOD / 2); + + /* rising clock period starts... */ + + /* raise clock */ + eepcr |= EEPCR_EESCK; + mutex_lock(&ks->lock); + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + + /* wait period / 2 */ + udelay(EEPROM_SK_PERIOD / 2); + } + + /* close transaction */ + mutex_lock(&ks->lock); + eepcr &= ~EEPCR_EECS; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + eepcr = 0; + ks8851_wrreg16(ks, KS_EEPCR, eepcr); + mutex_unlock(&ks->lock); + +} + +/* ethtool support */ + +static void ks8851_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *di) +{ + strlcpy(di->driver, "KS8851", sizeof(di->driver)); + strlcpy(di->version, "1.00", sizeof(di->version)); + strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); +} + +static u32 ks8851_get_msglevel(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + return ks->msg_enable; +} + +static void ks8851_set_msglevel(struct net_device *dev, u32 to) +{ + struct ks8851_net *ks = netdev_priv(dev); + ks->msg_enable = to; +} + +static int ks8851_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ks8851_net *ks = netdev_priv(dev); + return mii_ethtool_gset(&ks->mii, cmd); +} + +static int ks8851_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ks8851_net *ks = netdev_priv(dev); + return mii_ethtool_sset(&ks->mii, cmd); +} + +static u32 ks8851_get_link(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + return mii_link_ok(&ks->mii); +} + +static int ks8851_nway_reset(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + return mii_nway_restart(&ks->mii); +} + +static int ks8851_get_eeprom_len(struct net_device *dev) +{ + struct ks8851_net *ks = netdev_priv(dev); + return ks->eeprom_size; +} + +static int ks8851_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct ks8851_net *ks = netdev_priv(dev); + u16 *eeprom_buff; + int first_word; + int last_word; + int ret_val = 0; + u16 i; + + if (eeprom->len == 0) + return -EINVAL; + + if (eeprom->len > ks->eeprom_size) + return -EINVAL; + + eeprom->magic = ks8851_rdreg16(ks, KS_CIDER); + + first_word = eeprom->offset >> 1; + last_word = (eeprom->offset + eeprom->len - 1) >> 1; + + eeprom_buff = kmalloc(sizeof(u16) * + (last_word - first_word + 1), GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + for (i = 0; i < last_word - first_word + 1; i++) + eeprom_buff[i] = ks8851_eeprom_read(dev, first_word + 1); + + /* Device's eeprom is little-endian, word addressable */ + for (i = 0; i < last_word - first_word + 1; i++) + le16_to_cpus(&eeprom_buff[i]); + + memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); + kfree(eeprom_buff); + + return ret_val; +} + +static int ks8851_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct ks8851_net *ks = netdev_priv(dev); + u16 *eeprom_buff; + void *ptr; + int max_len; + int first_word; + int last_word; + int ret_val = 0; + u16 i; + + if (eeprom->len == 0) + return -EOPNOTSUPP; + + if (eeprom->len > ks->eeprom_size) + return -EINVAL; + + if (eeprom->magic != ks8851_rdreg16(ks, KS_CIDER)) + return -EFAULT; + + first_word = eeprom->offset >> 1; + last_word = (eeprom->offset + eeprom->len - 1) >> 1; + max_len = (last_word - first_word + 1) * 2; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ptr = (void *)eeprom_buff; + + if (eeprom->offset & 1) { + /* need read/modify/write of first changed EEPROM word */ + /* only the second byte of the word is being modified */ + eeprom_buff[0] = ks8851_eeprom_read(dev, first_word); + ptr++; + } + if ((eeprom->offset + eeprom->len) & 1) + /* need read/modify/write of last changed EEPROM word */ + /* only the first byte of the word is being modified */ + eeprom_buff[last_word - first_word] = + ks8851_eeprom_read(dev, last_word); + + + /* Device's eeprom is little-endian, word addressable */ + le16_to_cpus(&eeprom_buff[0]); + le16_to_cpus(&eeprom_buff[last_word - first_word]); + + memcpy(ptr, bytes, eeprom->len); + + for (i = 0; i < last_word - first_word + 1; i++) + eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); + + ks8851_eeprom_write(dev, EEPROM_OP_EWEN, 0, 0); + + for (i = 0; i < last_word - first_word + 1; i++) { + ks8851_eeprom_write(dev, EEPROM_OP_WRITE, first_word + i, + eeprom_buff[i]); + mdelay(EEPROM_WRITE_TIME); + } + + ks8851_eeprom_write(dev, EEPROM_OP_EWDS, 0, 0); + + kfree(eeprom_buff); + return ret_val; +} + +static const struct ethtool_ops ks8851_ethtool_ops = { + .get_drvinfo = ks8851_get_drvinfo, + .get_msglevel = ks8851_get_msglevel, + .set_msglevel = ks8851_set_msglevel, + .get_settings = ks8851_get_settings, + .set_settings = ks8851_set_settings, + .get_link = ks8851_get_link, + .nway_reset = ks8851_nway_reset, + .get_eeprom_len = ks8851_get_eeprom_len, + .get_eeprom = ks8851_get_eeprom, + .set_eeprom = ks8851_set_eeprom, +}; + +/* MII interface controls */ + +/** + * ks8851_phy_reg - convert MII register into a KS8851 register + * @reg: MII register number. + * + * Return the KS8851 register number for the corresponding MII PHY register + * if possible. Return zero if the MII register has no direct mapping to the + * KS8851 register set. + */ +static int ks8851_phy_reg(int reg) +{ + switch (reg) { + case MII_BMCR: + return KS_P1MBCR; + case MII_BMSR: + return KS_P1MBSR; + case MII_PHYSID1: + return KS_PHY1ILR; + case MII_PHYSID2: + return KS_PHY1IHR; + case MII_ADVERTISE: + return KS_P1ANAR; + case MII_LPA: + return KS_P1ANLPR; + } + + return 0x0; +} + +/** + * ks8851_phy_read - MII interface PHY register read. + * @dev: The network device the PHY is on. + * @phy_addr: Address of PHY (ignored as we only have one) + * @reg: The register to read. + * + * This call reads data from the PHY register specified in @reg. Since the + * device does not support all the MII registers, the non-existent values + * are always returned as zero. + * + * We return zero for unsupported registers as the MII code does not check + * the value returned for any error status, and simply returns it to the + * caller. The mii-tool that the driver was tested with takes any -ve error + * as real PHY capabilities, thus displaying incorrect data to the user. + */ +static int ks8851_phy_read(struct net_device *dev, int phy_addr, int reg) +{ + struct ks8851_net *ks = netdev_priv(dev); + int ksreg; + int result; + + ksreg = ks8851_phy_reg(reg); + if (!ksreg) + return 0x0; /* no error return allowed, so use zero */ + + mutex_lock(&ks->lock); + result = ks8851_rdreg16(ks, ksreg); + mutex_unlock(&ks->lock); + + return result; +} + +static void ks8851_phy_write(struct net_device *dev, + int phy, int reg, int value) +{ + struct ks8851_net *ks = netdev_priv(dev); + int ksreg; + + ksreg = ks8851_phy_reg(reg); + if (ksreg) { + mutex_lock(&ks->lock); + ks8851_wrreg16(ks, ksreg, value); + mutex_unlock(&ks->lock); + } +} + +/** + * ks8851_read_selftest - read the selftest memory info. + * @ks: The device state + * + * Read and check the TX/RX memory selftest information. + */ +static int ks8851_read_selftest(struct ks8851_net *ks) +{ + unsigned both_done = MBIR_TXMBF | MBIR_RXMBF; + int ret = 0; + unsigned rd; + + rd = ks8851_rdreg16(ks, KS_MBIR); + + if ((rd & both_done) != both_done) { + netdev_warn(ks->netdev, "Memory selftest not finished\n"); + return 0; + } + + if (rd & MBIR_TXMBFA) { + netdev_err(ks->netdev, "TX memory selftest fail\n"); + ret |= 1; + } + + if (rd & MBIR_RXMBFA) { + netdev_err(ks->netdev, "RX memory selftest fail\n"); + ret |= 2; + } + + return 0; +} + +/* driver bus management functions */ + +#ifdef CONFIG_PM +static int ks8851_suspend(struct spi_device *spi, pm_message_t state) +{ + struct ks8851_net *ks = dev_get_drvdata(&spi->dev); + struct net_device *dev = ks->netdev; + + if (netif_running(dev)) { + netif_device_detach(dev); + ks8851_net_stop(dev); + } + + return 0; +} + +static int ks8851_resume(struct spi_device *spi) +{ + struct ks8851_net *ks = dev_get_drvdata(&spi->dev); + struct net_device *dev = ks->netdev; + + if (netif_running(dev)) { + ks8851_net_open(dev); + netif_device_attach(dev); + } + + return 0; +} +#else +#define ks8851_suspend NULL +#define ks8851_resume NULL +#endif + +static int __devinit ks8851_probe(struct spi_device *spi) +{ + struct net_device *ndev; + struct ks8851_net *ks; + int ret; + + ndev = alloc_etherdev(sizeof(struct ks8851_net)); + if (!ndev) { + dev_err(&spi->dev, "failed to alloc ethernet device\n"); + return -ENOMEM; + } + + spi->bits_per_word = 8; + + ks = netdev_priv(ndev); + + ks->netdev = ndev; + ks->spidev = spi; + ks->tx_space = 6144; + + mutex_init(&ks->lock); + spin_lock_init(&ks->statelock); + + INIT_WORK(&ks->tx_work, ks8851_tx_work); + INIT_WORK(&ks->irq_work, ks8851_irq_work); + INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); + + /* initialise pre-made spi transfer messages */ + + spi_message_init(&ks->spi_msg1); + spi_message_add_tail(&ks->spi_xfer1, &ks->spi_msg1); + + spi_message_init(&ks->spi_msg2); + spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2); + spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2); + + /* setup mii state */ + ks->mii.dev = ndev; + ks->mii.phy_id = 1, + ks->mii.phy_id_mask = 1; + ks->mii.reg_num_mask = 0xf; + ks->mii.mdio_read = ks8851_phy_read; + ks->mii.mdio_write = ks8851_phy_write; + + dev_info(&spi->dev, "message enable is %d\n", msg_enable); + + /* set the default message enable */ + ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | + NETIF_MSG_PROBE | + NETIF_MSG_LINK)); + + skb_queue_head_init(&ks->txq); + + SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops); + SET_NETDEV_DEV(ndev, &spi->dev); + + dev_set_drvdata(&spi->dev, ks); + + ndev->if_port = IF_PORT_100BASET; + ndev->netdev_ops = &ks8851_netdev_ops; + ndev->irq = spi->irq; + + /* issue a global soft reset to reset the device. */ + ks8851_soft_reset(ks, GRR_GSR); + + /* simple check for a valid chip being connected to the bus */ + + if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { + dev_err(&spi->dev, "failed to read device ID\n"); + ret = -ENODEV; + goto err_id; + } + + /* cache the contents of the CCR register for EEPROM, etc. */ + ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR); + + if (ks->rc_ccr & CCR_EEPROM) + ks->eeprom_size = 128; + else + ks->eeprom_size = 0; + + ks8851_read_selftest(ks); + ks8851_init_mac(ks); + + ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW, + ndev->name, ks); + if (ret < 0) { + dev_err(&spi->dev, "failed to get irq\n"); + goto err_irq; + } + + ret = register_netdev(ndev); + if (ret) { + dev_err(&spi->dev, "failed to register network device\n"); + goto err_netdev; + } + + netdev_info(ndev, "revision %d, MAC %pM, IRQ %d\n", + CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), + ndev->dev_addr, ndev->irq); + + return 0; + + +err_netdev: + free_irq(ndev->irq, ndev); + +err_id: +err_irq: + free_netdev(ndev); + return ret; +} + +static int __devexit ks8851_remove(struct spi_device *spi) +{ + struct ks8851_net *priv = dev_get_drvdata(&spi->dev); + + if (netif_msg_drv(priv)) + dev_info(&spi->dev, "remove\n"); + + unregister_netdev(priv->netdev); + free_irq(spi->irq, priv); + free_netdev(priv->netdev); + + return 0; +} + +static struct spi_driver ks8851_driver = { + .driver = { + .name = "ks8851", + .owner = THIS_MODULE, + }, + .probe = ks8851_probe, + .remove = __devexit_p(ks8851_remove), + .suspend = ks8851_suspend, + .resume = ks8851_resume, +}; + +static int __init ks8851_init(void) +{ + return spi_register_driver(&ks8851_driver); +} + +static void __exit ks8851_exit(void) +{ + spi_unregister_driver(&ks8851_driver); +} + +module_init(ks8851_init); +module_exit(ks8851_exit); + +MODULE_DESCRIPTION("KS8851 Network driver"); +MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); +MODULE_LICENSE("GPL"); + +module_param_named(message, msg_enable, int, 0); +MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); +MODULE_ALIAS("spi:ks8851"); diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h new file mode 100644 index 000000000000..537fb06e5932 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -0,0 +1,309 @@ +/* drivers/net/ks8851.h + * + * Copyright 2009 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * KS8851 register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#define KS_CCR 0x08 +#define CCR_EEPROM (1 << 9) +#define CCR_SPI (1 << 8) +#define CCR_32PIN (1 << 0) + +/* MAC address registers */ +#define KS_MAR(_m) 0x15 - (_m) +#define KS_MARL 0x10 +#define KS_MARM 0x12 +#define KS_MARH 0x14 + +#define KS_OBCR 0x20 +#define OBCR_ODS_16mA (1 << 6) + +#define KS_EEPCR 0x22 +#define EEPCR_EESRWA (1 << 5) +#define EEPCR_EESA (1 << 4) +#define EEPCR_EESB_OFFSET 3 +#define EEPCR_EESB (1 << EEPCR_EESB_OFFSET) +#define EEPCR_EEDO (1 << 2) +#define EEPCR_EESCK (1 << 1) +#define EEPCR_EECS (1 << 0) + +#define EEPROM_OP_LEN 3 /* bits:*/ +#define EEPROM_OP_READ 0x06 +#define EEPROM_OP_EWEN 0x04 +#define EEPROM_OP_WRITE 0x05 +#define EEPROM_OP_EWDS 0x14 + +#define EEPROM_DATA_LEN 16 /* 16 bits EEPROM */ +#define EEPROM_WRITE_TIME 4 /* wrt ack time in ms */ +#define EEPROM_SK_PERIOD 400 /* in us */ + +#define KS_MBIR 0x24 +#define MBIR_TXMBF (1 << 12) +#define MBIR_TXMBFA (1 << 11) +#define MBIR_RXMBF (1 << 4) +#define MBIR_RXMBFA (1 << 3) + +#define KS_GRR 0x26 +#define GRR_QMU (1 << 1) +#define GRR_GSR (1 << 0) + +#define KS_WFCR 0x2A +#define WFCR_MPRXE (1 << 7) +#define WFCR_WF3E (1 << 3) +#define WFCR_WF2E (1 << 2) +#define WFCR_WF1E (1 << 1) +#define WFCR_WF0E (1 << 0) + +#define KS_WF0CRC0 0x30 +#define KS_WF0CRC1 0x32 +#define KS_WF0BM0 0x34 +#define KS_WF0BM1 0x36 +#define KS_WF0BM2 0x38 +#define KS_WF0BM3 0x3A + +#define KS_WF1CRC0 0x40 +#define KS_WF1CRC1 0x42 +#define KS_WF1BM0 0x44 +#define KS_WF1BM1 0x46 +#define KS_WF1BM2 0x48 +#define KS_WF1BM3 0x4A + +#define KS_WF2CRC0 0x50 +#define KS_WF2CRC1 0x52 +#define KS_WF2BM0 0x54 +#define KS_WF2BM1 0x56 +#define KS_WF2BM2 0x58 +#define KS_WF2BM3 0x5A + +#define KS_WF3CRC0 0x60 +#define KS_WF3CRC1 0x62 +#define KS_WF3BM0 0x64 +#define KS_WF3BM1 0x66 +#define KS_WF3BM2 0x68 +#define KS_WF3BM3 0x6A + +#define KS_TXCR 0x70 +#define TXCR_TCGICMP (1 << 8) +#define TXCR_TCGUDP (1 << 7) +#define TXCR_TCGTCP (1 << 6) +#define TXCR_TCGIP (1 << 5) +#define TXCR_FTXQ (1 << 4) +#define TXCR_TXFCE (1 << 3) +#define TXCR_TXPE (1 << 2) +#define TXCR_TXCRC (1 << 1) +#define TXCR_TXE (1 << 0) + +#define KS_TXSR 0x72 +#define TXSR_TXLC (1 << 13) +#define TXSR_TXMC (1 << 12) +#define TXSR_TXFID_MASK (0x3f << 0) +#define TXSR_TXFID_SHIFT (0) +#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) + +#define KS_RXCR1 0x74 +#define RXCR1_FRXQ (1 << 15) +#define RXCR1_RXUDPFCC (1 << 14) +#define RXCR1_RXTCPFCC (1 << 13) +#define RXCR1_RXIPFCC (1 << 12) +#define RXCR1_RXPAFMA (1 << 11) +#define RXCR1_RXFCE (1 << 10) +#define RXCR1_RXEFE (1 << 9) +#define RXCR1_RXMAFMA (1 << 8) +#define RXCR1_RXBE (1 << 7) +#define RXCR1_RXME (1 << 6) +#define RXCR1_RXUE (1 << 5) +#define RXCR1_RXAE (1 << 4) +#define RXCR1_RXINVF (1 << 1) +#define RXCR1_RXE (1 << 0) + +#define KS_RXCR2 0x76 +#define RXCR2_SRDBL_MASK (0x7 << 5) +#define RXCR2_SRDBL_SHIFT (5) +#define RXCR2_SRDBL_4B (0x0 << 5) +#define RXCR2_SRDBL_8B (0x1 << 5) +#define RXCR2_SRDBL_16B (0x2 << 5) +#define RXCR2_SRDBL_32B (0x3 << 5) +#define RXCR2_SRDBL_FRAME (0x4 << 5) +#define RXCR2_IUFFP (1 << 4) +#define RXCR2_RXIUFCEZ (1 << 3) +#define RXCR2_UDPLFE (1 << 2) +#define RXCR2_RXICMPFCC (1 << 1) +#define RXCR2_RXSAF (1 << 0) + +#define KS_TXMIR 0x78 + +#define KS_RXFHSR 0x7C +#define RXFSHR_RXFV (1 << 15) +#define RXFSHR_RXICMPFCS (1 << 13) +#define RXFSHR_RXIPFCS (1 << 12) +#define RXFSHR_RXTCPFCS (1 << 11) +#define RXFSHR_RXUDPFCS (1 << 10) +#define RXFSHR_RXBF (1 << 7) +#define RXFSHR_RXMF (1 << 6) +#define RXFSHR_RXUF (1 << 5) +#define RXFSHR_RXMR (1 << 4) +#define RXFSHR_RXFT (1 << 3) +#define RXFSHR_RXFTL (1 << 2) +#define RXFSHR_RXRF (1 << 1) +#define RXFSHR_RXCE (1 << 0) + +#define KS_RXFHBCR 0x7E +#define KS_TXQCR 0x80 +#define TXQCR_AETFE (1 << 2) +#define TXQCR_TXQMAM (1 << 1) +#define TXQCR_METFE (1 << 0) + +#define KS_RXQCR 0x82 +#define RXQCR_RXDTTS (1 << 12) +#define RXQCR_RXDBCTS (1 << 11) +#define RXQCR_RXFCTS (1 << 10) +#define RXQCR_RXIPHTOE (1 << 9) +#define RXQCR_RXDTTE (1 << 7) +#define RXQCR_RXDBCTE (1 << 6) +#define RXQCR_RXFCTE (1 << 5) +#define RXQCR_ADRFE (1 << 4) +#define RXQCR_SDA (1 << 3) +#define RXQCR_RRXEF (1 << 0) + +#define KS_TXFDPR 0x84 +#define TXFDPR_TXFPAI (1 << 14) +#define TXFDPR_TXFP_MASK (0x7ff << 0) +#define TXFDPR_TXFP_SHIFT (0) + +#define KS_RXFDPR 0x86 +#define RXFDPR_RXFPAI (1 << 14) + +#define KS_RXDTTR 0x8C +#define KS_RXDBCTR 0x8E + +#define KS_IER 0x90 +#define KS_ISR 0x92 +#define IRQ_LCI (1 << 15) +#define IRQ_TXI (1 << 14) +#define IRQ_RXI (1 << 13) +#define IRQ_RXOI (1 << 11) +#define IRQ_TXPSI (1 << 9) +#define IRQ_RXPSI (1 << 8) +#define IRQ_TXSAI (1 << 6) +#define IRQ_RXWFDI (1 << 5) +#define IRQ_RXMPDI (1 << 4) +#define IRQ_LDI (1 << 3) +#define IRQ_EDI (1 << 2) +#define IRQ_SPIBEI (1 << 1) +#define IRQ_DEDI (1 << 0) + +#define KS_RXFCTR 0x9C +#define KS_RXFC 0x9D +#define RXFCTR_RXFC_MASK (0xff << 8) +#define RXFCTR_RXFC_SHIFT (8) +#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) +#define RXFCTR_RXFCT_MASK (0xff << 0) +#define RXFCTR_RXFCT_SHIFT (0) + +#define KS_TXNTFSR 0x9E + +#define KS_MAHTR0 0xA0 +#define KS_MAHTR1 0xA2 +#define KS_MAHTR2 0xA4 +#define KS_MAHTR3 0xA6 + +#define KS_FCLWR 0xB0 +#define KS_FCHWR 0xB2 +#define KS_FCOWR 0xB4 + +#define KS_CIDER 0xC0 +#define CIDER_ID 0x8870 +#define CIDER_REV_MASK (0x7 << 1) +#define CIDER_REV_SHIFT (1) +#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) + +#define KS_CGCR 0xC6 + +#define KS_IACR 0xC8 +#define IACR_RDEN (1 << 12) +#define IACR_TSEL_MASK (0x3 << 10) +#define IACR_TSEL_SHIFT (10) +#define IACR_TSEL_MIB (0x3 << 10) +#define IACR_ADDR_MASK (0x1f << 0) +#define IACR_ADDR_SHIFT (0) + +#define KS_IADLR 0xD0 +#define KS_IAHDR 0xD2 + +#define KS_PMECR 0xD4 +#define PMECR_PME_DELAY (1 << 14) +#define PMECR_PME_POL (1 << 12) +#define PMECR_WOL_WAKEUP (1 << 11) +#define PMECR_WOL_MAGICPKT (1 << 10) +#define PMECR_WOL_LINKUP (1 << 9) +#define PMECR_WOL_ENERGY (1 << 8) +#define PMECR_AUTO_WAKE_EN (1 << 7) +#define PMECR_WAKEUP_NORMAL (1 << 6) +#define PMECR_WKEVT_MASK (0xf << 2) +#define PMECR_WKEVT_SHIFT (2) +#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) +#define PMECR_WKEVT_ENERGY (0x1 << 2) +#define PMECR_WKEVT_LINK (0x2 << 2) +#define PMECR_WKEVT_MAGICPKT (0x4 << 2) +#define PMECR_WKEVT_FRAME (0x8 << 2) +#define PMECR_PM_MASK (0x3 << 0) +#define PMECR_PM_SHIFT (0) +#define PMECR_PM_NORMAL (0x0 << 0) +#define PMECR_PM_ENERGY (0x1 << 0) +#define PMECR_PM_SOFTDOWN (0x2 << 0) +#define PMECR_PM_POWERSAVE (0x3 << 0) + +/* Standard MII PHY data */ +#define KS_P1MBCR 0xE4 +#define KS_P1MBSR 0xE6 +#define KS_PHY1ILR 0xE8 +#define KS_PHY1IHR 0xEA +#define KS_P1ANAR 0xEC +#define KS_P1ANLPR 0xEE + +#define KS_P1SCLMD 0xF4 +#define P1SCLMD_LEDOFF (1 << 15) +#define P1SCLMD_TXIDS (1 << 14) +#define P1SCLMD_RESTARTAN (1 << 13) +#define P1SCLMD_DISAUTOMDIX (1 << 10) +#define P1SCLMD_FORCEMDIX (1 << 9) +#define P1SCLMD_AUTONEGEN (1 << 7) +#define P1SCLMD_FORCE100 (1 << 6) +#define P1SCLMD_FORCEFDX (1 << 5) +#define P1SCLMD_ADV_FLOW (1 << 4) +#define P1SCLMD_ADV_100BT_FDX (1 << 3) +#define P1SCLMD_ADV_100BT_HDX (1 << 2) +#define P1SCLMD_ADV_10BT_FDX (1 << 1) +#define P1SCLMD_ADV_10BT_HDX (1 << 0) + +#define KS_P1CR 0xF6 +#define P1CR_HP_MDIX (1 << 15) +#define P1CR_REV_POL (1 << 13) +#define P1CR_OP_100M (1 << 10) +#define P1CR_OP_FDX (1 << 9) +#define P1CR_OP_MDI (1 << 7) +#define P1CR_AN_DONE (1 << 6) +#define P1CR_LINK_GOOD (1 << 5) +#define P1CR_PNTR_FLOW (1 << 4) +#define P1CR_PNTR_100BT_FDX (1 << 3) +#define P1CR_PNTR_100BT_HDX (1 << 2) +#define P1CR_PNTR_10BT_FDX (1 << 1) +#define P1CR_PNTR_10BT_HDX (1 << 0) + +/* TX Frame control */ + +#define TXFR_TXIC (1 << 15) +#define TXFR_TXFID_MASK (0x3f << 0) +#define TXFR_TXFID_SHIFT (0) + +/* SPI frame opcodes */ +#define KS_SPIOP_RD (0x00) +#define KS_SPIOP_WR (0x40) +#define KS_SPIOP_RXFIFO (0x80) +#define KS_SPIOP_TXFIFO (0xC0) diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c new file mode 100644 index 000000000000..d19c849059d8 --- /dev/null +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -0,0 +1,1680 @@ +/** + * drivers/net/ks8851_mll.c + * Copyright (c) 2009 Micrel Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/** + * Supports: + * KS8851 16bit MLL chip from Micrel Inc. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/cache.h> +#include <linux/crc32.h> +#include <linux/mii.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <asm/io.h> + +#define DRV_NAME "ks8851_mll" + +static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; +#define MAX_RECV_FRAMES 32 +#define MAX_BUF_SIZE 2048 +#define TX_BUF_SIZE 2000 +#define RX_BUF_SIZE 2000 + +#define KS_CCR 0x08 +#define CCR_EEPROM (1 << 9) +#define CCR_SPI (1 << 8) +#define CCR_8BIT (1 << 7) +#define CCR_16BIT (1 << 6) +#define CCR_32BIT (1 << 5) +#define CCR_SHARED (1 << 4) +#define CCR_32PIN (1 << 0) + +/* MAC address registers */ +#define KS_MARL 0x10 +#define KS_MARM 0x12 +#define KS_MARH 0x14 + +#define KS_OBCR 0x20 +#define OBCR_ODS_16MA (1 << 6) + +#define KS_EEPCR 0x22 +#define EEPCR_EESA (1 << 4) +#define EEPCR_EESB (1 << 3) +#define EEPCR_EEDO (1 << 2) +#define EEPCR_EESCK (1 << 1) +#define EEPCR_EECS (1 << 0) + +#define KS_MBIR 0x24 +#define MBIR_TXMBF (1 << 12) +#define MBIR_TXMBFA (1 << 11) +#define MBIR_RXMBF (1 << 4) +#define MBIR_RXMBFA (1 << 3) + +#define KS_GRR 0x26 +#define GRR_QMU (1 << 1) +#define GRR_GSR (1 << 0) + +#define KS_WFCR 0x2A +#define WFCR_MPRXE (1 << 7) +#define WFCR_WF3E (1 << 3) +#define WFCR_WF2E (1 << 2) +#define WFCR_WF1E (1 << 1) +#define WFCR_WF0E (1 << 0) + +#define KS_WF0CRC0 0x30 +#define KS_WF0CRC1 0x32 +#define KS_WF0BM0 0x34 +#define KS_WF0BM1 0x36 +#define KS_WF0BM2 0x38 +#define KS_WF0BM3 0x3A + +#define KS_WF1CRC0 0x40 +#define KS_WF1CRC1 0x42 +#define KS_WF1BM0 0x44 +#define KS_WF1BM1 0x46 +#define KS_WF1BM2 0x48 +#define KS_WF1BM3 0x4A + +#define KS_WF2CRC0 0x50 +#define KS_WF2CRC1 0x52 +#define KS_WF2BM0 0x54 +#define KS_WF2BM1 0x56 +#define KS_WF2BM2 0x58 +#define KS_WF2BM3 0x5A + +#define KS_WF3CRC0 0x60 +#define KS_WF3CRC1 0x62 +#define KS_WF3BM0 0x64 +#define KS_WF3BM1 0x66 +#define KS_WF3BM2 0x68 +#define KS_WF3BM3 0x6A + +#define KS_TXCR 0x70 +#define TXCR_TCGICMP (1 << 8) +#define TXCR_TCGUDP (1 << 7) +#define TXCR_TCGTCP (1 << 6) +#define TXCR_TCGIP (1 << 5) +#define TXCR_FTXQ (1 << 4) +#define TXCR_TXFCE (1 << 3) +#define TXCR_TXPE (1 << 2) +#define TXCR_TXCRC (1 << 1) +#define TXCR_TXE (1 << 0) + +#define KS_TXSR 0x72 +#define TXSR_TXLC (1 << 13) +#define TXSR_TXMC (1 << 12) +#define TXSR_TXFID_MASK (0x3f << 0) +#define TXSR_TXFID_SHIFT (0) +#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) + + +#define KS_RXCR1 0x74 +#define RXCR1_FRXQ (1 << 15) +#define RXCR1_RXUDPFCC (1 << 14) +#define RXCR1_RXTCPFCC (1 << 13) +#define RXCR1_RXIPFCC (1 << 12) +#define RXCR1_RXPAFMA (1 << 11) +#define RXCR1_RXFCE (1 << 10) +#define RXCR1_RXEFE (1 << 9) +#define RXCR1_RXMAFMA (1 << 8) +#define RXCR1_RXBE (1 << 7) +#define RXCR1_RXME (1 << 6) +#define RXCR1_RXUE (1 << 5) +#define RXCR1_RXAE (1 << 4) +#define RXCR1_RXINVF (1 << 1) +#define RXCR1_RXE (1 << 0) +#define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | \ + RXCR1_RXMAFMA | RXCR1_RXPAFMA) + +#define KS_RXCR2 0x76 +#define RXCR2_SRDBL_MASK (0x7 << 5) +#define RXCR2_SRDBL_SHIFT (5) +#define RXCR2_SRDBL_4B (0x0 << 5) +#define RXCR2_SRDBL_8B (0x1 << 5) +#define RXCR2_SRDBL_16B (0x2 << 5) +#define RXCR2_SRDBL_32B (0x3 << 5) +/* #define RXCR2_SRDBL_FRAME (0x4 << 5) */ +#define RXCR2_IUFFP (1 << 4) +#define RXCR2_RXIUFCEZ (1 << 3) +#define RXCR2_UDPLFE (1 << 2) +#define RXCR2_RXICMPFCC (1 << 1) +#define RXCR2_RXSAF (1 << 0) + +#define KS_TXMIR 0x78 + +#define KS_RXFHSR 0x7C +#define RXFSHR_RXFV (1 << 15) +#define RXFSHR_RXICMPFCS (1 << 13) +#define RXFSHR_RXIPFCS (1 << 12) +#define RXFSHR_RXTCPFCS (1 << 11) +#define RXFSHR_RXUDPFCS (1 << 10) +#define RXFSHR_RXBF (1 << 7) +#define RXFSHR_RXMF (1 << 6) +#define RXFSHR_RXUF (1 << 5) +#define RXFSHR_RXMR (1 << 4) +#define RXFSHR_RXFT (1 << 3) +#define RXFSHR_RXFTL (1 << 2) +#define RXFSHR_RXRF (1 << 1) +#define RXFSHR_RXCE (1 << 0) +#define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF |\ + RXFSHR_RXFTL | RXFSHR_RXMR |\ + RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\ + RXFSHR_RXTCPFCS) +#define KS_RXFHBCR 0x7E +#define RXFHBCR_CNT_MASK 0x0FFF + +#define KS_TXQCR 0x80 +#define TXQCR_AETFE (1 << 2) +#define TXQCR_TXQMAM (1 << 1) +#define TXQCR_METFE (1 << 0) + +#define KS_RXQCR 0x82 +#define RXQCR_RXDTTS (1 << 12) +#define RXQCR_RXDBCTS (1 << 11) +#define RXQCR_RXFCTS (1 << 10) +#define RXQCR_RXIPHTOE (1 << 9) +#define RXQCR_RXDTTE (1 << 7) +#define RXQCR_RXDBCTE (1 << 6) +#define RXQCR_RXFCTE (1 << 5) +#define RXQCR_ADRFE (1 << 4) +#define RXQCR_SDA (1 << 3) +#define RXQCR_RRXEF (1 << 0) +#define RXQCR_CMD_CNTL (RXQCR_RXFCTE|RXQCR_ADRFE) + +#define KS_TXFDPR 0x84 +#define TXFDPR_TXFPAI (1 << 14) +#define TXFDPR_TXFP_MASK (0x7ff << 0) +#define TXFDPR_TXFP_SHIFT (0) + +#define KS_RXFDPR 0x86 +#define RXFDPR_RXFPAI (1 << 14) + +#define KS_RXDTTR 0x8C +#define KS_RXDBCTR 0x8E + +#define KS_IER 0x90 +#define KS_ISR 0x92 +#define IRQ_LCI (1 << 15) +#define IRQ_TXI (1 << 14) +#define IRQ_RXI (1 << 13) +#define IRQ_RXOI (1 << 11) +#define IRQ_TXPSI (1 << 9) +#define IRQ_RXPSI (1 << 8) +#define IRQ_TXSAI (1 << 6) +#define IRQ_RXWFDI (1 << 5) +#define IRQ_RXMPDI (1 << 4) +#define IRQ_LDI (1 << 3) +#define IRQ_EDI (1 << 2) +#define IRQ_SPIBEI (1 << 1) +#define IRQ_DEDI (1 << 0) + +#define KS_RXFCTR 0x9C +#define RXFCTR_THRESHOLD_MASK 0x00FF + +#define KS_RXFC 0x9D +#define RXFCTR_RXFC_MASK (0xff << 8) +#define RXFCTR_RXFC_SHIFT (8) +#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) +#define RXFCTR_RXFCT_MASK (0xff << 0) +#define RXFCTR_RXFCT_SHIFT (0) + +#define KS_TXNTFSR 0x9E + +#define KS_MAHTR0 0xA0 +#define KS_MAHTR1 0xA2 +#define KS_MAHTR2 0xA4 +#define KS_MAHTR3 0xA6 + +#define KS_FCLWR 0xB0 +#define KS_FCHWR 0xB2 +#define KS_FCOWR 0xB4 + +#define KS_CIDER 0xC0 +#define CIDER_ID 0x8870 +#define CIDER_REV_MASK (0x7 << 1) +#define CIDER_REV_SHIFT (1) +#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) + +#define KS_CGCR 0xC6 +#define KS_IACR 0xC8 +#define IACR_RDEN (1 << 12) +#define IACR_TSEL_MASK (0x3 << 10) +#define IACR_TSEL_SHIFT (10) +#define IACR_TSEL_MIB (0x3 << 10) +#define IACR_ADDR_MASK (0x1f << 0) +#define IACR_ADDR_SHIFT (0) + +#define KS_IADLR 0xD0 +#define KS_IAHDR 0xD2 + +#define KS_PMECR 0xD4 +#define PMECR_PME_DELAY (1 << 14) +#define PMECR_PME_POL (1 << 12) +#define PMECR_WOL_WAKEUP (1 << 11) +#define PMECR_WOL_MAGICPKT (1 << 10) +#define PMECR_WOL_LINKUP (1 << 9) +#define PMECR_WOL_ENERGY (1 << 8) +#define PMECR_AUTO_WAKE_EN (1 << 7) +#define PMECR_WAKEUP_NORMAL (1 << 6) +#define PMECR_WKEVT_MASK (0xf << 2) +#define PMECR_WKEVT_SHIFT (2) +#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) +#define PMECR_WKEVT_ENERGY (0x1 << 2) +#define PMECR_WKEVT_LINK (0x2 << 2) +#define PMECR_WKEVT_MAGICPKT (0x4 << 2) +#define PMECR_WKEVT_FRAME (0x8 << 2) +#define PMECR_PM_MASK (0x3 << 0) +#define PMECR_PM_SHIFT (0) +#define PMECR_PM_NORMAL (0x0 << 0) +#define PMECR_PM_ENERGY (0x1 << 0) +#define PMECR_PM_SOFTDOWN (0x2 << 0) +#define PMECR_PM_POWERSAVE (0x3 << 0) + +/* Standard MII PHY data */ +#define KS_P1MBCR 0xE4 +#define P1MBCR_FORCE_FDX (1 << 8) + +#define KS_P1MBSR 0xE6 +#define P1MBSR_AN_COMPLETE (1 << 5) +#define P1MBSR_AN_CAPABLE (1 << 3) +#define P1MBSR_LINK_UP (1 << 2) + +#define KS_PHY1ILR 0xE8 +#define KS_PHY1IHR 0xEA +#define KS_P1ANAR 0xEC +#define KS_P1ANLPR 0xEE + +#define KS_P1SCLMD 0xF4 +#define P1SCLMD_LEDOFF (1 << 15) +#define P1SCLMD_TXIDS (1 << 14) +#define P1SCLMD_RESTARTAN (1 << 13) +#define P1SCLMD_DISAUTOMDIX (1 << 10) +#define P1SCLMD_FORCEMDIX (1 << 9) +#define P1SCLMD_AUTONEGEN (1 << 7) +#define P1SCLMD_FORCE100 (1 << 6) +#define P1SCLMD_FORCEFDX (1 << 5) +#define P1SCLMD_ADV_FLOW (1 << 4) +#define P1SCLMD_ADV_100BT_FDX (1 << 3) +#define P1SCLMD_ADV_100BT_HDX (1 << 2) +#define P1SCLMD_ADV_10BT_FDX (1 << 1) +#define P1SCLMD_ADV_10BT_HDX (1 << 0) + +#define KS_P1CR 0xF6 +#define P1CR_HP_MDIX (1 << 15) +#define P1CR_REV_POL (1 << 13) +#define P1CR_OP_100M (1 << 10) +#define P1CR_OP_FDX (1 << 9) +#define P1CR_OP_MDI (1 << 7) +#define P1CR_AN_DONE (1 << 6) +#define P1CR_LINK_GOOD (1 << 5) +#define P1CR_PNTR_FLOW (1 << 4) +#define P1CR_PNTR_100BT_FDX (1 << 3) +#define P1CR_PNTR_100BT_HDX (1 << 2) +#define P1CR_PNTR_10BT_FDX (1 << 1) +#define P1CR_PNTR_10BT_HDX (1 << 0) + +/* TX Frame control */ + +#define TXFR_TXIC (1 << 15) +#define TXFR_TXFID_MASK (0x3f << 0) +#define TXFR_TXFID_SHIFT (0) + +#define KS_P1SR 0xF8 +#define P1SR_HP_MDIX (1 << 15) +#define P1SR_REV_POL (1 << 13) +#define P1SR_OP_100M (1 << 10) +#define P1SR_OP_FDX (1 << 9) +#define P1SR_OP_MDI (1 << 7) +#define P1SR_AN_DONE (1 << 6) +#define P1SR_LINK_GOOD (1 << 5) +#define P1SR_PNTR_FLOW (1 << 4) +#define P1SR_PNTR_100BT_FDX (1 << 3) +#define P1SR_PNTR_100BT_HDX (1 << 2) +#define P1SR_PNTR_10BT_FDX (1 << 1) +#define P1SR_PNTR_10BT_HDX (1 << 0) + +#define ENUM_BUS_NONE 0 +#define ENUM_BUS_8BIT 1 +#define ENUM_BUS_16BIT 2 +#define ENUM_BUS_32BIT 3 + +#define MAX_MCAST_LST 32 +#define HW_MCAST_SIZE 8 + +/** + * union ks_tx_hdr - tx header data + * @txb: The header as bytes + * @txw: The header as 16bit, little-endian words + * + * A dual representation of the tx header data to allow + * access to individual bytes, and to allow 16bit accesses + * with 16bit alignment. + */ +union ks_tx_hdr { + u8 txb[4]; + __le16 txw[2]; +}; + +/** + * struct ks_net - KS8851 driver private data + * @net_device : The network device we're bound to + * @hw_addr : start address of data register. + * @hw_addr_cmd : start address of command register. + * @txh : temporaly buffer to save status/length. + * @lock : Lock to ensure that the device is not accessed when busy. + * @pdev : Pointer to platform device. + * @mii : The MII state information for the mii calls. + * @frame_head_info : frame header information for multi-pkt rx. + * @statelock : Lock on this structure for tx list. + * @msg_enable : The message flags controlling driver output (see ethtool). + * @frame_cnt : number of frames received. + * @bus_width : i/o bus width. + * @irq : irq number assigned to this device. + * @rc_rxqcr : Cached copy of KS_RXQCR. + * @rc_txcr : Cached copy of KS_TXCR. + * @rc_ier : Cached copy of KS_IER. + * @sharedbus : Multipex(addr and data bus) mode indicator. + * @cmd_reg_cache : command register cached. + * @cmd_reg_cache_int : command register cached. Used in the irq handler. + * @promiscuous : promiscuous mode indicator. + * @all_mcast : mutlicast indicator. + * @mcast_lst_size : size of multicast list. + * @mcast_lst : multicast list. + * @mcast_bits : multicast enabed. + * @mac_addr : MAC address assigned to this device. + * @fid : frame id. + * @extra_byte : number of extra byte prepended rx pkt. + * @enabled : indicator this device works. + * + * The @lock ensures that the chip is protected when certain operations are + * in progress. When the read or write packet transfer is in progress, most + * of the chip registers are not accessible until the transfer is finished and + * the DMA has been de-asserted. + * + * The @statelock is used to protect information in the structure which may + * need to be accessed via several sources, such as the network driver layer + * or one of the work queues. + * + */ + +/* Receive multiplex framer header info */ +struct type_frame_head { + u16 sts; /* Frame status */ + u16 len; /* Byte count */ +}; + +struct ks_net { + struct net_device *netdev; + void __iomem *hw_addr; + void __iomem *hw_addr_cmd; + union ks_tx_hdr txh ____cacheline_aligned; + struct mutex lock; /* spinlock to be interrupt safe */ + struct platform_device *pdev; + struct mii_if_info mii; + struct type_frame_head *frame_head_info; + spinlock_t statelock; + u32 msg_enable; + u32 frame_cnt; + int bus_width; + int irq; + + u16 rc_rxqcr; + u16 rc_txcr; + u16 rc_ier; + u16 sharedbus; + u16 cmd_reg_cache; + u16 cmd_reg_cache_int; + u16 promiscuous; + u16 all_mcast; + u16 mcast_lst_size; + u8 mcast_lst[MAX_MCAST_LST][ETH_ALEN]; + u8 mcast_bits[HW_MCAST_SIZE]; + u8 mac_addr[6]; + u8 fid; + u8 extra_byte; + u8 enabled; +}; + +static int msg_enable; + +#define BE3 0x8000 /* Byte Enable 3 */ +#define BE2 0x4000 /* Byte Enable 2 */ +#define BE1 0x2000 /* Byte Enable 1 */ +#define BE0 0x1000 /* Byte Enable 0 */ + +/** + * register read/write calls. + * + * All these calls issue transactions to access the chip's registers. They + * all require that the necessary lock is held to prevent accesses when the + * chip is busy transferring packet data (RX/TX FIFO accesses). + */ + +/** + * ks_rdreg8 - read 8 bit register from device + * @ks : The chip information + * @offset: The register address + * + * Read a 8bit register from the chip, returning the result + */ +static u8 ks_rdreg8(struct ks_net *ks, int offset) +{ + u16 data; + u8 shift_bit = offset & 0x03; + u8 shift_data = (offset & 1) << 3; + ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + data = ioread16(ks->hw_addr); + return (u8)(data >> shift_data); +} + +/** + * ks_rdreg16 - read 16 bit register from device + * @ks : The chip information + * @offset: The register address + * + * Read a 16bit register from the chip, returning the result + */ + +static u16 ks_rdreg16(struct ks_net *ks, int offset) +{ + ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + return ioread16(ks->hw_addr); +} + +/** + * ks_wrreg8 - write 8bit register value to chip + * @ks: The chip information + * @offset: The register address + * @value: The value to write + * + */ +static void ks_wrreg8(struct ks_net *ks, int offset, u8 value) +{ + u8 shift_bit = (offset & 0x03); + u16 value_write = (u16)(value << ((offset & 1) << 3)); + ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + iowrite16(value_write, ks->hw_addr); +} + +/** + * ks_wrreg16 - write 16bit register value to chip + * @ks: The chip information + * @offset: The register address + * @value: The value to write + * + */ + +static void ks_wrreg16(struct ks_net *ks, int offset, u16 value) +{ + ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + iowrite16(value, ks->hw_addr); +} + +/** + * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode enabled. + * @ks: The chip state + * @wptr: buffer address to save data + * @len: length in byte to read + * + */ +static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len) +{ + len >>= 1; + while (len--) + *wptr++ = (u16)ioread16(ks->hw_addr); +} + +/** + * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled. + * @ks: The chip information + * @wptr: buffer address + * @len: length in byte to write + * + */ +static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) +{ + len >>= 1; + while (len--) + iowrite16(*wptr++, ks->hw_addr); +} + +static void ks_disable_int(struct ks_net *ks) +{ + ks_wrreg16(ks, KS_IER, 0x0000); +} /* ks_disable_int */ + +static void ks_enable_int(struct ks_net *ks) +{ + ks_wrreg16(ks, KS_IER, ks->rc_ier); +} /* ks_enable_int */ + +/** + * ks_tx_fifo_space - return the available hardware buffer size. + * @ks: The chip information + * + */ +static inline u16 ks_tx_fifo_space(struct ks_net *ks) +{ + return ks_rdreg16(ks, KS_TXMIR) & 0x1fff; +} + +/** + * ks_save_cmd_reg - save the command register from the cache. + * @ks: The chip information + * + */ +static inline void ks_save_cmd_reg(struct ks_net *ks) +{ + /*ks8851 MLL has a bug to read back the command register. + * So rely on software to save the content of command register. + */ + ks->cmd_reg_cache_int = ks->cmd_reg_cache; +} + +/** + * ks_restore_cmd_reg - restore the command register from the cache and + * write to hardware register. + * @ks: The chip information + * + */ +static inline void ks_restore_cmd_reg(struct ks_net *ks) +{ + ks->cmd_reg_cache = ks->cmd_reg_cache_int; + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); +} + +/** + * ks_set_powermode - set power mode of the device + * @ks: The chip information + * @pwrmode: The power mode value to write to KS_PMECR. + * + * Change the power mode of the chip. + */ +static void ks_set_powermode(struct ks_net *ks, unsigned pwrmode) +{ + unsigned pmecr; + + netif_dbg(ks, hw, ks->netdev, "setting power mode %d\n", pwrmode); + + ks_rdreg16(ks, KS_GRR); + pmecr = ks_rdreg16(ks, KS_PMECR); + pmecr &= ~PMECR_PM_MASK; + pmecr |= pwrmode; + + ks_wrreg16(ks, KS_PMECR, pmecr); +} + +/** + * ks_read_config - read chip configuration of bus width. + * @ks: The chip information + * + */ +static void ks_read_config(struct ks_net *ks) +{ + u16 reg_data = 0; + + /* Regardless of bus width, 8 bit read should always work.*/ + reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF; + reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8; + + /* addr/data bus are multiplexed */ + ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED; + + /* There are garbage data when reading data from QMU, + depending on bus-width. + */ + + if (reg_data & CCR_8BIT) { + ks->bus_width = ENUM_BUS_8BIT; + ks->extra_byte = 1; + } else if (reg_data & CCR_16BIT) { + ks->bus_width = ENUM_BUS_16BIT; + ks->extra_byte = 2; + } else { + ks->bus_width = ENUM_BUS_32BIT; + ks->extra_byte = 4; + } +} + +/** + * ks_soft_reset - issue one of the soft reset to the device + * @ks: The device state. + * @op: The bit(s) to set in the GRR + * + * Issue the relevant soft-reset command to the device's GRR register + * specified by @op. + * + * Note, the delays are in there as a caution to ensure that the reset + * has time to take effect and then complete. Since the datasheet does + * not currently specify the exact sequence, we have chosen something + * that seems to work with our device. + */ +static void ks_soft_reset(struct ks_net *ks, unsigned op) +{ + /* Disable interrupt first */ + ks_wrreg16(ks, KS_IER, 0x0000); + ks_wrreg16(ks, KS_GRR, op); + mdelay(10); /* wait a short time to effect reset */ + ks_wrreg16(ks, KS_GRR, 0); + mdelay(1); /* wait for condition to clear */ +} + + +void ks_enable_qmu(struct ks_net *ks) +{ + u16 w; + + w = ks_rdreg16(ks, KS_TXCR); + /* Enables QMU Transmit (TXCR). */ + ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); + + /* + * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame + * Enable + */ + + w = ks_rdreg16(ks, KS_RXQCR); + ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); + + /* Enables QMU Receive (RXCR1). */ + w = ks_rdreg16(ks, KS_RXCR1); + ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); + ks->enabled = true; +} /* ks_enable_qmu */ + +static void ks_disable_qmu(struct ks_net *ks) +{ + u16 w; + + w = ks_rdreg16(ks, KS_TXCR); + + /* Disables QMU Transmit (TXCR). */ + w &= ~TXCR_TXE; + ks_wrreg16(ks, KS_TXCR, w); + + /* Disables QMU Receive (RXCR1). */ + w = ks_rdreg16(ks, KS_RXCR1); + w &= ~RXCR1_RXE ; + ks_wrreg16(ks, KS_RXCR1, w); + + ks->enabled = false; + +} /* ks_disable_qmu */ + +/** + * ks_read_qmu - read 1 pkt data from the QMU. + * @ks: The chip information + * @buf: buffer address to save 1 pkt + * @len: Pkt length + * Here is the sequence to read 1 pkt: + * 1. set sudo DMA mode + * 2. read prepend data + * 3. read pkt data + * 4. reset sudo DMA Mode + */ +static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len) +{ + u32 r = ks->extra_byte & 0x1 ; + u32 w = ks->extra_byte - r; + + /* 1. set sudo DMA mode */ + ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI); + ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); + + /* 2. read prepend data */ + /** + * read 4 + extra bytes and discard them. + * extra bytes for dummy, 2 for status, 2 for len + */ + + /* use likely(r) for 8 bit access for performance */ + if (unlikely(r)) + ioread8(ks->hw_addr); + ks_inblk(ks, buf, w + 2 + 2); + + /* 3. read pkt data */ + ks_inblk(ks, buf, ALIGN(len, 4)); + + /* 4. reset sudo DMA Mode */ + ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); +} + +/** + * ks_rcv - read multiple pkts data from the QMU. + * @ks: The chip information + * @netdev: The network device being opened. + * + * Read all of header information before reading pkt content. + * It is not allowed only port of pkts in QMU after issuing + * interrupt ack. + */ +static void ks_rcv(struct ks_net *ks, struct net_device *netdev) +{ + u32 i; + struct type_frame_head *frame_hdr = ks->frame_head_info; + struct sk_buff *skb; + + ks->frame_cnt = ks_rdreg16(ks, KS_RXFCTR) >> 8; + + /* read all header information */ + for (i = 0; i < ks->frame_cnt; i++) { + /* Checking Received packet status */ + frame_hdr->sts = ks_rdreg16(ks, KS_RXFHSR); + /* Get packet len from hardware */ + frame_hdr->len = ks_rdreg16(ks, KS_RXFHBCR); + frame_hdr++; + } + + frame_hdr = ks->frame_head_info; + while (ks->frame_cnt--) { + skb = dev_alloc_skb(frame_hdr->len + 16); + if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) && + (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { + skb_reserve(skb, 2); + /* read data block including CRC 4 bytes */ + ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); + skb_put(skb, frame_hdr->len); + skb->protocol = eth_type_trans(skb, netdev); + netif_rx(skb); + } else { + pr_err("%s: err:skb alloc\n", __func__); + ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); + if (skb) + dev_kfree_skb_irq(skb); + } + frame_hdr++; + } +} + +/** + * ks_update_link_status - link status update. + * @netdev: The network device being opened. + * @ks: The chip information + * + */ + +static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks) +{ + /* check the status of the link */ + u32 link_up_status; + if (ks_rdreg16(ks, KS_P1SR) & P1SR_LINK_GOOD) { + netif_carrier_on(netdev); + link_up_status = true; + } else { + netif_carrier_off(netdev); + link_up_status = false; + } + netif_dbg(ks, link, ks->netdev, + "%s: %s\n", __func__, link_up_status ? "UP" : "DOWN"); +} + +/** + * ks_irq - device interrupt handler + * @irq: Interrupt number passed from the IRQ hnalder. + * @pw: The private word passed to register_irq(), our struct ks_net. + * + * This is the handler invoked to find out what happened + * + * Read the interrupt status, work out what needs to be done and then clear + * any of the interrupts that are not needed. + */ + +static irqreturn_t ks_irq(int irq, void *pw) +{ + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); + u16 status; + + /*this should be the first in IRQ handler */ + ks_save_cmd_reg(ks); + + status = ks_rdreg16(ks, KS_ISR); + if (unlikely(!status)) { + ks_restore_cmd_reg(ks); + return IRQ_NONE; + } + + ks_wrreg16(ks, KS_ISR, status); + + if (likely(status & IRQ_RXI)) + ks_rcv(ks, netdev); + + if (unlikely(status & IRQ_LCI)) + ks_update_link_status(netdev, ks); + + if (unlikely(status & IRQ_TXI)) + netif_wake_queue(netdev); + + if (unlikely(status & IRQ_LDI)) { + + u16 pmecr = ks_rdreg16(ks, KS_PMECR); + pmecr &= ~PMECR_WKEVT_MASK; + ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); + } + + /* this should be the last in IRQ handler*/ + ks_restore_cmd_reg(ks); + return IRQ_HANDLED; +} + + +/** + * ks_net_open - open network device + * @netdev: The network device being opened. + * + * Called when the network device is marked active, such as a user executing + * 'ifconfig up' on the device. + */ +static int ks_net_open(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + int err; + +#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW) + /* lock the card, even if we may not actually do anything + * else at the moment. + */ + + netif_dbg(ks, ifup, ks->netdev, "%s - entry\n", __func__); + + /* reset the HW */ + err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); + + if (err) { + pr_err("Failed to request IRQ: %d: %d\n", ks->irq, err); + return err; + } + + /* wake up powermode to normal mode */ + ks_set_powermode(ks, PMECR_PM_NORMAL); + mdelay(1); /* wait for normal mode to take effect */ + + ks_wrreg16(ks, KS_ISR, 0xffff); + ks_enable_int(ks); + ks_enable_qmu(ks); + netif_start_queue(ks->netdev); + + netif_dbg(ks, ifup, ks->netdev, "network device up\n"); + + return 0; +} + +/** + * ks_net_stop - close network device + * @netdev: The device being closed. + * + * Called to close down a network device which has been active. Cancell any + * work, shutdown the RX and TX process and then place the chip into a low + * power state whilst it is not being used. + */ +static int ks_net_stop(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + + netif_info(ks, ifdown, netdev, "shutting down\n"); + + netif_stop_queue(netdev); + + mutex_lock(&ks->lock); + + /* turn off the IRQs and ack any outstanding */ + ks_wrreg16(ks, KS_IER, 0x0000); + ks_wrreg16(ks, KS_ISR, 0xffff); + + /* shutdown RX/TX QMU */ + ks_disable_qmu(ks); + + /* set powermode to soft power down to save power */ + ks_set_powermode(ks, PMECR_PM_SOFTDOWN); + free_irq(ks->irq, netdev); + mutex_unlock(&ks->lock); + return 0; +} + + +/** + * ks_write_qmu - write 1 pkt data to the QMU. + * @ks: The chip information + * @pdata: buffer address to save 1 pkt + * @len: Pkt length in byte + * Here is the sequence to write 1 pkt: + * 1. set sudo DMA mode + * 2. write status/length + * 3. write pkt data + * 4. reset sudo DMA Mode + * 5. reset sudo DMA mode + * 6. Wait until pkt is out + */ +static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) +{ + /* start header at txb[0] to align txw entries */ + ks->txh.txw[0] = 0; + ks->txh.txw[1] = cpu_to_le16(len); + + /* 1. set sudo-DMA mode */ + ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); + /* 2. write status/lenth info */ + ks_outblk(ks, ks->txh.txw, 4); + /* 3. write pkt data */ + ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4)); + /* 4. reset sudo-DMA mode */ + ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); + /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */ + ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE); + /* 6. wait until TXQCR_METFE is auto-cleared */ + while (ks_rdreg16(ks, KS_TXQCR) & TXQCR_METFE) + ; +} + +/** + * ks_start_xmit - transmit packet + * @skb : The buffer to transmit + * @netdev : The device used to transmit the packet. + * + * Called by the network layer to transmit the @skb. + * spin_lock_irqsave is required because tx and rx should be mutual exclusive. + * So while tx is in-progress, prevent IRQ interrupt from happenning. + */ +static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + int retv = NETDEV_TX_OK; + struct ks_net *ks = netdev_priv(netdev); + + disable_irq(netdev->irq); + ks_disable_int(ks); + spin_lock(&ks->statelock); + + /* Extra space are required: + * 4 byte for alignment, 4 for status/length, 4 for CRC + */ + + if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) { + ks_write_qmu(ks, skb->data, skb->len); + dev_kfree_skb(skb); + } else + retv = NETDEV_TX_BUSY; + spin_unlock(&ks->statelock); + ks_enable_int(ks); + enable_irq(netdev->irq); + return retv; +} + +/** + * ks_start_rx - ready to serve pkts + * @ks : The chip information + * + */ +static void ks_start_rx(struct ks_net *ks) +{ + u16 cntl; + + /* Enables QMU Receive (RXCR1). */ + cntl = ks_rdreg16(ks, KS_RXCR1); + cntl |= RXCR1_RXE ; + ks_wrreg16(ks, KS_RXCR1, cntl); +} /* ks_start_rx */ + +/** + * ks_stop_rx - stop to serve pkts + * @ks : The chip information + * + */ +static void ks_stop_rx(struct ks_net *ks) +{ + u16 cntl; + + /* Disables QMU Receive (RXCR1). */ + cntl = ks_rdreg16(ks, KS_RXCR1); + cntl &= ~RXCR1_RXE ; + ks_wrreg16(ks, KS_RXCR1, cntl); + +} /* ks_stop_rx */ + +static unsigned long const ethernet_polynomial = 0x04c11db7U; + +static unsigned long ether_gen_crc(int length, u8 *data) +{ + long crc = -1; + while (--length >= 0) { + u8 current_octet = *data++; + int bit; + + for (bit = 0; bit < 8; bit++, current_octet >>= 1) { + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? + ethernet_polynomial : 0); + } + } + return (unsigned long)crc; +} /* ether_gen_crc */ + +/** +* ks_set_grpaddr - set multicast information +* @ks : The chip information +*/ + +static void ks_set_grpaddr(struct ks_net *ks) +{ + u8 i; + u32 index, position, value; + + memset(ks->mcast_bits, 0, sizeof(u8) * HW_MCAST_SIZE); + + for (i = 0; i < ks->mcast_lst_size; i++) { + position = (ether_gen_crc(6, ks->mcast_lst[i]) >> 26) & 0x3f; + index = position >> 3; + value = 1 << (position & 7); + ks->mcast_bits[index] |= (u8)value; + } + + for (i = 0; i < HW_MCAST_SIZE; i++) { + if (i & 1) { + ks_wrreg16(ks, (u16)((KS_MAHTR0 + i) & ~1), + (ks->mcast_bits[i] << 8) | + ks->mcast_bits[i - 1]); + } + } +} /* ks_set_grpaddr */ + +/* +* ks_clear_mcast - clear multicast information +* +* @ks : The chip information +* This routine removes all mcast addresses set in the hardware. +*/ + +static void ks_clear_mcast(struct ks_net *ks) +{ + u16 i, mcast_size; + for (i = 0; i < HW_MCAST_SIZE; i++) + ks->mcast_bits[i] = 0; + + mcast_size = HW_MCAST_SIZE >> 2; + for (i = 0; i < mcast_size; i++) + ks_wrreg16(ks, KS_MAHTR0 + (2*i), 0); +} + +static void ks_set_promis(struct ks_net *ks, u16 promiscuous_mode) +{ + u16 cntl; + ks->promiscuous = promiscuous_mode; + ks_stop_rx(ks); /* Stop receiving for reconfiguration */ + cntl = ks_rdreg16(ks, KS_RXCR1); + + cntl &= ~RXCR1_FILTER_MASK; + if (promiscuous_mode) + /* Enable Promiscuous mode */ + cntl |= RXCR1_RXAE | RXCR1_RXINVF; + else + /* Disable Promiscuous mode (default normal mode) */ + cntl |= RXCR1_RXPAFMA; + + ks_wrreg16(ks, KS_RXCR1, cntl); + + if (ks->enabled) + ks_start_rx(ks); + +} /* ks_set_promis */ + +static void ks_set_mcast(struct ks_net *ks, u16 mcast) +{ + u16 cntl; + + ks->all_mcast = mcast; + ks_stop_rx(ks); /* Stop receiving for reconfiguration */ + cntl = ks_rdreg16(ks, KS_RXCR1); + cntl &= ~RXCR1_FILTER_MASK; + if (mcast) + /* Enable "Perfect with Multicast address passed mode" */ + cntl |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA); + else + /** + * Disable "Perfect with Multicast address passed + * mode" (normal mode). + */ + cntl |= RXCR1_RXPAFMA; + + ks_wrreg16(ks, KS_RXCR1, cntl); + + if (ks->enabled) + ks_start_rx(ks); +} /* ks_set_mcast */ + +static void ks_set_rx_mode(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + struct netdev_hw_addr *ha; + + /* Turn on/off promiscuous mode. */ + if ((netdev->flags & IFF_PROMISC) == IFF_PROMISC) + ks_set_promis(ks, + (u16)((netdev->flags & IFF_PROMISC) == IFF_PROMISC)); + /* Turn on/off all mcast mode. */ + else if ((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI) + ks_set_mcast(ks, + (u16)((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI)); + else + ks_set_promis(ks, false); + + if ((netdev->flags & IFF_MULTICAST) && netdev_mc_count(netdev)) { + if (netdev_mc_count(netdev) <= MAX_MCAST_LST) { + int i = 0; + + netdev_for_each_mc_addr(ha, netdev) { + if (i >= MAX_MCAST_LST) + break; + memcpy(ks->mcast_lst[i++], ha->addr, ETH_ALEN); + } + ks->mcast_lst_size = (u8)i; + ks_set_grpaddr(ks); + } else { + /** + * List too big to support so + * turn on all mcast mode. + */ + ks->mcast_lst_size = MAX_MCAST_LST; + ks_set_mcast(ks, true); + } + } else { + ks->mcast_lst_size = 0; + ks_clear_mcast(ks); + } +} /* ks_set_rx_mode */ + +static void ks_set_mac(struct ks_net *ks, u8 *data) +{ + u16 *pw = (u16 *)data; + u16 w, u; + + ks_stop_rx(ks); /* Stop receiving for reconfiguration */ + + u = *pw++; + w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF); + ks_wrreg16(ks, KS_MARH, w); + + u = *pw++; + w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF); + ks_wrreg16(ks, KS_MARM, w); + + u = *pw; + w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF); + ks_wrreg16(ks, KS_MARL, w); + + memcpy(ks->mac_addr, data, 6); + + if (ks->enabled) + ks_start_rx(ks); +} + +static int ks_set_mac_address(struct net_device *netdev, void *paddr) +{ + struct ks_net *ks = netdev_priv(netdev); + struct sockaddr *addr = paddr; + u8 *da; + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + + da = (u8 *)netdev->dev_addr; + + ks_set_mac(ks, da); + return 0; +} + +static int ks_net_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) +{ + struct ks_net *ks = netdev_priv(netdev); + + if (!netif_running(netdev)) + return -EINVAL; + + return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL); +} + +static const struct net_device_ops ks_netdev_ops = { + .ndo_open = ks_net_open, + .ndo_stop = ks_net_stop, + .ndo_do_ioctl = ks_net_ioctl, + .ndo_start_xmit = ks_start_xmit, + .ndo_set_mac_address = ks_set_mac_address, + .ndo_set_rx_mode = ks_set_rx_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + +/* ethtool support */ + +static void ks_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *di) +{ + strlcpy(di->driver, DRV_NAME, sizeof(di->driver)); + strlcpy(di->version, "1.00", sizeof(di->version)); + strlcpy(di->bus_info, dev_name(netdev->dev.parent), + sizeof(di->bus_info)); +} + +static u32 ks_get_msglevel(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + return ks->msg_enable; +} + +static void ks_set_msglevel(struct net_device *netdev, u32 to) +{ + struct ks_net *ks = netdev_priv(netdev); + ks->msg_enable = to; +} + +static int ks_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + struct ks_net *ks = netdev_priv(netdev); + return mii_ethtool_gset(&ks->mii, cmd); +} + +static int ks_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + struct ks_net *ks = netdev_priv(netdev); + return mii_ethtool_sset(&ks->mii, cmd); +} + +static u32 ks_get_link(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + return mii_link_ok(&ks->mii); +} + +static int ks_nway_reset(struct net_device *netdev) +{ + struct ks_net *ks = netdev_priv(netdev); + return mii_nway_restart(&ks->mii); +} + +static const struct ethtool_ops ks_ethtool_ops = { + .get_drvinfo = ks_get_drvinfo, + .get_msglevel = ks_get_msglevel, + .set_msglevel = ks_set_msglevel, + .get_settings = ks_get_settings, + .set_settings = ks_set_settings, + .get_link = ks_get_link, + .nway_reset = ks_nway_reset, +}; + +/* MII interface controls */ + +/** + * ks_phy_reg - convert MII register into a KS8851 register + * @reg: MII register number. + * + * Return the KS8851 register number for the corresponding MII PHY register + * if possible. Return zero if the MII register has no direct mapping to the + * KS8851 register set. + */ +static int ks_phy_reg(int reg) +{ + switch (reg) { + case MII_BMCR: + return KS_P1MBCR; + case MII_BMSR: + return KS_P1MBSR; + case MII_PHYSID1: + return KS_PHY1ILR; + case MII_PHYSID2: + return KS_PHY1IHR; + case MII_ADVERTISE: + return KS_P1ANAR; + case MII_LPA: + return KS_P1ANLPR; + } + + return 0x0; +} + +/** + * ks_phy_read - MII interface PHY register read. + * @netdev: The network device the PHY is on. + * @phy_addr: Address of PHY (ignored as we only have one) + * @reg: The register to read. + * + * This call reads data from the PHY register specified in @reg. Since the + * device does not support all the MII registers, the non-existent values + * are always returned as zero. + * + * We return zero for unsupported registers as the MII code does not check + * the value returned for any error status, and simply returns it to the + * caller. The mii-tool that the driver was tested with takes any -ve error + * as real PHY capabilities, thus displaying incorrect data to the user. + */ +static int ks_phy_read(struct net_device *netdev, int phy_addr, int reg) +{ + struct ks_net *ks = netdev_priv(netdev); + int ksreg; + int result; + + ksreg = ks_phy_reg(reg); + if (!ksreg) + return 0x0; /* no error return allowed, so use zero */ + + mutex_lock(&ks->lock); + result = ks_rdreg16(ks, ksreg); + mutex_unlock(&ks->lock); + + return result; +} + +static void ks_phy_write(struct net_device *netdev, + int phy, int reg, int value) +{ + struct ks_net *ks = netdev_priv(netdev); + int ksreg; + + ksreg = ks_phy_reg(reg); + if (ksreg) { + mutex_lock(&ks->lock); + ks_wrreg16(ks, ksreg, value); + mutex_unlock(&ks->lock); + } +} + +/** + * ks_read_selftest - read the selftest memory info. + * @ks: The device state + * + * Read and check the TX/RX memory selftest information. + */ +static int ks_read_selftest(struct ks_net *ks) +{ + unsigned both_done = MBIR_TXMBF | MBIR_RXMBF; + int ret = 0; + unsigned rd; + + rd = ks_rdreg16(ks, KS_MBIR); + + if ((rd & both_done) != both_done) { + netdev_warn(ks->netdev, "Memory selftest not finished\n"); + return 0; + } + + if (rd & MBIR_TXMBFA) { + netdev_err(ks->netdev, "TX memory selftest fails\n"); + ret |= 1; + } + + if (rd & MBIR_RXMBFA) { + netdev_err(ks->netdev, "RX memory selftest fails\n"); + ret |= 2; + } + + netdev_info(ks->netdev, "the selftest passes\n"); + return ret; +} + +static void ks_setup(struct ks_net *ks) +{ + u16 w; + + /** + * Configure QMU Transmit + */ + + /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */ + ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI); + + /* Setup Receive Frame Data Pointer Auto-Increment */ + ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI); + + /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */ + ks_wrreg16(ks, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK); + + /* Setup RxQ Command Control (RXQCR) */ + ks->rc_rxqcr = RXQCR_CMD_CNTL; + ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + + /** + * set the force mode to half duplex, default is full duplex + * because if the auto-negotiation fails, most switch uses + * half-duplex. + */ + + w = ks_rdreg16(ks, KS_P1MBCR); + w &= ~P1MBCR_FORCE_FDX; + ks_wrreg16(ks, KS_P1MBCR, w); + + w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; + ks_wrreg16(ks, KS_TXCR, w); + + w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; + + if (ks->promiscuous) /* bPromiscuous */ + w |= (RXCR1_RXAE | RXCR1_RXINVF); + else if (ks->all_mcast) /* Multicast address passed mode */ + w |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA); + else /* Normal mode */ + w |= RXCR1_RXPAFMA; + + ks_wrreg16(ks, KS_RXCR1, w); +} /*ks_setup */ + + +static void ks_setup_int(struct ks_net *ks) +{ + ks->rc_ier = 0x00; + /* Clear the interrupts status of the hardware. */ + ks_wrreg16(ks, KS_ISR, 0xffff); + + /* Enables the interrupts of the hardware. */ + ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); +} /* ks_setup_int */ + +static int ks_hw_init(struct ks_net *ks) +{ +#define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) + ks->promiscuous = 0; + ks->all_mcast = 0; + ks->mcast_lst_size = 0; + + ks->frame_head_info = (struct type_frame_head *) \ + kmalloc(MHEADER_SIZE, GFP_KERNEL); + if (!ks->frame_head_info) { + pr_err("Error: Fail to allocate frame memory\n"); + return false; + } + + ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS); + return true; +} + + +static int __devinit ks8851_probe(struct platform_device *pdev) +{ + int err = -ENOMEM; + struct resource *io_d, *io_c; + struct net_device *netdev; + struct ks_net *ks; + u16 id, data; + + io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0); + io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1); + + if (!request_mem_region(io_d->start, resource_size(io_d), DRV_NAME)) + goto err_mem_region; + + if (!request_mem_region(io_c->start, resource_size(io_c), DRV_NAME)) + goto err_mem_region1; + + netdev = alloc_etherdev(sizeof(struct ks_net)); + if (!netdev) + goto err_alloc_etherdev; + + SET_NETDEV_DEV(netdev, &pdev->dev); + + ks = netdev_priv(netdev); + ks->netdev = netdev; + ks->hw_addr = ioremap(io_d->start, resource_size(io_d)); + + if (!ks->hw_addr) + goto err_ioremap; + + ks->hw_addr_cmd = ioremap(io_c->start, resource_size(io_c)); + if (!ks->hw_addr_cmd) + goto err_ioremap1; + + ks->irq = platform_get_irq(pdev, 0); + + if (ks->irq < 0) { + err = ks->irq; + goto err_get_irq; + } + + ks->pdev = pdev; + + mutex_init(&ks->lock); + spin_lock_init(&ks->statelock); + + netdev->netdev_ops = &ks_netdev_ops; + netdev->ethtool_ops = &ks_ethtool_ops; + + /* setup mii state */ + ks->mii.dev = netdev; + ks->mii.phy_id = 1, + ks->mii.phy_id_mask = 1; + ks->mii.reg_num_mask = 0xf; + ks->mii.mdio_read = ks_phy_read; + ks->mii.mdio_write = ks_phy_write; + + netdev_info(netdev, "message enable is %d\n", msg_enable); + /* set the default message enable */ + ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | + NETIF_MSG_PROBE | + NETIF_MSG_LINK)); + ks_read_config(ks); + + /* simple check for a valid chip being connected to the bus */ + if ((ks_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { + netdev_err(netdev, "failed to read device ID\n"); + err = -ENODEV; + goto err_register; + } + + if (ks_read_selftest(ks)) { + netdev_err(netdev, "failed to read device ID\n"); + err = -ENODEV; + goto err_register; + } + + err = register_netdev(netdev); + if (err) + goto err_register; + + platform_set_drvdata(pdev, netdev); + + ks_soft_reset(ks, GRR_GSR); + ks_hw_init(ks); + ks_disable_qmu(ks); + ks_setup(ks); + ks_setup_int(ks); + memcpy(netdev->dev_addr, ks->mac_addr, 6); + + data = ks_rdreg16(ks, KS_OBCR); + ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA); + + /** + * If you want to use the default MAC addr, + * comment out the 2 functions below. + */ + + random_ether_addr(netdev->dev_addr); + ks_set_mac(ks, netdev->dev_addr); + + id = ks_rdreg16(ks, KS_CIDER); + + netdev_info(netdev, "Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n", + (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); + return 0; + +err_register: +err_get_irq: + iounmap(ks->hw_addr_cmd); +err_ioremap1: + iounmap(ks->hw_addr); +err_ioremap: + free_netdev(netdev); +err_alloc_etherdev: + release_mem_region(io_c->start, resource_size(io_c)); +err_mem_region1: + release_mem_region(io_d->start, resource_size(io_d)); +err_mem_region: + return err; +} + +static int __devexit ks8851_remove(struct platform_device *pdev) +{ + struct net_device *netdev = platform_get_drvdata(pdev); + struct ks_net *ks = netdev_priv(netdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + kfree(ks->frame_head_info); + unregister_netdev(netdev); + iounmap(ks->hw_addr); + free_netdev(netdev); + release_mem_region(iomem->start, resource_size(iomem)); + platform_set_drvdata(pdev, NULL); + return 0; + +} + +static struct platform_driver ks8851_platform_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ks8851_probe, + .remove = __devexit_p(ks8851_remove), +}; + +static int __init ks8851_init(void) +{ + return platform_driver_register(&ks8851_platform_driver); +} + +static void __exit ks8851_exit(void) +{ + platform_driver_unregister(&ks8851_platform_driver); +} + +module_init(ks8851_init); +module_exit(ks8851_exit); + +MODULE_DESCRIPTION("KS8851 MLL Network driver"); +MODULE_AUTHOR("David Choi <david.choi@micrel.com>"); +MODULE_LICENSE("GPL"); +module_param_named(message, msg_enable, int, 0); +MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); + diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c new file mode 100644 index 000000000000..27418d31a09f --- /dev/null +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -0,0 +1,7289 @@ +/** + * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver + * + * Copyright (c) 2009-2010 Micrel, Inc. + * Tristram Ha <Tristram.Ha@micrel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/proc_fs.h> +#include <linux/mii.h> +#include <linux/platform_device.h> +#include <linux/ethtool.h> +#include <linux/etherdevice.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/if_vlan.h> +#include <linux/crc32.h> +#include <linux/sched.h> +#include <linux/slab.h> + + +/* DMA Registers */ + +#define KS_DMA_TX_CTRL 0x0000 +#define DMA_TX_ENABLE 0x00000001 +#define DMA_TX_CRC_ENABLE 0x00000002 +#define DMA_TX_PAD_ENABLE 0x00000004 +#define DMA_TX_LOOPBACK 0x00000100 +#define DMA_TX_FLOW_ENABLE 0x00000200 +#define DMA_TX_CSUM_IP 0x00010000 +#define DMA_TX_CSUM_TCP 0x00020000 +#define DMA_TX_CSUM_UDP 0x00040000 +#define DMA_TX_BURST_SIZE 0x3F000000 + +#define KS_DMA_RX_CTRL 0x0004 +#define DMA_RX_ENABLE 0x00000001 +#define KS884X_DMA_RX_MULTICAST 0x00000002 +#define DMA_RX_PROMISCUOUS 0x00000004 +#define DMA_RX_ERROR 0x00000008 +#define DMA_RX_UNICAST 0x00000010 +#define DMA_RX_ALL_MULTICAST 0x00000020 +#define DMA_RX_BROADCAST 0x00000040 +#define DMA_RX_FLOW_ENABLE 0x00000200 +#define DMA_RX_CSUM_IP 0x00010000 +#define DMA_RX_CSUM_TCP 0x00020000 +#define DMA_RX_CSUM_UDP 0x00040000 +#define DMA_RX_BURST_SIZE 0x3F000000 + +#define DMA_BURST_SHIFT 24 +#define DMA_BURST_DEFAULT 8 + +#define KS_DMA_TX_START 0x0008 +#define KS_DMA_RX_START 0x000C +#define DMA_START 0x00000001 + +#define KS_DMA_TX_ADDR 0x0010 +#define KS_DMA_RX_ADDR 0x0014 + +#define DMA_ADDR_LIST_MASK 0xFFFFFFFC +#define DMA_ADDR_LIST_SHIFT 2 + +/* MTR0 */ +#define KS884X_MULTICAST_0_OFFSET 0x0020 +#define KS884X_MULTICAST_1_OFFSET 0x0021 +#define KS884X_MULTICAST_2_OFFSET 0x0022 +#define KS884x_MULTICAST_3_OFFSET 0x0023 +/* MTR1 */ +#define KS884X_MULTICAST_4_OFFSET 0x0024 +#define KS884X_MULTICAST_5_OFFSET 0x0025 +#define KS884X_MULTICAST_6_OFFSET 0x0026 +#define KS884X_MULTICAST_7_OFFSET 0x0027 + +/* Interrupt Registers */ + +/* INTEN */ +#define KS884X_INTERRUPTS_ENABLE 0x0028 +/* INTST */ +#define KS884X_INTERRUPTS_STATUS 0x002C + +#define KS884X_INT_RX_STOPPED 0x02000000 +#define KS884X_INT_TX_STOPPED 0x04000000 +#define KS884X_INT_RX_OVERRUN 0x08000000 +#define KS884X_INT_TX_EMPTY 0x10000000 +#define KS884X_INT_RX 0x20000000 +#define KS884X_INT_TX 0x40000000 +#define KS884X_INT_PHY 0x80000000 + +#define KS884X_INT_RX_MASK \ + (KS884X_INT_RX | KS884X_INT_RX_OVERRUN) +#define KS884X_INT_TX_MASK \ + (KS884X_INT_TX | KS884X_INT_TX_EMPTY) +#define KS884X_INT_MASK (KS884X_INT_RX | KS884X_INT_TX | KS884X_INT_PHY) + +/* MAC Additional Station Address */ + +/* MAAL0 */ +#define KS_ADD_ADDR_0_LO 0x0080 +/* MAAH0 */ +#define KS_ADD_ADDR_0_HI 0x0084 +/* MAAL1 */ +#define KS_ADD_ADDR_1_LO 0x0088 +/* MAAH1 */ +#define KS_ADD_ADDR_1_HI 0x008C +/* MAAL2 */ +#define KS_ADD_ADDR_2_LO 0x0090 +/* MAAH2 */ +#define KS_ADD_ADDR_2_HI 0x0094 +/* MAAL3 */ +#define KS_ADD_ADDR_3_LO 0x0098 +/* MAAH3 */ +#define KS_ADD_ADDR_3_HI 0x009C +/* MAAL4 */ +#define KS_ADD_ADDR_4_LO 0x00A0 +/* MAAH4 */ +#define KS_ADD_ADDR_4_HI 0x00A4 +/* MAAL5 */ +#define KS_ADD_ADDR_5_LO 0x00A8 +/* MAAH5 */ +#define KS_ADD_ADDR_5_HI 0x00AC +/* MAAL6 */ +#define KS_ADD_ADDR_6_LO 0x00B0 +/* MAAH6 */ +#define KS_ADD_ADDR_6_HI 0x00B4 +/* MAAL7 */ +#define KS_ADD_ADDR_7_LO 0x00B8 +/* MAAH7 */ +#define KS_ADD_ADDR_7_HI 0x00BC +/* MAAL8 */ +#define KS_ADD_ADDR_8_LO 0x00C0 +/* MAAH8 */ +#define KS_ADD_ADDR_8_HI 0x00C4 +/* MAAL9 */ +#define KS_ADD_ADDR_9_LO 0x00C8 +/* MAAH9 */ +#define KS_ADD_ADDR_9_HI 0x00CC +/* MAAL10 */ +#define KS_ADD_ADDR_A_LO 0x00D0 +/* MAAH10 */ +#define KS_ADD_ADDR_A_HI 0x00D4 +/* MAAL11 */ +#define KS_ADD_ADDR_B_LO 0x00D8 +/* MAAH11 */ +#define KS_ADD_ADDR_B_HI 0x00DC +/* MAAL12 */ +#define KS_ADD_ADDR_C_LO 0x00E0 +/* MAAH12 */ +#define KS_ADD_ADDR_C_HI 0x00E4 +/* MAAL13 */ +#define KS_ADD_ADDR_D_LO 0x00E8 +/* MAAH13 */ +#define KS_ADD_ADDR_D_HI 0x00EC +/* MAAL14 */ +#define KS_ADD_ADDR_E_LO 0x00F0 +/* MAAH14 */ +#define KS_ADD_ADDR_E_HI 0x00F4 +/* MAAL15 */ +#define KS_ADD_ADDR_F_LO 0x00F8 +/* MAAH15 */ +#define KS_ADD_ADDR_F_HI 0x00FC + +#define ADD_ADDR_HI_MASK 0x0000FFFF +#define ADD_ADDR_ENABLE 0x80000000 +#define ADD_ADDR_INCR 8 + +/* Miscellaneous Registers */ + +/* MARL */ +#define KS884X_ADDR_0_OFFSET 0x0200 +#define KS884X_ADDR_1_OFFSET 0x0201 +/* MARM */ +#define KS884X_ADDR_2_OFFSET 0x0202 +#define KS884X_ADDR_3_OFFSET 0x0203 +/* MARH */ +#define KS884X_ADDR_4_OFFSET 0x0204 +#define KS884X_ADDR_5_OFFSET 0x0205 + +/* OBCR */ +#define KS884X_BUS_CTRL_OFFSET 0x0210 + +#define BUS_SPEED_125_MHZ 0x0000 +#define BUS_SPEED_62_5_MHZ 0x0001 +#define BUS_SPEED_41_66_MHZ 0x0002 +#define BUS_SPEED_25_MHZ 0x0003 + +/* EEPCR */ +#define KS884X_EEPROM_CTRL_OFFSET 0x0212 + +#define EEPROM_CHIP_SELECT 0x0001 +#define EEPROM_SERIAL_CLOCK 0x0002 +#define EEPROM_DATA_OUT 0x0004 +#define EEPROM_DATA_IN 0x0008 +#define EEPROM_ACCESS_ENABLE 0x0010 + +/* MBIR */ +#define KS884X_MEM_INFO_OFFSET 0x0214 + +#define RX_MEM_TEST_FAILED 0x0008 +#define RX_MEM_TEST_FINISHED 0x0010 +#define TX_MEM_TEST_FAILED 0x0800 +#define TX_MEM_TEST_FINISHED 0x1000 + +/* GCR */ +#define KS884X_GLOBAL_CTRL_OFFSET 0x0216 +#define GLOBAL_SOFTWARE_RESET 0x0001 + +#define KS8841_POWER_MANAGE_OFFSET 0x0218 + +/* WFCR */ +#define KS8841_WOL_CTRL_OFFSET 0x021A +#define KS8841_WOL_MAGIC_ENABLE 0x0080 +#define KS8841_WOL_FRAME3_ENABLE 0x0008 +#define KS8841_WOL_FRAME2_ENABLE 0x0004 +#define KS8841_WOL_FRAME1_ENABLE 0x0002 +#define KS8841_WOL_FRAME0_ENABLE 0x0001 + +/* WF0 */ +#define KS8841_WOL_FRAME_CRC_OFFSET 0x0220 +#define KS8841_WOL_FRAME_BYTE0_OFFSET 0x0224 +#define KS8841_WOL_FRAME_BYTE2_OFFSET 0x0228 + +/* IACR */ +#define KS884X_IACR_P 0x04A0 +#define KS884X_IACR_OFFSET KS884X_IACR_P + +/* IADR1 */ +#define KS884X_IADR1_P 0x04A2 +#define KS884X_IADR2_P 0x04A4 +#define KS884X_IADR3_P 0x04A6 +#define KS884X_IADR4_P 0x04A8 +#define KS884X_IADR5_P 0x04AA + +#define KS884X_ACC_CTRL_SEL_OFFSET KS884X_IACR_P +#define KS884X_ACC_CTRL_INDEX_OFFSET (KS884X_ACC_CTRL_SEL_OFFSET + 1) + +#define KS884X_ACC_DATA_0_OFFSET KS884X_IADR4_P +#define KS884X_ACC_DATA_1_OFFSET (KS884X_ACC_DATA_0_OFFSET + 1) +#define KS884X_ACC_DATA_2_OFFSET KS884X_IADR5_P +#define KS884X_ACC_DATA_3_OFFSET (KS884X_ACC_DATA_2_OFFSET + 1) +#define KS884X_ACC_DATA_4_OFFSET KS884X_IADR2_P +#define KS884X_ACC_DATA_5_OFFSET (KS884X_ACC_DATA_4_OFFSET + 1) +#define KS884X_ACC_DATA_6_OFFSET KS884X_IADR3_P +#define KS884X_ACC_DATA_7_OFFSET (KS884X_ACC_DATA_6_OFFSET + 1) +#define KS884X_ACC_DATA_8_OFFSET KS884X_IADR1_P + +/* P1MBCR */ +#define KS884X_P1MBCR_P 0x04D0 +#define KS884X_P1MBSR_P 0x04D2 +#define KS884X_PHY1ILR_P 0x04D4 +#define KS884X_PHY1IHR_P 0x04D6 +#define KS884X_P1ANAR_P 0x04D8 +#define KS884X_P1ANLPR_P 0x04DA + +/* P2MBCR */ +#define KS884X_P2MBCR_P 0x04E0 +#define KS884X_P2MBSR_P 0x04E2 +#define KS884X_PHY2ILR_P 0x04E4 +#define KS884X_PHY2IHR_P 0x04E6 +#define KS884X_P2ANAR_P 0x04E8 +#define KS884X_P2ANLPR_P 0x04EA + +#define KS884X_PHY_1_CTRL_OFFSET KS884X_P1MBCR_P +#define PHY_CTRL_INTERVAL (KS884X_P2MBCR_P - KS884X_P1MBCR_P) + +#define KS884X_PHY_CTRL_OFFSET 0x00 + +/* Mode Control Register */ +#define PHY_REG_CTRL 0 + +#define PHY_RESET 0x8000 +#define PHY_LOOPBACK 0x4000 +#define PHY_SPEED_100MBIT 0x2000 +#define PHY_AUTO_NEG_ENABLE 0x1000 +#define PHY_POWER_DOWN 0x0800 +#define PHY_MII_DISABLE 0x0400 +#define PHY_AUTO_NEG_RESTART 0x0200 +#define PHY_FULL_DUPLEX 0x0100 +#define PHY_COLLISION_TEST 0x0080 +#define PHY_HP_MDIX 0x0020 +#define PHY_FORCE_MDIX 0x0010 +#define PHY_AUTO_MDIX_DISABLE 0x0008 +#define PHY_REMOTE_FAULT_DISABLE 0x0004 +#define PHY_TRANSMIT_DISABLE 0x0002 +#define PHY_LED_DISABLE 0x0001 + +#define KS884X_PHY_STATUS_OFFSET 0x02 + +/* Mode Status Register */ +#define PHY_REG_STATUS 1 + +#define PHY_100BT4_CAPABLE 0x8000 +#define PHY_100BTX_FD_CAPABLE 0x4000 +#define PHY_100BTX_CAPABLE 0x2000 +#define PHY_10BT_FD_CAPABLE 0x1000 +#define PHY_10BT_CAPABLE 0x0800 +#define PHY_MII_SUPPRESS_CAPABLE 0x0040 +#define PHY_AUTO_NEG_ACKNOWLEDGE 0x0020 +#define PHY_REMOTE_FAULT 0x0010 +#define PHY_AUTO_NEG_CAPABLE 0x0008 +#define PHY_LINK_STATUS 0x0004 +#define PHY_JABBER_DETECT 0x0002 +#define PHY_EXTENDED_CAPABILITY 0x0001 + +#define KS884X_PHY_ID_1_OFFSET 0x04 +#define KS884X_PHY_ID_2_OFFSET 0x06 + +/* PHY Identifier Registers */ +#define PHY_REG_ID_1 2 +#define PHY_REG_ID_2 3 + +#define KS884X_PHY_AUTO_NEG_OFFSET 0x08 + +/* Auto-Negotiation Advertisement Register */ +#define PHY_REG_AUTO_NEGOTIATION 4 + +#define PHY_AUTO_NEG_NEXT_PAGE 0x8000 +#define PHY_AUTO_NEG_REMOTE_FAULT 0x2000 +/* Not supported. */ +#define PHY_AUTO_NEG_ASYM_PAUSE 0x0800 +#define PHY_AUTO_NEG_SYM_PAUSE 0x0400 +#define PHY_AUTO_NEG_100BT4 0x0200 +#define PHY_AUTO_NEG_100BTX_FD 0x0100 +#define PHY_AUTO_NEG_100BTX 0x0080 +#define PHY_AUTO_NEG_10BT_FD 0x0040 +#define PHY_AUTO_NEG_10BT 0x0020 +#define PHY_AUTO_NEG_SELECTOR 0x001F +#define PHY_AUTO_NEG_802_3 0x0001 + +#define PHY_AUTO_NEG_PAUSE (PHY_AUTO_NEG_SYM_PAUSE | PHY_AUTO_NEG_ASYM_PAUSE) + +#define KS884X_PHY_REMOTE_CAP_OFFSET 0x0A + +/* Auto-Negotiation Link Partner Ability Register */ +#define PHY_REG_REMOTE_CAPABILITY 5 + +#define PHY_REMOTE_NEXT_PAGE 0x8000 +#define PHY_REMOTE_ACKNOWLEDGE 0x4000 +#define PHY_REMOTE_REMOTE_FAULT 0x2000 +#define PHY_REMOTE_SYM_PAUSE 0x0400 +#define PHY_REMOTE_100BTX_FD 0x0100 +#define PHY_REMOTE_100BTX 0x0080 +#define PHY_REMOTE_10BT_FD 0x0040 +#define PHY_REMOTE_10BT 0x0020 + +/* P1VCT */ +#define KS884X_P1VCT_P 0x04F0 +#define KS884X_P1PHYCTRL_P 0x04F2 + +/* P2VCT */ +#define KS884X_P2VCT_P 0x04F4 +#define KS884X_P2PHYCTRL_P 0x04F6 + +#define KS884X_PHY_SPECIAL_OFFSET KS884X_P1VCT_P +#define PHY_SPECIAL_INTERVAL (KS884X_P2VCT_P - KS884X_P1VCT_P) + +#define KS884X_PHY_LINK_MD_OFFSET 0x00 + +#define PHY_START_CABLE_DIAG 0x8000 +#define PHY_CABLE_DIAG_RESULT 0x6000 +#define PHY_CABLE_STAT_NORMAL 0x0000 +#define PHY_CABLE_STAT_OPEN 0x2000 +#define PHY_CABLE_STAT_SHORT 0x4000 +#define PHY_CABLE_STAT_FAILED 0x6000 +#define PHY_CABLE_10M_SHORT 0x1000 +#define PHY_CABLE_FAULT_COUNTER 0x01FF + +#define KS884X_PHY_PHY_CTRL_OFFSET 0x02 + +#define PHY_STAT_REVERSED_POLARITY 0x0020 +#define PHY_STAT_MDIX 0x0010 +#define PHY_FORCE_LINK 0x0008 +#define PHY_POWER_SAVING_DISABLE 0x0004 +#define PHY_REMOTE_LOOPBACK 0x0002 + +/* SIDER */ +#define KS884X_SIDER_P 0x0400 +#define KS884X_CHIP_ID_OFFSET KS884X_SIDER_P +#define KS884X_FAMILY_ID_OFFSET (KS884X_CHIP_ID_OFFSET + 1) + +#define REG_FAMILY_ID 0x88 + +#define REG_CHIP_ID_41 0x8810 +#define REG_CHIP_ID_42 0x8800 + +#define KS884X_CHIP_ID_MASK_41 0xFF10 +#define KS884X_CHIP_ID_MASK 0xFFF0 +#define KS884X_CHIP_ID_SHIFT 4 +#define KS884X_REVISION_MASK 0x000E +#define KS884X_REVISION_SHIFT 1 +#define KS8842_START 0x0001 + +#define CHIP_IP_41_M 0x8810 +#define CHIP_IP_42_M 0x8800 +#define CHIP_IP_61_M 0x8890 +#define CHIP_IP_62_M 0x8880 + +#define CHIP_IP_41_P 0x8850 +#define CHIP_IP_42_P 0x8840 +#define CHIP_IP_61_P 0x88D0 +#define CHIP_IP_62_P 0x88C0 + +/* SGCR1 */ +#define KS8842_SGCR1_P 0x0402 +#define KS8842_SWITCH_CTRL_1_OFFSET KS8842_SGCR1_P + +#define SWITCH_PASS_ALL 0x8000 +#define SWITCH_TX_FLOW_CTRL 0x2000 +#define SWITCH_RX_FLOW_CTRL 0x1000 +#define SWITCH_CHECK_LENGTH 0x0800 +#define SWITCH_AGING_ENABLE 0x0400 +#define SWITCH_FAST_AGING 0x0200 +#define SWITCH_AGGR_BACKOFF 0x0100 +#define SWITCH_PASS_PAUSE 0x0008 +#define SWITCH_LINK_AUTO_AGING 0x0001 + +/* SGCR2 */ +#define KS8842_SGCR2_P 0x0404 +#define KS8842_SWITCH_CTRL_2_OFFSET KS8842_SGCR2_P + +#define SWITCH_VLAN_ENABLE 0x8000 +#define SWITCH_IGMP_SNOOP 0x4000 +#define IPV6_MLD_SNOOP_ENABLE 0x2000 +#define IPV6_MLD_SNOOP_OPTION 0x1000 +#define PRIORITY_SCHEME_SELECT 0x0800 +#define SWITCH_MIRROR_RX_TX 0x0100 +#define UNICAST_VLAN_BOUNDARY 0x0080 +#define MULTICAST_STORM_DISABLE 0x0040 +#define SWITCH_BACK_PRESSURE 0x0020 +#define FAIR_FLOW_CTRL 0x0010 +#define NO_EXC_COLLISION_DROP 0x0008 +#define SWITCH_HUGE_PACKET 0x0004 +#define SWITCH_LEGAL_PACKET 0x0002 +#define SWITCH_BUF_RESERVE 0x0001 + +/* SGCR3 */ +#define KS8842_SGCR3_P 0x0406 +#define KS8842_SWITCH_CTRL_3_OFFSET KS8842_SGCR3_P + +#define BROADCAST_STORM_RATE_LO 0xFF00 +#define SWITCH_REPEATER 0x0080 +#define SWITCH_HALF_DUPLEX 0x0040 +#define SWITCH_FLOW_CTRL 0x0020 +#define SWITCH_10_MBIT 0x0010 +#define SWITCH_REPLACE_NULL_VID 0x0008 +#define BROADCAST_STORM_RATE_HI 0x0007 + +#define BROADCAST_STORM_RATE 0x07FF + +/* SGCR4 */ +#define KS8842_SGCR4_P 0x0408 + +/* SGCR5 */ +#define KS8842_SGCR5_P 0x040A +#define KS8842_SWITCH_CTRL_5_OFFSET KS8842_SGCR5_P + +#define LED_MODE 0x8200 +#define LED_SPEED_DUPLEX_ACT 0x0000 +#define LED_SPEED_DUPLEX_LINK_ACT 0x8000 +#define LED_DUPLEX_10_100 0x0200 + +/* SGCR6 */ +#define KS8842_SGCR6_P 0x0410 +#define KS8842_SWITCH_CTRL_6_OFFSET KS8842_SGCR6_P + +#define KS8842_PRIORITY_MASK 3 +#define KS8842_PRIORITY_SHIFT 2 + +/* SGCR7 */ +#define KS8842_SGCR7_P 0x0412 +#define KS8842_SWITCH_CTRL_7_OFFSET KS8842_SGCR7_P + +#define SWITCH_UNK_DEF_PORT_ENABLE 0x0008 +#define SWITCH_UNK_DEF_PORT_3 0x0004 +#define SWITCH_UNK_DEF_PORT_2 0x0002 +#define SWITCH_UNK_DEF_PORT_1 0x0001 + +/* MACAR1 */ +#define KS8842_MACAR1_P 0x0470 +#define KS8842_MACAR2_P 0x0472 +#define KS8842_MACAR3_P 0x0474 +#define KS8842_MAC_ADDR_1_OFFSET KS8842_MACAR1_P +#define KS8842_MAC_ADDR_0_OFFSET (KS8842_MAC_ADDR_1_OFFSET + 1) +#define KS8842_MAC_ADDR_3_OFFSET KS8842_MACAR2_P +#define KS8842_MAC_ADDR_2_OFFSET (KS8842_MAC_ADDR_3_OFFSET + 1) +#define KS8842_MAC_ADDR_5_OFFSET KS8842_MACAR3_P +#define KS8842_MAC_ADDR_4_OFFSET (KS8842_MAC_ADDR_5_OFFSET + 1) + +/* TOSR1 */ +#define KS8842_TOSR1_P 0x0480 +#define KS8842_TOSR2_P 0x0482 +#define KS8842_TOSR3_P 0x0484 +#define KS8842_TOSR4_P 0x0486 +#define KS8842_TOSR5_P 0x0488 +#define KS8842_TOSR6_P 0x048A +#define KS8842_TOSR7_P 0x0490 +#define KS8842_TOSR8_P 0x0492 +#define KS8842_TOS_1_OFFSET KS8842_TOSR1_P +#define KS8842_TOS_2_OFFSET KS8842_TOSR2_P +#define KS8842_TOS_3_OFFSET KS8842_TOSR3_P +#define KS8842_TOS_4_OFFSET KS8842_TOSR4_P +#define KS8842_TOS_5_OFFSET KS8842_TOSR5_P +#define KS8842_TOS_6_OFFSET KS8842_TOSR6_P + +#define KS8842_TOS_7_OFFSET KS8842_TOSR7_P +#define KS8842_TOS_8_OFFSET KS8842_TOSR8_P + +/* P1CR1 */ +#define KS8842_P1CR1_P 0x0500 +#define KS8842_P1CR2_P 0x0502 +#define KS8842_P1VIDR_P 0x0504 +#define KS8842_P1CR3_P 0x0506 +#define KS8842_P1IRCR_P 0x0508 +#define KS8842_P1ERCR_P 0x050A +#define KS884X_P1SCSLMD_P 0x0510 +#define KS884X_P1CR4_P 0x0512 +#define KS884X_P1SR_P 0x0514 + +/* P2CR1 */ +#define KS8842_P2CR1_P 0x0520 +#define KS8842_P2CR2_P 0x0522 +#define KS8842_P2VIDR_P 0x0524 +#define KS8842_P2CR3_P 0x0526 +#define KS8842_P2IRCR_P 0x0528 +#define KS8842_P2ERCR_P 0x052A +#define KS884X_P2SCSLMD_P 0x0530 +#define KS884X_P2CR4_P 0x0532 +#define KS884X_P2SR_P 0x0534 + +/* P3CR1 */ +#define KS8842_P3CR1_P 0x0540 +#define KS8842_P3CR2_P 0x0542 +#define KS8842_P3VIDR_P 0x0544 +#define KS8842_P3CR3_P 0x0546 +#define KS8842_P3IRCR_P 0x0548 +#define KS8842_P3ERCR_P 0x054A + +#define KS8842_PORT_1_CTRL_1 KS8842_P1CR1_P +#define KS8842_PORT_2_CTRL_1 KS8842_P2CR1_P +#define KS8842_PORT_3_CTRL_1 KS8842_P3CR1_P + +#define PORT_CTRL_ADDR(port, addr) \ + (addr = KS8842_PORT_1_CTRL_1 + (port) * \ + (KS8842_PORT_2_CTRL_1 - KS8842_PORT_1_CTRL_1)) + +#define KS8842_PORT_CTRL_1_OFFSET 0x00 + +#define PORT_BROADCAST_STORM 0x0080 +#define PORT_DIFFSERV_ENABLE 0x0040 +#define PORT_802_1P_ENABLE 0x0020 +#define PORT_BASED_PRIORITY_MASK 0x0018 +#define PORT_BASED_PRIORITY_BASE 0x0003 +#define PORT_BASED_PRIORITY_SHIFT 3 +#define PORT_BASED_PRIORITY_0 0x0000 +#define PORT_BASED_PRIORITY_1 0x0008 +#define PORT_BASED_PRIORITY_2 0x0010 +#define PORT_BASED_PRIORITY_3 0x0018 +#define PORT_INSERT_TAG 0x0004 +#define PORT_REMOVE_TAG 0x0002 +#define PORT_PRIO_QUEUE_ENABLE 0x0001 + +#define KS8842_PORT_CTRL_2_OFFSET 0x02 + +#define PORT_INGRESS_VLAN_FILTER 0x4000 +#define PORT_DISCARD_NON_VID 0x2000 +#define PORT_FORCE_FLOW_CTRL 0x1000 +#define PORT_BACK_PRESSURE 0x0800 +#define PORT_TX_ENABLE 0x0400 +#define PORT_RX_ENABLE 0x0200 +#define PORT_LEARN_DISABLE 0x0100 +#define PORT_MIRROR_SNIFFER 0x0080 +#define PORT_MIRROR_RX 0x0040 +#define PORT_MIRROR_TX 0x0020 +#define PORT_USER_PRIORITY_CEILING 0x0008 +#define PORT_VLAN_MEMBERSHIP 0x0007 + +#define KS8842_PORT_CTRL_VID_OFFSET 0x04 + +#define PORT_DEFAULT_VID 0x0001 + +#define KS8842_PORT_CTRL_3_OFFSET 0x06 + +#define PORT_INGRESS_LIMIT_MODE 0x000C +#define PORT_INGRESS_ALL 0x0000 +#define PORT_INGRESS_UNICAST 0x0004 +#define PORT_INGRESS_MULTICAST 0x0008 +#define PORT_INGRESS_BROADCAST 0x000C +#define PORT_COUNT_IFG 0x0002 +#define PORT_COUNT_PREAMBLE 0x0001 + +#define KS8842_PORT_IN_RATE_OFFSET 0x08 +#define KS8842_PORT_OUT_RATE_OFFSET 0x0A + +#define PORT_PRIORITY_RATE 0x0F +#define PORT_PRIORITY_RATE_SHIFT 4 + +#define KS884X_PORT_LINK_MD 0x10 + +#define PORT_CABLE_10M_SHORT 0x8000 +#define PORT_CABLE_DIAG_RESULT 0x6000 +#define PORT_CABLE_STAT_NORMAL 0x0000 +#define PORT_CABLE_STAT_OPEN 0x2000 +#define PORT_CABLE_STAT_SHORT 0x4000 +#define PORT_CABLE_STAT_FAILED 0x6000 +#define PORT_START_CABLE_DIAG 0x1000 +#define PORT_FORCE_LINK 0x0800 +#define PORT_POWER_SAVING_DISABLE 0x0400 +#define PORT_PHY_REMOTE_LOOPBACK 0x0200 +#define PORT_CABLE_FAULT_COUNTER 0x01FF + +#define KS884X_PORT_CTRL_4_OFFSET 0x12 + +#define PORT_LED_OFF 0x8000 +#define PORT_TX_DISABLE 0x4000 +#define PORT_AUTO_NEG_RESTART 0x2000 +#define PORT_REMOTE_FAULT_DISABLE 0x1000 +#define PORT_POWER_DOWN 0x0800 +#define PORT_AUTO_MDIX_DISABLE 0x0400 +#define PORT_FORCE_MDIX 0x0200 +#define PORT_LOOPBACK 0x0100 +#define PORT_AUTO_NEG_ENABLE 0x0080 +#define PORT_FORCE_100_MBIT 0x0040 +#define PORT_FORCE_FULL_DUPLEX 0x0020 +#define PORT_AUTO_NEG_SYM_PAUSE 0x0010 +#define PORT_AUTO_NEG_100BTX_FD 0x0008 +#define PORT_AUTO_NEG_100BTX 0x0004 +#define PORT_AUTO_NEG_10BT_FD 0x0002 +#define PORT_AUTO_NEG_10BT 0x0001 + +#define KS884X_PORT_STATUS_OFFSET 0x14 + +#define PORT_HP_MDIX 0x8000 +#define PORT_REVERSED_POLARITY 0x2000 +#define PORT_RX_FLOW_CTRL 0x0800 +#define PORT_TX_FLOW_CTRL 0x1000 +#define PORT_STATUS_SPEED_100MBIT 0x0400 +#define PORT_STATUS_FULL_DUPLEX 0x0200 +#define PORT_REMOTE_FAULT 0x0100 +#define PORT_MDIX_STATUS 0x0080 +#define PORT_AUTO_NEG_COMPLETE 0x0040 +#define PORT_STATUS_LINK_GOOD 0x0020 +#define PORT_REMOTE_SYM_PAUSE 0x0010 +#define PORT_REMOTE_100BTX_FD 0x0008 +#define PORT_REMOTE_100BTX 0x0004 +#define PORT_REMOTE_10BT_FD 0x0002 +#define PORT_REMOTE_10BT 0x0001 + +/* +#define STATIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF +#define STATIC_MAC_TABLE_FWD_PORTS 00-00070000-00000000 +#define STATIC_MAC_TABLE_VALID 00-00080000-00000000 +#define STATIC_MAC_TABLE_OVERRIDE 00-00100000-00000000 +#define STATIC_MAC_TABLE_USE_FID 00-00200000-00000000 +#define STATIC_MAC_TABLE_FID 00-03C00000-00000000 +*/ + +#define STATIC_MAC_TABLE_ADDR 0x0000FFFF +#define STATIC_MAC_TABLE_FWD_PORTS 0x00070000 +#define STATIC_MAC_TABLE_VALID 0x00080000 +#define STATIC_MAC_TABLE_OVERRIDE 0x00100000 +#define STATIC_MAC_TABLE_USE_FID 0x00200000 +#define STATIC_MAC_TABLE_FID 0x03C00000 + +#define STATIC_MAC_FWD_PORTS_SHIFT 16 +#define STATIC_MAC_FID_SHIFT 22 + +/* +#define VLAN_TABLE_VID 00-00000000-00000FFF +#define VLAN_TABLE_FID 00-00000000-0000F000 +#define VLAN_TABLE_MEMBERSHIP 00-00000000-00070000 +#define VLAN_TABLE_VALID 00-00000000-00080000 +*/ + +#define VLAN_TABLE_VID 0x00000FFF +#define VLAN_TABLE_FID 0x0000F000 +#define VLAN_TABLE_MEMBERSHIP 0x00070000 +#define VLAN_TABLE_VALID 0x00080000 + +#define VLAN_TABLE_FID_SHIFT 12 +#define VLAN_TABLE_MEMBERSHIP_SHIFT 16 + +/* +#define DYNAMIC_MAC_TABLE_ADDR 00-0000FFFF-FFFFFFFF +#define DYNAMIC_MAC_TABLE_FID 00-000F0000-00000000 +#define DYNAMIC_MAC_TABLE_SRC_PORT 00-00300000-00000000 +#define DYNAMIC_MAC_TABLE_TIMESTAMP 00-00C00000-00000000 +#define DYNAMIC_MAC_TABLE_ENTRIES 03-FF000000-00000000 +#define DYNAMIC_MAC_TABLE_MAC_EMPTY 04-00000000-00000000 +#define DYNAMIC_MAC_TABLE_RESERVED 78-00000000-00000000 +#define DYNAMIC_MAC_TABLE_NOT_READY 80-00000000-00000000 +*/ + +#define DYNAMIC_MAC_TABLE_ADDR 0x0000FFFF +#define DYNAMIC_MAC_TABLE_FID 0x000F0000 +#define DYNAMIC_MAC_TABLE_SRC_PORT 0x00300000 +#define DYNAMIC_MAC_TABLE_TIMESTAMP 0x00C00000 +#define DYNAMIC_MAC_TABLE_ENTRIES 0xFF000000 + +#define DYNAMIC_MAC_TABLE_ENTRIES_H 0x03 +#define DYNAMIC_MAC_TABLE_MAC_EMPTY 0x04 +#define DYNAMIC_MAC_TABLE_RESERVED 0x78 +#define DYNAMIC_MAC_TABLE_NOT_READY 0x80 + +#define DYNAMIC_MAC_FID_SHIFT 16 +#define DYNAMIC_MAC_SRC_PORT_SHIFT 20 +#define DYNAMIC_MAC_TIMESTAMP_SHIFT 22 +#define DYNAMIC_MAC_ENTRIES_SHIFT 24 +#define DYNAMIC_MAC_ENTRIES_H_SHIFT 8 + +/* +#define MIB_COUNTER_VALUE 00-00000000-3FFFFFFF +#define MIB_COUNTER_VALID 00-00000000-40000000 +#define MIB_COUNTER_OVERFLOW 00-00000000-80000000 +*/ + +#define MIB_COUNTER_VALUE 0x3FFFFFFF +#define MIB_COUNTER_VALID 0x40000000 +#define MIB_COUNTER_OVERFLOW 0x80000000 + +#define MIB_PACKET_DROPPED 0x0000FFFF + +#define KS_MIB_PACKET_DROPPED_TX_0 0x100 +#define KS_MIB_PACKET_DROPPED_TX_1 0x101 +#define KS_MIB_PACKET_DROPPED_TX 0x102 +#define KS_MIB_PACKET_DROPPED_RX_0 0x103 +#define KS_MIB_PACKET_DROPPED_RX_1 0x104 +#define KS_MIB_PACKET_DROPPED_RX 0x105 + +/* Change default LED mode. */ +#define SET_DEFAULT_LED LED_SPEED_DUPLEX_ACT + +#define MAC_ADDR_LEN 6 +#define MAC_ADDR_ORDER(i) (MAC_ADDR_LEN - 1 - (i)) + +#define MAX_ETHERNET_BODY_SIZE 1500 +#define ETHERNET_HEADER_SIZE 14 + +#define MAX_ETHERNET_PACKET_SIZE \ + (MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE) + +#define REGULAR_RX_BUF_SIZE (MAX_ETHERNET_PACKET_SIZE + 4) +#define MAX_RX_BUF_SIZE (1912 + 4) + +#define ADDITIONAL_ENTRIES 16 +#define MAX_MULTICAST_LIST 32 + +#define HW_MULTICAST_SIZE 8 + +#define HW_TO_DEV_PORT(port) (port - 1) + +enum { + media_connected, + media_disconnected +}; + +enum { + OID_COUNTER_UNKOWN, + + OID_COUNTER_FIRST, + + /* total transmit errors */ + OID_COUNTER_XMIT_ERROR, + + /* total receive errors */ + OID_COUNTER_RCV_ERROR, + + OID_COUNTER_LAST +}; + +/* + * Hardware descriptor definitions + */ + +#define DESC_ALIGNMENT 16 +#define BUFFER_ALIGNMENT 8 + +#define NUM_OF_RX_DESC 64 +#define NUM_OF_TX_DESC 64 + +#define KS_DESC_RX_FRAME_LEN 0x000007FF +#define KS_DESC_RX_FRAME_TYPE 0x00008000 +#define KS_DESC_RX_ERROR_CRC 0x00010000 +#define KS_DESC_RX_ERROR_RUNT 0x00020000 +#define KS_DESC_RX_ERROR_TOO_LONG 0x00040000 +#define KS_DESC_RX_ERROR_PHY 0x00080000 +#define KS884X_DESC_RX_PORT_MASK 0x00300000 +#define KS_DESC_RX_MULTICAST 0x01000000 +#define KS_DESC_RX_ERROR 0x02000000 +#define KS_DESC_RX_ERROR_CSUM_UDP 0x04000000 +#define KS_DESC_RX_ERROR_CSUM_TCP 0x08000000 +#define KS_DESC_RX_ERROR_CSUM_IP 0x10000000 +#define KS_DESC_RX_LAST 0x20000000 +#define KS_DESC_RX_FIRST 0x40000000 +#define KS_DESC_RX_ERROR_COND \ + (KS_DESC_RX_ERROR_CRC | \ + KS_DESC_RX_ERROR_RUNT | \ + KS_DESC_RX_ERROR_PHY | \ + KS_DESC_RX_ERROR_TOO_LONG) + +#define KS_DESC_HW_OWNED 0x80000000 + +#define KS_DESC_BUF_SIZE 0x000007FF +#define KS884X_DESC_TX_PORT_MASK 0x00300000 +#define KS_DESC_END_OF_RING 0x02000000 +#define KS_DESC_TX_CSUM_GEN_UDP 0x04000000 +#define KS_DESC_TX_CSUM_GEN_TCP 0x08000000 +#define KS_DESC_TX_CSUM_GEN_IP 0x10000000 +#define KS_DESC_TX_LAST 0x20000000 +#define KS_DESC_TX_FIRST 0x40000000 +#define KS_DESC_TX_INTERRUPT 0x80000000 + +#define KS_DESC_PORT_SHIFT 20 + +#define KS_DESC_RX_MASK (KS_DESC_BUF_SIZE) + +#define KS_DESC_TX_MASK \ + (KS_DESC_TX_INTERRUPT | \ + KS_DESC_TX_FIRST | \ + KS_DESC_TX_LAST | \ + KS_DESC_TX_CSUM_GEN_IP | \ + KS_DESC_TX_CSUM_GEN_TCP | \ + KS_DESC_TX_CSUM_GEN_UDP | \ + KS_DESC_BUF_SIZE) + +struct ksz_desc_rx_stat { +#ifdef __BIG_ENDIAN_BITFIELD + u32 hw_owned:1; + u32 first_desc:1; + u32 last_desc:1; + u32 csum_err_ip:1; + u32 csum_err_tcp:1; + u32 csum_err_udp:1; + u32 error:1; + u32 multicast:1; + u32 src_port:4; + u32 err_phy:1; + u32 err_too_long:1; + u32 err_runt:1; + u32 err_crc:1; + u32 frame_type:1; + u32 reserved1:4; + u32 frame_len:11; +#else + u32 frame_len:11; + u32 reserved1:4; + u32 frame_type:1; + u32 err_crc:1; + u32 err_runt:1; + u32 err_too_long:1; + u32 err_phy:1; + u32 src_port:4; + u32 multicast:1; + u32 error:1; + u32 csum_err_udp:1; + u32 csum_err_tcp:1; + u32 csum_err_ip:1; + u32 last_desc:1; + u32 first_desc:1; + u32 hw_owned:1; +#endif +}; + +struct ksz_desc_tx_stat { +#ifdef __BIG_ENDIAN_BITFIELD + u32 hw_owned:1; + u32 reserved1:31; +#else + u32 reserved1:31; + u32 hw_owned:1; +#endif +}; + +struct ksz_desc_rx_buf { +#ifdef __BIG_ENDIAN_BITFIELD + u32 reserved4:6; + u32 end_of_ring:1; + u32 reserved3:14; + u32 buf_size:11; +#else + u32 buf_size:11; + u32 reserved3:14; + u32 end_of_ring:1; + u32 reserved4:6; +#endif +}; + +struct ksz_desc_tx_buf { +#ifdef __BIG_ENDIAN_BITFIELD + u32 intr:1; + u32 first_seg:1; + u32 last_seg:1; + u32 csum_gen_ip:1; + u32 csum_gen_tcp:1; + u32 csum_gen_udp:1; + u32 end_of_ring:1; + u32 reserved4:1; + u32 dest_port:4; + u32 reserved3:9; + u32 buf_size:11; +#else + u32 buf_size:11; + u32 reserved3:9; + u32 dest_port:4; + u32 reserved4:1; + u32 end_of_ring:1; + u32 csum_gen_udp:1; + u32 csum_gen_tcp:1; + u32 csum_gen_ip:1; + u32 last_seg:1; + u32 first_seg:1; + u32 intr:1; +#endif +}; + +union desc_stat { + struct ksz_desc_rx_stat rx; + struct ksz_desc_tx_stat tx; + u32 data; +}; + +union desc_buf { + struct ksz_desc_rx_buf rx; + struct ksz_desc_tx_buf tx; + u32 data; +}; + +/** + * struct ksz_hw_desc - Hardware descriptor data structure + * @ctrl: Descriptor control value. + * @buf: Descriptor buffer value. + * @addr: Physical address of memory buffer. + * @next: Pointer to next hardware descriptor. + */ +struct ksz_hw_desc { + union desc_stat ctrl; + union desc_buf buf; + u32 addr; + u32 next; +}; + +/** + * struct ksz_sw_desc - Software descriptor data structure + * @ctrl: Descriptor control value. + * @buf: Descriptor buffer value. + * @buf_size: Current buffers size value in hardware descriptor. + */ +struct ksz_sw_desc { + union desc_stat ctrl; + union desc_buf buf; + u32 buf_size; +}; + +/** + * struct ksz_dma_buf - OS dependent DMA buffer data structure + * @skb: Associated socket buffer. + * @dma: Associated physical DMA address. + * len: Actual len used. + */ +struct ksz_dma_buf { + struct sk_buff *skb; + dma_addr_t dma; + int len; +}; + +/** + * struct ksz_desc - Descriptor structure + * @phw: Hardware descriptor pointer to uncached physical memory. + * @sw: Cached memory to hold hardware descriptor values for + * manipulation. + * @dma_buf: Operating system dependent data structure to hold physical + * memory buffer allocation information. + */ +struct ksz_desc { + struct ksz_hw_desc *phw; + struct ksz_sw_desc sw; + struct ksz_dma_buf dma_buf; +}; + +#define DMA_BUFFER(desc) ((struct ksz_dma_buf *)(&(desc)->dma_buf)) + +/** + * struct ksz_desc_info - Descriptor information data structure + * @ring: First descriptor in the ring. + * @cur: Current descriptor being manipulated. + * @ring_virt: First hardware descriptor in the ring. + * @ring_phys: The physical address of the first descriptor of the ring. + * @size: Size of hardware descriptor. + * @alloc: Number of descriptors allocated. + * @avail: Number of descriptors available for use. + * @last: Index for last descriptor released to hardware. + * @next: Index for next descriptor available for use. + * @mask: Mask for index wrapping. + */ +struct ksz_desc_info { + struct ksz_desc *ring; + struct ksz_desc *cur; + struct ksz_hw_desc *ring_virt; + u32 ring_phys; + int size; + int alloc; + int avail; + int last; + int next; + int mask; +}; + +/* + * KSZ8842 switch definitions + */ + +enum { + TABLE_STATIC_MAC = 0, + TABLE_VLAN, + TABLE_DYNAMIC_MAC, + TABLE_MIB +}; + +#define LEARNED_MAC_TABLE_ENTRIES 1024 +#define STATIC_MAC_TABLE_ENTRIES 8 + +/** + * struct ksz_mac_table - Static MAC table data structure + * @mac_addr: MAC address to filter. + * @vid: VID value. + * @fid: FID value. + * @ports: Port membership. + * @override: Override setting. + * @use_fid: FID use setting. + * @valid: Valid setting indicating the entry is being used. + */ +struct ksz_mac_table { + u8 mac_addr[MAC_ADDR_LEN]; + u16 vid; + u8 fid; + u8 ports; + u8 override:1; + u8 use_fid:1; + u8 valid:1; +}; + +#define VLAN_TABLE_ENTRIES 16 + +/** + * struct ksz_vlan_table - VLAN table data structure + * @vid: VID value. + * @fid: FID value. + * @member: Port membership. + */ +struct ksz_vlan_table { + u16 vid; + u8 fid; + u8 member; +}; + +#define DIFFSERV_ENTRIES 64 +#define PRIO_802_1P_ENTRIES 8 +#define PRIO_QUEUES 4 + +#define SWITCH_PORT_NUM 2 +#define TOTAL_PORT_NUM (SWITCH_PORT_NUM + 1) +#define HOST_MASK (1 << SWITCH_PORT_NUM) +#define PORT_MASK 7 + +#define MAIN_PORT 0 +#define OTHER_PORT 1 +#define HOST_PORT SWITCH_PORT_NUM + +#define PORT_COUNTER_NUM 0x20 +#define TOTAL_PORT_COUNTER_NUM (PORT_COUNTER_NUM + 2) + +#define MIB_COUNTER_RX_LO_PRIORITY 0x00 +#define MIB_COUNTER_RX_HI_PRIORITY 0x01 +#define MIB_COUNTER_RX_UNDERSIZE 0x02 +#define MIB_COUNTER_RX_FRAGMENT 0x03 +#define MIB_COUNTER_RX_OVERSIZE 0x04 +#define MIB_COUNTER_RX_JABBER 0x05 +#define MIB_COUNTER_RX_SYMBOL_ERR 0x06 +#define MIB_COUNTER_RX_CRC_ERR 0x07 +#define MIB_COUNTER_RX_ALIGNMENT_ERR 0x08 +#define MIB_COUNTER_RX_CTRL_8808 0x09 +#define MIB_COUNTER_RX_PAUSE 0x0A +#define MIB_COUNTER_RX_BROADCAST 0x0B +#define MIB_COUNTER_RX_MULTICAST 0x0C +#define MIB_COUNTER_RX_UNICAST 0x0D +#define MIB_COUNTER_RX_OCTET_64 0x0E +#define MIB_COUNTER_RX_OCTET_65_127 0x0F +#define MIB_COUNTER_RX_OCTET_128_255 0x10 +#define MIB_COUNTER_RX_OCTET_256_511 0x11 +#define MIB_COUNTER_RX_OCTET_512_1023 0x12 +#define MIB_COUNTER_RX_OCTET_1024_1522 0x13 +#define MIB_COUNTER_TX_LO_PRIORITY 0x14 +#define MIB_COUNTER_TX_HI_PRIORITY 0x15 +#define MIB_COUNTER_TX_LATE_COLLISION 0x16 +#define MIB_COUNTER_TX_PAUSE 0x17 +#define MIB_COUNTER_TX_BROADCAST 0x18 +#define MIB_COUNTER_TX_MULTICAST 0x19 +#define MIB_COUNTER_TX_UNICAST 0x1A +#define MIB_COUNTER_TX_DEFERRED 0x1B +#define MIB_COUNTER_TX_TOTAL_COLLISION 0x1C +#define MIB_COUNTER_TX_EXCESS_COLLISION 0x1D +#define MIB_COUNTER_TX_SINGLE_COLLISION 0x1E +#define MIB_COUNTER_TX_MULTI_COLLISION 0x1F + +#define MIB_COUNTER_RX_DROPPED_PACKET 0x20 +#define MIB_COUNTER_TX_DROPPED_PACKET 0x21 + +/** + * struct ksz_port_mib - Port MIB data structure + * @cnt_ptr: Current pointer to MIB counter index. + * @link_down: Indication the link has just gone down. + * @state: Connection status of the port. + * @mib_start: The starting counter index. Some ports do not start at 0. + * @counter: 64-bit MIB counter value. + * @dropped: Temporary buffer to remember last read packet dropped values. + * + * MIB counters needs to be read periodically so that counters do not get + * overflowed and give incorrect values. A right balance is needed to + * satisfy this condition and not waste too much CPU time. + * + * It is pointless to read MIB counters when the port is disconnected. The + * @state provides the connection status so that MIB counters are read only + * when the port is connected. The @link_down indicates the port is just + * disconnected so that all MIB counters are read one last time to update the + * information. + */ +struct ksz_port_mib { + u8 cnt_ptr; + u8 link_down; + u8 state; + u8 mib_start; + + u64 counter[TOTAL_PORT_COUNTER_NUM]; + u32 dropped[2]; +}; + +/** + * struct ksz_port_cfg - Port configuration data structure + * @vid: VID value. + * @member: Port membership. + * @port_prio: Port priority. + * @rx_rate: Receive priority rate. + * @tx_rate: Transmit priority rate. + * @stp_state: Current Spanning Tree Protocol state. + */ +struct ksz_port_cfg { + u16 vid; + u8 member; + u8 port_prio; + u32 rx_rate[PRIO_QUEUES]; + u32 tx_rate[PRIO_QUEUES]; + int stp_state; +}; + +/** + * struct ksz_switch - KSZ8842 switch data structure + * @mac_table: MAC table entries information. + * @vlan_table: VLAN table entries information. + * @port_cfg: Port configuration information. + * @diffserv: DiffServ priority settings. Possible values from 6-bit of ToS + * (bit7 ~ bit2) field. + * @p_802_1p: 802.1P priority settings. Possible values from 3-bit of 802.1p + * Tag priority field. + * @br_addr: Bridge address. Used for STP. + * @other_addr: Other MAC address. Used for multiple network device mode. + * @broad_per: Broadcast storm percentage. + * @member: Current port membership. Used for STP. + */ +struct ksz_switch { + struct ksz_mac_table mac_table[STATIC_MAC_TABLE_ENTRIES]; + struct ksz_vlan_table vlan_table[VLAN_TABLE_ENTRIES]; + struct ksz_port_cfg port_cfg[TOTAL_PORT_NUM]; + + u8 diffserv[DIFFSERV_ENTRIES]; + u8 p_802_1p[PRIO_802_1P_ENTRIES]; + + u8 br_addr[MAC_ADDR_LEN]; + u8 other_addr[MAC_ADDR_LEN]; + + u8 broad_per; + u8 member; +}; + +#define TX_RATE_UNIT 10000 + +/** + * struct ksz_port_info - Port information data structure + * @state: Connection status of the port. + * @tx_rate: Transmit rate divided by 10000 to get Mbit. + * @duplex: Duplex mode. + * @advertised: Advertised auto-negotiation setting. Used to determine link. + * @partner: Auto-negotiation partner setting. Used to determine link. + * @port_id: Port index to access actual hardware register. + * @pdev: Pointer to OS dependent network device. + */ +struct ksz_port_info { + uint state; + uint tx_rate; + u8 duplex; + u8 advertised; + u8 partner; + u8 port_id; + void *pdev; +}; + +#define MAX_TX_HELD_SIZE 52000 + +/* Hardware features and bug fixes. */ +#define LINK_INT_WORKING (1 << 0) +#define SMALL_PACKET_TX_BUG (1 << 1) +#define HALF_DUPLEX_SIGNAL_BUG (1 << 2) +#define RX_HUGE_FRAME (1 << 4) +#define STP_SUPPORT (1 << 8) + +/* Software overrides. */ +#define PAUSE_FLOW_CTRL (1 << 0) +#define FAST_AGING (1 << 1) + +/** + * struct ksz_hw - KSZ884X hardware data structure + * @io: Virtual address assigned. + * @ksz_switch: Pointer to KSZ8842 switch. + * @port_info: Port information. + * @port_mib: Port MIB information. + * @dev_count: Number of network devices this hardware supports. + * @dst_ports: Destination ports in switch for transmission. + * @id: Hardware ID. Used for display only. + * @mib_cnt: Number of MIB counters this hardware has. + * @mib_port_cnt: Number of ports with MIB counters. + * @tx_cfg: Cached transmit control settings. + * @rx_cfg: Cached receive control settings. + * @intr_mask: Current interrupt mask. + * @intr_set: Current interrup set. + * @intr_blocked: Interrupt blocked. + * @rx_desc_info: Receive descriptor information. + * @tx_desc_info: Transmit descriptor information. + * @tx_int_cnt: Transmit interrupt count. Used for TX optimization. + * @tx_int_mask: Transmit interrupt mask. Used for TX optimization. + * @tx_size: Transmit data size. Used for TX optimization. + * The maximum is defined by MAX_TX_HELD_SIZE. + * @perm_addr: Permanent MAC address. + * @override_addr: Overrided MAC address. + * @address: Additional MAC address entries. + * @addr_list_size: Additional MAC address list size. + * @mac_override: Indication of MAC address overrided. + * @promiscuous: Counter to keep track of promiscuous mode set. + * @all_multi: Counter to keep track of all multicast mode set. + * @multi_list: Multicast address entries. + * @multi_bits: Cached multicast hash table settings. + * @multi_list_size: Multicast address list size. + * @enabled: Indication of hardware enabled. + * @rx_stop: Indication of receive process stop. + * @features: Hardware features to enable. + * @overrides: Hardware features to override. + * @parent: Pointer to parent, network device private structure. + */ +struct ksz_hw { + void __iomem *io; + + struct ksz_switch *ksz_switch; + struct ksz_port_info port_info[SWITCH_PORT_NUM]; + struct ksz_port_mib port_mib[TOTAL_PORT_NUM]; + int dev_count; + int dst_ports; + int id; + int mib_cnt; + int mib_port_cnt; + + u32 tx_cfg; + u32 rx_cfg; + u32 intr_mask; + u32 intr_set; + uint intr_blocked; + + struct ksz_desc_info rx_desc_info; + struct ksz_desc_info tx_desc_info; + + int tx_int_cnt; + int tx_int_mask; + int tx_size; + + u8 perm_addr[MAC_ADDR_LEN]; + u8 override_addr[MAC_ADDR_LEN]; + u8 address[ADDITIONAL_ENTRIES][MAC_ADDR_LEN]; + u8 addr_list_size; + u8 mac_override; + u8 promiscuous; + u8 all_multi; + u8 multi_list[MAX_MULTICAST_LIST][MAC_ADDR_LEN]; + u8 multi_bits[HW_MULTICAST_SIZE]; + u8 multi_list_size; + + u8 enabled; + u8 rx_stop; + u8 reserved2[1]; + + uint features; + uint overrides; + + void *parent; +}; + +enum { + PHY_NO_FLOW_CTRL, + PHY_FLOW_CTRL, + PHY_TX_ONLY, + PHY_RX_ONLY +}; + +/** + * struct ksz_port - Virtual port data structure + * @duplex: Duplex mode setting. 1 for half duplex, 2 for full + * duplex, and 0 for auto, which normally results in full + * duplex. + * @speed: Speed setting. 10 for 10 Mbit, 100 for 100 Mbit, and + * 0 for auto, which normally results in 100 Mbit. + * @force_link: Force link setting. 0 for auto-negotiation, and 1 for + * force. + * @flow_ctrl: Flow control setting. PHY_NO_FLOW_CTRL for no flow + * control, and PHY_FLOW_CTRL for flow control. + * PHY_TX_ONLY and PHY_RX_ONLY are not supported for 100 + * Mbit PHY. + * @first_port: Index of first port this port supports. + * @mib_port_cnt: Number of ports with MIB counters. + * @port_cnt: Number of ports this port supports. + * @counter: Port statistics counter. + * @hw: Pointer to hardware structure. + * @linked: Pointer to port information linked to this port. + */ +struct ksz_port { + u8 duplex; + u8 speed; + u8 force_link; + u8 flow_ctrl; + + int first_port; + int mib_port_cnt; + int port_cnt; + u64 counter[OID_COUNTER_LAST]; + + struct ksz_hw *hw; + struct ksz_port_info *linked; +}; + +/** + * struct ksz_timer_info - Timer information data structure + * @timer: Kernel timer. + * @cnt: Running timer counter. + * @max: Number of times to run timer; -1 for infinity. + * @period: Timer period in jiffies. + */ +struct ksz_timer_info { + struct timer_list timer; + int cnt; + int max; + int period; +}; + +/** + * struct ksz_shared_mem - OS dependent shared memory data structure + * @dma_addr: Physical DMA address allocated. + * @alloc_size: Allocation size. + * @phys: Actual physical address used. + * @alloc_virt: Virtual address allocated. + * @virt: Actual virtual address used. + */ +struct ksz_shared_mem { + dma_addr_t dma_addr; + uint alloc_size; + uint phys; + u8 *alloc_virt; + u8 *virt; +}; + +/** + * struct ksz_counter_info - OS dependent counter information data structure + * @counter: Wait queue to wakeup after counters are read. + * @time: Next time in jiffies to read counter. + * @read: Indication of counters read in full or not. + */ +struct ksz_counter_info { + wait_queue_head_t counter; + unsigned long time; + int read; +}; + +/** + * struct dev_info - Network device information data structure + * @dev: Pointer to network device. + * @pdev: Pointer to PCI device. + * @hw: Hardware structure. + * @desc_pool: Physical memory used for descriptor pool. + * @hwlock: Spinlock to prevent hardware from accessing. + * @lock: Mutex lock to prevent device from accessing. + * @dev_rcv: Receive process function used. + * @last_skb: Socket buffer allocated for descriptor rx fragments. + * @skb_index: Buffer index for receiving fragments. + * @skb_len: Buffer length for receiving fragments. + * @mib_read: Workqueue to read MIB counters. + * @mib_timer_info: Timer to read MIB counters. + * @counter: Used for MIB reading. + * @mtu: Current MTU used. The default is REGULAR_RX_BUF_SIZE; + * the maximum is MAX_RX_BUF_SIZE. + * @opened: Counter to keep track of device open. + * @rx_tasklet: Receive processing tasklet. + * @tx_tasklet: Transmit processing tasklet. + * @wol_enable: Wake-on-LAN enable set by ethtool. + * @wol_support: Wake-on-LAN support used by ethtool. + * @pme_wait: Used for KSZ8841 power management. + */ +struct dev_info { + struct net_device *dev; + struct pci_dev *pdev; + + struct ksz_hw hw; + struct ksz_shared_mem desc_pool; + + spinlock_t hwlock; + struct mutex lock; + + int (*dev_rcv)(struct dev_info *); + + struct sk_buff *last_skb; + int skb_index; + int skb_len; + + struct work_struct mib_read; + struct ksz_timer_info mib_timer_info; + struct ksz_counter_info counter[TOTAL_PORT_NUM]; + + int mtu; + int opened; + + struct tasklet_struct rx_tasklet; + struct tasklet_struct tx_tasklet; + + int wol_enable; + int wol_support; + unsigned long pme_wait; +}; + +/** + * struct dev_priv - Network device private data structure + * @adapter: Adapter device information. + * @port: Port information. + * @monitor_time_info: Timer to monitor ports. + * @proc_sem: Semaphore for proc accessing. + * @id: Device ID. + * @mii_if: MII interface information. + * @advertising: Temporary variable to store advertised settings. + * @msg_enable: The message flags controlling driver output. + * @media_state: The connection status of the device. + * @multicast: The all multicast state of the device. + * @promiscuous: The promiscuous state of the device. + */ +struct dev_priv { + struct dev_info *adapter; + struct ksz_port port; + struct ksz_timer_info monitor_timer_info; + + struct semaphore proc_sem; + int id; + + struct mii_if_info mii_if; + u32 advertising; + + u32 msg_enable; + int media_state; + int multicast; + int promiscuous; +}; + +#define DRV_NAME "KSZ884X PCI" +#define DEVICE_NAME "KSZ884x PCI" +#define DRV_VERSION "1.0.0" +#define DRV_RELDATE "Feb 8, 2010" + +static char version[] __devinitdata = + "Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")"; + +static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 }; + +/* + * Interrupt processing primary routines + */ + +static inline void hw_ack_intr(struct ksz_hw *hw, uint interrupt) +{ + writel(interrupt, hw->io + KS884X_INTERRUPTS_STATUS); +} + +static inline void hw_dis_intr(struct ksz_hw *hw) +{ + hw->intr_blocked = hw->intr_mask; + writel(0, hw->io + KS884X_INTERRUPTS_ENABLE); + hw->intr_set = readl(hw->io + KS884X_INTERRUPTS_ENABLE); +} + +static inline void hw_set_intr(struct ksz_hw *hw, uint interrupt) +{ + hw->intr_set = interrupt; + writel(interrupt, hw->io + KS884X_INTERRUPTS_ENABLE); +} + +static inline void hw_ena_intr(struct ksz_hw *hw) +{ + hw->intr_blocked = 0; + hw_set_intr(hw, hw->intr_mask); +} + +static inline void hw_dis_intr_bit(struct ksz_hw *hw, uint bit) +{ + hw->intr_mask &= ~(bit); +} + +static inline void hw_turn_off_intr(struct ksz_hw *hw, uint interrupt) +{ + u32 read_intr; + + read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE); + hw->intr_set = read_intr & ~interrupt; + writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE); + hw_dis_intr_bit(hw, interrupt); +} + +/** + * hw_turn_on_intr - turn on specified interrupts + * @hw: The hardware instance. + * @bit: The interrupt bits to be on. + * + * This routine turns on the specified interrupts in the interrupt mask so that + * those interrupts will be enabled. + */ +static void hw_turn_on_intr(struct ksz_hw *hw, u32 bit) +{ + hw->intr_mask |= bit; + + if (!hw->intr_blocked) + hw_set_intr(hw, hw->intr_mask); +} + +static inline void hw_ena_intr_bit(struct ksz_hw *hw, uint interrupt) +{ + u32 read_intr; + + read_intr = readl(hw->io + KS884X_INTERRUPTS_ENABLE); + hw->intr_set = read_intr | interrupt; + writel(hw->intr_set, hw->io + KS884X_INTERRUPTS_ENABLE); +} + +static inline void hw_read_intr(struct ksz_hw *hw, uint *status) +{ + *status = readl(hw->io + KS884X_INTERRUPTS_STATUS); + *status = *status & hw->intr_set; +} + +static inline void hw_restore_intr(struct ksz_hw *hw, uint interrupt) +{ + if (interrupt) + hw_ena_intr(hw); +} + +/** + * hw_block_intr - block hardware interrupts + * + * This function blocks all interrupts of the hardware and returns the current + * interrupt enable mask so that interrupts can be restored later. + * + * Return the current interrupt enable mask. + */ +static uint hw_block_intr(struct ksz_hw *hw) +{ + uint interrupt = 0; + + if (!hw->intr_blocked) { + hw_dis_intr(hw); + interrupt = hw->intr_blocked; + } + return interrupt; +} + +/* + * Hardware descriptor routines + */ + +static inline void reset_desc(struct ksz_desc *desc, union desc_stat status) +{ + status.rx.hw_owned = 0; + desc->phw->ctrl.data = cpu_to_le32(status.data); +} + +static inline void release_desc(struct ksz_desc *desc) +{ + desc->sw.ctrl.tx.hw_owned = 1; + if (desc->sw.buf_size != desc->sw.buf.data) { + desc->sw.buf_size = desc->sw.buf.data; + desc->phw->buf.data = cpu_to_le32(desc->sw.buf.data); + } + desc->phw->ctrl.data = cpu_to_le32(desc->sw.ctrl.data); +} + +static void get_rx_pkt(struct ksz_desc_info *info, struct ksz_desc **desc) +{ + *desc = &info->ring[info->last]; + info->last++; + info->last &= info->mask; + info->avail--; + (*desc)->sw.buf.data &= ~KS_DESC_RX_MASK; +} + +static inline void set_rx_buf(struct ksz_desc *desc, u32 addr) +{ + desc->phw->addr = cpu_to_le32(addr); +} + +static inline void set_rx_len(struct ksz_desc *desc, u32 len) +{ + desc->sw.buf.rx.buf_size = len; +} + +static inline void get_tx_pkt(struct ksz_desc_info *info, + struct ksz_desc **desc) +{ + *desc = &info->ring[info->next]; + info->next++; + info->next &= info->mask; + info->avail--; + (*desc)->sw.buf.data &= ~KS_DESC_TX_MASK; +} + +static inline void set_tx_buf(struct ksz_desc *desc, u32 addr) +{ + desc->phw->addr = cpu_to_le32(addr); +} + +static inline void set_tx_len(struct ksz_desc *desc, u32 len) +{ + desc->sw.buf.tx.buf_size = len; +} + +/* Switch functions */ + +#define TABLE_READ 0x10 +#define TABLE_SEL_SHIFT 2 + +#define HW_DELAY(hw, reg) \ + do { \ + u16 dummy; \ + dummy = readw(hw->io + reg); \ + } while (0) + +/** + * sw_r_table - read 4 bytes of data from switch table + * @hw: The hardware instance. + * @table: The table selector. + * @addr: The address of the table entry. + * @data: Buffer to store the read data. + * + * This routine reads 4 bytes of data from the table of the switch. + * Hardware interrupts are disabled to minimize corruption of read data. + */ +static void sw_r_table(struct ksz_hw *hw, int table, u16 addr, u32 *data) +{ + u16 ctrl_addr; + uint interrupt; + + ctrl_addr = (((table << TABLE_SEL_SHIFT) | TABLE_READ) << 8) | addr; + + interrupt = hw_block_intr(hw); + + writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET); + HW_DELAY(hw, KS884X_IACR_OFFSET); + *data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET); + + hw_restore_intr(hw, interrupt); +} + +/** + * sw_w_table_64 - write 8 bytes of data to the switch table + * @hw: The hardware instance. + * @table: The table selector. + * @addr: The address of the table entry. + * @data_hi: The high part of data to be written (bit63 ~ bit32). + * @data_lo: The low part of data to be written (bit31 ~ bit0). + * + * This routine writes 8 bytes of data to the table of the switch. + * Hardware interrupts are disabled to minimize corruption of written data. + */ +static void sw_w_table_64(struct ksz_hw *hw, int table, u16 addr, u32 data_hi, + u32 data_lo) +{ + u16 ctrl_addr; + uint interrupt; + + ctrl_addr = ((table << TABLE_SEL_SHIFT) << 8) | addr; + + interrupt = hw_block_intr(hw); + + writel(data_hi, hw->io + KS884X_ACC_DATA_4_OFFSET); + writel(data_lo, hw->io + KS884X_ACC_DATA_0_OFFSET); + + writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET); + HW_DELAY(hw, KS884X_IACR_OFFSET); + + hw_restore_intr(hw, interrupt); +} + +/** + * sw_w_sta_mac_table - write to the static MAC table + * @hw: The hardware instance. + * @addr: The address of the table entry. + * @mac_addr: The MAC address. + * @ports: The port members. + * @override: The flag to override the port receive/transmit settings. + * @valid: The flag to indicate entry is valid. + * @use_fid: The flag to indicate the FID is valid. + * @fid: The FID value. + * + * This routine writes an entry of the static MAC table of the switch. It + * calls sw_w_table_64() to write the data. + */ +static void sw_w_sta_mac_table(struct ksz_hw *hw, u16 addr, u8 *mac_addr, + u8 ports, int override, int valid, int use_fid, u8 fid) +{ + u32 data_hi; + u32 data_lo; + + data_lo = ((u32) mac_addr[2] << 24) | + ((u32) mac_addr[3] << 16) | + ((u32) mac_addr[4] << 8) | mac_addr[5]; + data_hi = ((u32) mac_addr[0] << 8) | mac_addr[1]; + data_hi |= (u32) ports << STATIC_MAC_FWD_PORTS_SHIFT; + + if (override) + data_hi |= STATIC_MAC_TABLE_OVERRIDE; + if (use_fid) { + data_hi |= STATIC_MAC_TABLE_USE_FID; + data_hi |= (u32) fid << STATIC_MAC_FID_SHIFT; + } + if (valid) + data_hi |= STATIC_MAC_TABLE_VALID; + + sw_w_table_64(hw, TABLE_STATIC_MAC, addr, data_hi, data_lo); +} + +/** + * sw_r_vlan_table - read from the VLAN table + * @hw: The hardware instance. + * @addr: The address of the table entry. + * @vid: Buffer to store the VID. + * @fid: Buffer to store the VID. + * @member: Buffer to store the port membership. + * + * This function reads an entry of the VLAN table of the switch. It calls + * sw_r_table() to get the data. + * + * Return 0 if the entry is valid; otherwise -1. + */ +static int sw_r_vlan_table(struct ksz_hw *hw, u16 addr, u16 *vid, u8 *fid, + u8 *member) +{ + u32 data; + + sw_r_table(hw, TABLE_VLAN, addr, &data); + if (data & VLAN_TABLE_VALID) { + *vid = (u16)(data & VLAN_TABLE_VID); + *fid = (u8)((data & VLAN_TABLE_FID) >> VLAN_TABLE_FID_SHIFT); + *member = (u8)((data & VLAN_TABLE_MEMBERSHIP) >> + VLAN_TABLE_MEMBERSHIP_SHIFT); + return 0; + } + return -1; +} + +/** + * port_r_mib_cnt - read MIB counter + * @hw: The hardware instance. + * @port: The port index. + * @addr: The address of the counter. + * @cnt: Buffer to store the counter. + * + * This routine reads a MIB counter of the port. + * Hardware interrupts are disabled to minimize corruption of read data. + */ +static void port_r_mib_cnt(struct ksz_hw *hw, int port, u16 addr, u64 *cnt) +{ + u32 data; + u16 ctrl_addr; + uint interrupt; + int timeout; + + ctrl_addr = addr + PORT_COUNTER_NUM * port; + + interrupt = hw_block_intr(hw); + + ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ) << 8); + writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET); + HW_DELAY(hw, KS884X_IACR_OFFSET); + + for (timeout = 100; timeout > 0; timeout--) { + data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET); + + if (data & MIB_COUNTER_VALID) { + if (data & MIB_COUNTER_OVERFLOW) + *cnt += MIB_COUNTER_VALUE + 1; + *cnt += data & MIB_COUNTER_VALUE; + break; + } + } + + hw_restore_intr(hw, interrupt); +} + +/** + * port_r_mib_pkt - read dropped packet counts + * @hw: The hardware instance. + * @port: The port index. + * @cnt: Buffer to store the receive and transmit dropped packet counts. + * + * This routine reads the dropped packet counts of the port. + * Hardware interrupts are disabled to minimize corruption of read data. + */ +static void port_r_mib_pkt(struct ksz_hw *hw, int port, u32 *last, u64 *cnt) +{ + u32 cur; + u32 data; + u16 ctrl_addr; + uint interrupt; + int index; + + index = KS_MIB_PACKET_DROPPED_RX_0 + port; + do { + interrupt = hw_block_intr(hw); + + ctrl_addr = (u16) index; + ctrl_addr |= (((TABLE_MIB << TABLE_SEL_SHIFT) | TABLE_READ) + << 8); + writew(ctrl_addr, hw->io + KS884X_IACR_OFFSET); + HW_DELAY(hw, KS884X_IACR_OFFSET); + data = readl(hw->io + KS884X_ACC_DATA_0_OFFSET); + + hw_restore_intr(hw, interrupt); + + data &= MIB_PACKET_DROPPED; + cur = *last; + if (data != cur) { + *last = data; + if (data < cur) + data += MIB_PACKET_DROPPED + 1; + data -= cur; + *cnt += data; + } + ++last; + ++cnt; + index -= KS_MIB_PACKET_DROPPED_TX - + KS_MIB_PACKET_DROPPED_TX_0 + 1; + } while (index >= KS_MIB_PACKET_DROPPED_TX_0 + port); +} + +/** + * port_r_cnt - read MIB counters periodically + * @hw: The hardware instance. + * @port: The port index. + * + * This routine is used to read the counters of the port periodically to avoid + * counter overflow. The hardware should be acquired first before calling this + * routine. + * + * Return non-zero when not all counters not read. + */ +static int port_r_cnt(struct ksz_hw *hw, int port) +{ + struct ksz_port_mib *mib = &hw->port_mib[port]; + + if (mib->mib_start < PORT_COUNTER_NUM) + while (mib->cnt_ptr < PORT_COUNTER_NUM) { + port_r_mib_cnt(hw, port, mib->cnt_ptr, + &mib->counter[mib->cnt_ptr]); + ++mib->cnt_ptr; + } + if (hw->mib_cnt > PORT_COUNTER_NUM) + port_r_mib_pkt(hw, port, mib->dropped, + &mib->counter[PORT_COUNTER_NUM]); + mib->cnt_ptr = 0; + return 0; +} + +/** + * port_init_cnt - initialize MIB counter values + * @hw: The hardware instance. + * @port: The port index. + * + * This routine is used to initialize all counters to zero if the hardware + * cannot do it after reset. + */ +static void port_init_cnt(struct ksz_hw *hw, int port) +{ + struct ksz_port_mib *mib = &hw->port_mib[port]; + + mib->cnt_ptr = 0; + if (mib->mib_start < PORT_COUNTER_NUM) + do { + port_r_mib_cnt(hw, port, mib->cnt_ptr, + &mib->counter[mib->cnt_ptr]); + ++mib->cnt_ptr; + } while (mib->cnt_ptr < PORT_COUNTER_NUM); + if (hw->mib_cnt > PORT_COUNTER_NUM) + port_r_mib_pkt(hw, port, mib->dropped, + &mib->counter[PORT_COUNTER_NUM]); + memset((void *) mib->counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM); + mib->cnt_ptr = 0; +} + +/* + * Port functions + */ + +/** + * port_chk - check port register bits + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the port register. + * @bits: The data bits to check. + * + * This function checks whether the specified bits of the port register are set + * or not. + * + * Return 0 if the bits are not set. + */ +static int port_chk(struct ksz_hw *hw, int port, int offset, u16 bits) +{ + u32 addr; + u16 data; + + PORT_CTRL_ADDR(port, addr); + addr += offset; + data = readw(hw->io + addr); + return (data & bits) == bits; +} + +/** + * port_cfg - set port register bits + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the port register. + * @bits: The data bits to set. + * @set: The flag indicating whether the bits are to be set or not. + * + * This routine sets or resets the specified bits of the port register. + */ +static void port_cfg(struct ksz_hw *hw, int port, int offset, u16 bits, + int set) +{ + u32 addr; + u16 data; + + PORT_CTRL_ADDR(port, addr); + addr += offset; + data = readw(hw->io + addr); + if (set) + data |= bits; + else + data &= ~bits; + writew(data, hw->io + addr); +} + +/** + * port_chk_shift - check port bit + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the register. + * @shift: Number of bits to shift. + * + * This function checks whether the specified port is set in the register or + * not. + * + * Return 0 if the port is not set. + */ +static int port_chk_shift(struct ksz_hw *hw, int port, u32 addr, int shift) +{ + u16 data; + u16 bit = 1 << port; + + data = readw(hw->io + addr); + data >>= shift; + return (data & bit) == bit; +} + +/** + * port_cfg_shift - set port bit + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the register. + * @shift: Number of bits to shift. + * @set: The flag indicating whether the port is to be set or not. + * + * This routine sets or resets the specified port in the register. + */ +static void port_cfg_shift(struct ksz_hw *hw, int port, u32 addr, int shift, + int set) +{ + u16 data; + u16 bits = 1 << port; + + data = readw(hw->io + addr); + bits <<= shift; + if (set) + data |= bits; + else + data &= ~bits; + writew(data, hw->io + addr); +} + +/** + * port_r8 - read byte from port register + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the port register. + * @data: Buffer to store the data. + * + * This routine reads a byte from the port register. + */ +static void port_r8(struct ksz_hw *hw, int port, int offset, u8 *data) +{ + u32 addr; + + PORT_CTRL_ADDR(port, addr); + addr += offset; + *data = readb(hw->io + addr); +} + +/** + * port_r16 - read word from port register. + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the port register. + * @data: Buffer to store the data. + * + * This routine reads a word from the port register. + */ +static void port_r16(struct ksz_hw *hw, int port, int offset, u16 *data) +{ + u32 addr; + + PORT_CTRL_ADDR(port, addr); + addr += offset; + *data = readw(hw->io + addr); +} + +/** + * port_w16 - write word to port register. + * @hw: The hardware instance. + * @port: The port index. + * @offset: The offset of the port register. + * @data: Data to write. + * + * This routine writes a word to the port register. + */ +static void port_w16(struct ksz_hw *hw, int port, int offset, u16 data) +{ + u32 addr; + + PORT_CTRL_ADDR(port, addr); + addr += offset; + writew(data, hw->io + addr); +} + +/** + * sw_chk - check switch register bits + * @hw: The hardware instance. + * @addr: The address of the switch register. + * @bits: The data bits to check. + * + * This function checks whether the specified bits of the switch register are + * set or not. + * + * Return 0 if the bits are not set. + */ +static int sw_chk(struct ksz_hw *hw, u32 addr, u16 bits) +{ + u16 data; + + data = readw(hw->io + addr); + return (data & bits) == bits; +} + +/** + * sw_cfg - set switch register bits + * @hw: The hardware instance. + * @addr: The address of the switch register. + * @bits: The data bits to set. + * @set: The flag indicating whether the bits are to be set or not. + * + * This function sets or resets the specified bits of the switch register. + */ +static void sw_cfg(struct ksz_hw *hw, u32 addr, u16 bits, int set) +{ + u16 data; + + data = readw(hw->io + addr); + if (set) + data |= bits; + else + data &= ~bits; + writew(data, hw->io + addr); +} + +/* Bandwidth */ + +static inline void port_cfg_broad_storm(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM, set); +} + +static inline int port_chk_broad_storm(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_BROADCAST_STORM); +} + +/* Driver set switch broadcast storm protection at 10% rate. */ +#define BROADCAST_STORM_PROTECTION_RATE 10 + +/* 148,800 frames * 67 ms / 100 */ +#define BROADCAST_STORM_VALUE 9969 + +/** + * sw_cfg_broad_storm - configure broadcast storm threshold + * @hw: The hardware instance. + * @percent: Broadcast storm threshold in percent of transmit rate. + * + * This routine configures the broadcast storm threshold of the switch. + */ +static void sw_cfg_broad_storm(struct ksz_hw *hw, u8 percent) +{ + u16 data; + u32 value = ((u32) BROADCAST_STORM_VALUE * (u32) percent / 100); + + if (value > BROADCAST_STORM_RATE) + value = BROADCAST_STORM_RATE; + + data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET); + data &= ~(BROADCAST_STORM_RATE_LO | BROADCAST_STORM_RATE_HI); + data |= ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8); + writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET); +} + +/** + * sw_get_board_storm - get broadcast storm threshold + * @hw: The hardware instance. + * @percent: Buffer to store the broadcast storm threshold percentage. + * + * This routine retrieves the broadcast storm threshold of the switch. + */ +static void sw_get_broad_storm(struct ksz_hw *hw, u8 *percent) +{ + int num; + u16 data; + + data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET); + num = (data & BROADCAST_STORM_RATE_HI); + num <<= 8; + num |= (data & BROADCAST_STORM_RATE_LO) >> 8; + num = (num * 100 + BROADCAST_STORM_VALUE / 2) / BROADCAST_STORM_VALUE; + *percent = (u8) num; +} + +/** + * sw_dis_broad_storm - disable broadstorm + * @hw: The hardware instance. + * @port: The port index. + * + * This routine disables the broadcast storm limit function of the switch. + */ +static void sw_dis_broad_storm(struct ksz_hw *hw, int port) +{ + port_cfg_broad_storm(hw, port, 0); +} + +/** + * sw_ena_broad_storm - enable broadcast storm + * @hw: The hardware instance. + * @port: The port index. + * + * This routine enables the broadcast storm limit function of the switch. + */ +static void sw_ena_broad_storm(struct ksz_hw *hw, int port) +{ + sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per); + port_cfg_broad_storm(hw, port, 1); +} + +/** + * sw_init_broad_storm - initialize broadcast storm + * @hw: The hardware instance. + * + * This routine initializes the broadcast storm limit function of the switch. + */ +static void sw_init_broad_storm(struct ksz_hw *hw) +{ + int port; + + hw->ksz_switch->broad_per = 1; + sw_cfg_broad_storm(hw, hw->ksz_switch->broad_per); + for (port = 0; port < TOTAL_PORT_NUM; port++) + sw_dis_broad_storm(hw, port); + sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, MULTICAST_STORM_DISABLE, 1); +} + +/** + * hw_cfg_broad_storm - configure broadcast storm + * @hw: The hardware instance. + * @percent: Broadcast storm threshold in percent of transmit rate. + * + * This routine configures the broadcast storm threshold of the switch. + * It is called by user functions. The hardware should be acquired first. + */ +static void hw_cfg_broad_storm(struct ksz_hw *hw, u8 percent) +{ + if (percent > 100) + percent = 100; + + sw_cfg_broad_storm(hw, percent); + sw_get_broad_storm(hw, &percent); + hw->ksz_switch->broad_per = percent; +} + +/** + * sw_dis_prio_rate - disable switch priority rate + * @hw: The hardware instance. + * @port: The port index. + * + * This routine disables the priority rate function of the switch. + */ +static void sw_dis_prio_rate(struct ksz_hw *hw, int port) +{ + u32 addr; + + PORT_CTRL_ADDR(port, addr); + addr += KS8842_PORT_IN_RATE_OFFSET; + writel(0, hw->io + addr); +} + +/** + * sw_init_prio_rate - initialize switch prioirty rate + * @hw: The hardware instance. + * + * This routine initializes the priority rate function of the switch. + */ +static void sw_init_prio_rate(struct ksz_hw *hw) +{ + int port; + int prio; + struct ksz_switch *sw = hw->ksz_switch; + + for (port = 0; port < TOTAL_PORT_NUM; port++) { + for (prio = 0; prio < PRIO_QUEUES; prio++) { + sw->port_cfg[port].rx_rate[prio] = + sw->port_cfg[port].tx_rate[prio] = 0; + } + sw_dis_prio_rate(hw, port); + } +} + +/* Communication */ + +static inline void port_cfg_back_pressure(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE, set); +} + +static inline void port_cfg_force_flow_ctrl(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL, set); +} + +static inline int port_chk_back_pressure(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_BACK_PRESSURE); +} + +static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_FORCE_FLOW_CTRL); +} + +/* Spanning Tree */ + +static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set); +} + +static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_RX_ENABLE, set); +} + +static inline void port_cfg_tx(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_TX_ENABLE, set); +} + +static inline void sw_cfg_fast_aging(struct ksz_hw *hw, int set) +{ + sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, SWITCH_FAST_AGING, set); +} + +static inline void sw_flush_dyn_mac_table(struct ksz_hw *hw) +{ + if (!(hw->overrides & FAST_AGING)) { + sw_cfg_fast_aging(hw, 1); + mdelay(1); + sw_cfg_fast_aging(hw, 0); + } +} + +/* VLAN */ + +static inline void port_cfg_ins_tag(struct ksz_hw *hw, int p, int insert) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG, insert); +} + +static inline void port_cfg_rmv_tag(struct ksz_hw *hw, int p, int remove) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG, remove); +} + +static inline int port_chk_ins_tag(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_INSERT_TAG); +} + +static inline int port_chk_rmv_tag(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_REMOVE_TAG); +} + +static inline void port_cfg_dis_non_vid(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID, set); +} + +static inline void port_cfg_in_filter(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER, set); +} + +static inline int port_chk_dis_non_vid(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_DISCARD_NON_VID); +} + +static inline int port_chk_in_filter(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_INGRESS_VLAN_FILTER); +} + +/* Mirroring */ + +static inline void port_cfg_mirror_sniffer(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_SNIFFER, set); +} + +static inline void port_cfg_mirror_rx(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_RX, set); +} + +static inline void port_cfg_mirror_tx(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_MIRROR_TX, set); +} + +static inline void sw_cfg_mirror_rx_tx(struct ksz_hw *hw, int set) +{ + sw_cfg(hw, KS8842_SWITCH_CTRL_2_OFFSET, SWITCH_MIRROR_RX_TX, set); +} + +static void sw_init_mirror(struct ksz_hw *hw) +{ + int port; + + for (port = 0; port < TOTAL_PORT_NUM; port++) { + port_cfg_mirror_sniffer(hw, port, 0); + port_cfg_mirror_rx(hw, port, 0); + port_cfg_mirror_tx(hw, port, 0); + } + sw_cfg_mirror_rx_tx(hw, 0); +} + +static inline void sw_cfg_unk_def_deliver(struct ksz_hw *hw, int set) +{ + sw_cfg(hw, KS8842_SWITCH_CTRL_7_OFFSET, + SWITCH_UNK_DEF_PORT_ENABLE, set); +} + +static inline int sw_cfg_chk_unk_def_deliver(struct ksz_hw *hw) +{ + return sw_chk(hw, KS8842_SWITCH_CTRL_7_OFFSET, + SWITCH_UNK_DEF_PORT_ENABLE); +} + +static inline void sw_cfg_unk_def_port(struct ksz_hw *hw, int port, int set) +{ + port_cfg_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0, set); +} + +static inline int sw_chk_unk_def_port(struct ksz_hw *hw, int port) +{ + return port_chk_shift(hw, port, KS8842_SWITCH_CTRL_7_OFFSET, 0); +} + +/* Priority */ + +static inline void port_cfg_diffserv(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE, set); +} + +static inline void port_cfg_802_1p(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE, set); +} + +static inline void port_cfg_replace_vid(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING, set); +} + +static inline void port_cfg_prio(struct ksz_hw *hw, int p, int set) +{ + port_cfg(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE, set); +} + +static inline int port_chk_diffserv(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_DIFFSERV_ENABLE); +} + +static inline int port_chk_802_1p(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_802_1P_ENABLE); +} + +static inline int port_chk_replace_vid(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_2_OFFSET, PORT_USER_PRIORITY_CEILING); +} + +static inline int port_chk_prio(struct ksz_hw *hw, int p) +{ + return port_chk(hw, p, + KS8842_PORT_CTRL_1_OFFSET, PORT_PRIO_QUEUE_ENABLE); +} + +/** + * sw_dis_diffserv - disable switch DiffServ priority + * @hw: The hardware instance. + * @port: The port index. + * + * This routine disables the DiffServ priority function of the switch. + */ +static void sw_dis_diffserv(struct ksz_hw *hw, int port) +{ + port_cfg_diffserv(hw, port, 0); +} + +/** + * sw_dis_802_1p - disable switch 802.1p priority + * @hw: The hardware instance. + * @port: The port index. + * + * This routine disables the 802.1p priority function of the switch. + */ +static void sw_dis_802_1p(struct ksz_hw *hw, int port) +{ + port_cfg_802_1p(hw, port, 0); +} + +/** + * sw_cfg_replace_null_vid - + * @hw: The hardware instance. + * @set: The flag to disable or enable. + * + */ +static void sw_cfg_replace_null_vid(struct ksz_hw *hw, int set) +{ + sw_cfg(hw, KS8842_SWITCH_CTRL_3_OFFSET, SWITCH_REPLACE_NULL_VID, set); +} + +/** + * sw_cfg_replace_vid - enable switch 802.10 priority re-mapping + * @hw: The hardware instance. + * @port: The port index. + * @set: The flag to disable or enable. + * + * This routine enables the 802.1p priority re-mapping function of the switch. + * That allows 802.1p priority field to be replaced with the port's default + * tag's priority value if the ingress packet's 802.1p priority has a higher + * priority than port's default tag's priority. + */ +static void sw_cfg_replace_vid(struct ksz_hw *hw, int port, int set) +{ + port_cfg_replace_vid(hw, port, set); +} + +/** + * sw_cfg_port_based - configure switch port based priority + * @hw: The hardware instance. + * @port: The port index. + * @prio: The priority to set. + * + * This routine configures the port based priority of the switch. + */ +static void sw_cfg_port_based(struct ksz_hw *hw, int port, u8 prio) +{ + u16 data; + + if (prio > PORT_BASED_PRIORITY_BASE) + prio = PORT_BASED_PRIORITY_BASE; + + hw->ksz_switch->port_cfg[port].port_prio = prio; + + port_r16(hw, port, KS8842_PORT_CTRL_1_OFFSET, &data); + data &= ~PORT_BASED_PRIORITY_MASK; + data |= prio << PORT_BASED_PRIORITY_SHIFT; + port_w16(hw, port, KS8842_PORT_CTRL_1_OFFSET, data); +} + +/** + * sw_dis_multi_queue - disable transmit multiple queues + * @hw: The hardware instance. + * @port: The port index. + * + * This routine disables the transmit multiple queues selection of the switch + * port. Only single transmit queue on the port. + */ +static void sw_dis_multi_queue(struct ksz_hw *hw, int port) +{ + port_cfg_prio(hw, port, 0); +} + +/** + * sw_init_prio - initialize switch priority + * @hw: The hardware instance. + * + * This routine initializes the switch QoS priority functions. + */ +static void sw_init_prio(struct ksz_hw *hw) +{ + int port; + int tos; + struct ksz_switch *sw = hw->ksz_switch; + + /* + * Init all the 802.1p tag priority value to be assigned to different + * priority queue. + */ + sw->p_802_1p[0] = 0; + sw->p_802_1p[1] = 0; + sw->p_802_1p[2] = 1; + sw->p_802_1p[3] = 1; + sw->p_802_1p[4] = 2; + sw->p_802_1p[5] = 2; + sw->p_802_1p[6] = 3; + sw->p_802_1p[7] = 3; + + /* + * Init all the DiffServ priority value to be assigned to priority + * queue 0. + */ + for (tos = 0; tos < DIFFSERV_ENTRIES; tos++) + sw->diffserv[tos] = 0; + + /* All QoS functions disabled. */ + for (port = 0; port < TOTAL_PORT_NUM; port++) { + sw_dis_multi_queue(hw, port); + sw_dis_diffserv(hw, port); + sw_dis_802_1p(hw, port); + sw_cfg_replace_vid(hw, port, 0); + + sw->port_cfg[port].port_prio = 0; + sw_cfg_port_based(hw, port, sw->port_cfg[port].port_prio); + } + sw_cfg_replace_null_vid(hw, 0); +} + +/** + * port_get_def_vid - get port default VID. + * @hw: The hardware instance. + * @port: The port index. + * @vid: Buffer to store the VID. + * + * This routine retrieves the default VID of the port. + */ +static void port_get_def_vid(struct ksz_hw *hw, int port, u16 *vid) +{ + u32 addr; + + PORT_CTRL_ADDR(port, addr); + addr += KS8842_PORT_CTRL_VID_OFFSET; + *vid = readw(hw->io + addr); +} + +/** + * sw_init_vlan - initialize switch VLAN + * @hw: The hardware instance. + * + * This routine initializes the VLAN function of the switch. + */ +static void sw_init_vlan(struct ksz_hw *hw) +{ + int port; + int entry; + struct ksz_switch *sw = hw->ksz_switch; + + /* Read 16 VLAN entries from device's VLAN table. */ + for (entry = 0; entry < VLAN_TABLE_ENTRIES; entry++) { + sw_r_vlan_table(hw, entry, + &sw->vlan_table[entry].vid, + &sw->vlan_table[entry].fid, + &sw->vlan_table[entry].member); + } + + for (port = 0; port < TOTAL_PORT_NUM; port++) { + port_get_def_vid(hw, port, &sw->port_cfg[port].vid); + sw->port_cfg[port].member = PORT_MASK; + } +} + +/** + * sw_cfg_port_base_vlan - configure port-based VLAN membership + * @hw: The hardware instance. + * @port: The port index. + * @member: The port-based VLAN membership. + * + * This routine configures the port-based VLAN membership of the port. + */ +static void sw_cfg_port_base_vlan(struct ksz_hw *hw, int port, u8 member) +{ + u32 addr; + u8 data; + + PORT_CTRL_ADDR(port, addr); + addr += KS8842_PORT_CTRL_2_OFFSET; + + data = readb(hw->io + addr); + data &= ~PORT_VLAN_MEMBERSHIP; + data |= (member & PORT_MASK); + writeb(data, hw->io + addr); + + hw->ksz_switch->port_cfg[port].member = member; +} + +/** + * sw_get_addr - get the switch MAC address. + * @hw: The hardware instance. + * @mac_addr: Buffer to store the MAC address. + * + * This function retrieves the MAC address of the switch. + */ +static inline void sw_get_addr(struct ksz_hw *hw, u8 *mac_addr) +{ + int i; + + for (i = 0; i < 6; i += 2) { + mac_addr[i] = readb(hw->io + KS8842_MAC_ADDR_0_OFFSET + i); + mac_addr[1 + i] = readb(hw->io + KS8842_MAC_ADDR_1_OFFSET + i); + } +} + +/** + * sw_set_addr - configure switch MAC address + * @hw: The hardware instance. + * @mac_addr: The MAC address. + * + * This function configures the MAC address of the switch. + */ +static void sw_set_addr(struct ksz_hw *hw, u8 *mac_addr) +{ + int i; + + for (i = 0; i < 6; i += 2) { + writeb(mac_addr[i], hw->io + KS8842_MAC_ADDR_0_OFFSET + i); + writeb(mac_addr[1 + i], hw->io + KS8842_MAC_ADDR_1_OFFSET + i); + } +} + +/** + * sw_set_global_ctrl - set switch global control + * @hw: The hardware instance. + * + * This routine sets the global control of the switch function. + */ +static void sw_set_global_ctrl(struct ksz_hw *hw) +{ + u16 data; + + /* Enable switch MII flow control. */ + data = readw(hw->io + KS8842_SWITCH_CTRL_3_OFFSET); + data |= SWITCH_FLOW_CTRL; + writew(data, hw->io + KS8842_SWITCH_CTRL_3_OFFSET); + + data = readw(hw->io + KS8842_SWITCH_CTRL_1_OFFSET); + + /* Enable aggressive back off algorithm in half duplex mode. */ + data |= SWITCH_AGGR_BACKOFF; + + /* Enable automatic fast aging when link changed detected. */ + data |= SWITCH_AGING_ENABLE; + data |= SWITCH_LINK_AUTO_AGING; + + if (hw->overrides & FAST_AGING) + data |= SWITCH_FAST_AGING; + else + data &= ~SWITCH_FAST_AGING; + writew(data, hw->io + KS8842_SWITCH_CTRL_1_OFFSET); + + data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET); + + /* Enable no excessive collision drop. */ + data |= NO_EXC_COLLISION_DROP; + writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET); +} + +enum { + STP_STATE_DISABLED = 0, + STP_STATE_LISTENING, + STP_STATE_LEARNING, + STP_STATE_FORWARDING, + STP_STATE_BLOCKED, + STP_STATE_SIMPLE +}; + +/** + * port_set_stp_state - configure port spanning tree state + * @hw: The hardware instance. + * @port: The port index. + * @state: The spanning tree state. + * + * This routine configures the spanning tree state of the port. + */ +static void port_set_stp_state(struct ksz_hw *hw, int port, int state) +{ + u16 data; + + port_r16(hw, port, KS8842_PORT_CTRL_2_OFFSET, &data); + switch (state) { + case STP_STATE_DISABLED: + data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE); + data |= PORT_LEARN_DISABLE; + break; + case STP_STATE_LISTENING: +/* + * No need to turn on transmit because of port direct mode. + * Turning on receive is required if static MAC table is not setup. + */ + data &= ~PORT_TX_ENABLE; + data |= PORT_RX_ENABLE; + data |= PORT_LEARN_DISABLE; + break; + case STP_STATE_LEARNING: + data &= ~PORT_TX_ENABLE; + data |= PORT_RX_ENABLE; + data &= ~PORT_LEARN_DISABLE; + break; + case STP_STATE_FORWARDING: + data |= (PORT_TX_ENABLE | PORT_RX_ENABLE); + data &= ~PORT_LEARN_DISABLE; + break; + case STP_STATE_BLOCKED: +/* + * Need to setup static MAC table with override to keep receiving BPDU + * messages. See sw_init_stp routine. + */ + data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE); + data |= PORT_LEARN_DISABLE; + break; + case STP_STATE_SIMPLE: + data |= (PORT_TX_ENABLE | PORT_RX_ENABLE); + data |= PORT_LEARN_DISABLE; + break; + } + port_w16(hw, port, KS8842_PORT_CTRL_2_OFFSET, data); + hw->ksz_switch->port_cfg[port].stp_state = state; +} + +#define STP_ENTRY 0 +#define BROADCAST_ENTRY 1 +#define BRIDGE_ADDR_ENTRY 2 +#define IPV6_ADDR_ENTRY 3 + +/** + * sw_clr_sta_mac_table - clear static MAC table + * @hw: The hardware instance. + * + * This routine clears the static MAC table. + */ +static void sw_clr_sta_mac_table(struct ksz_hw *hw) +{ + struct ksz_mac_table *entry; + int i; + + for (i = 0; i < STATIC_MAC_TABLE_ENTRIES; i++) { + entry = &hw->ksz_switch->mac_table[i]; + sw_w_sta_mac_table(hw, i, + entry->mac_addr, entry->ports, + entry->override, 0, + entry->use_fid, entry->fid); + } +} + +/** + * sw_init_stp - initialize switch spanning tree support + * @hw: The hardware instance. + * + * This routine initializes the spanning tree support of the switch. + */ +static void sw_init_stp(struct ksz_hw *hw) +{ + struct ksz_mac_table *entry; + + entry = &hw->ksz_switch->mac_table[STP_ENTRY]; + entry->mac_addr[0] = 0x01; + entry->mac_addr[1] = 0x80; + entry->mac_addr[2] = 0xC2; + entry->mac_addr[3] = 0x00; + entry->mac_addr[4] = 0x00; + entry->mac_addr[5] = 0x00; + entry->ports = HOST_MASK; + entry->override = 1; + entry->valid = 1; + sw_w_sta_mac_table(hw, STP_ENTRY, + entry->mac_addr, entry->ports, + entry->override, entry->valid, + entry->use_fid, entry->fid); +} + +/** + * sw_block_addr - block certain packets from the host port + * @hw: The hardware instance. + * + * This routine blocks certain packets from reaching to the host port. + */ +static void sw_block_addr(struct ksz_hw *hw) +{ + struct ksz_mac_table *entry; + int i; + + for (i = BROADCAST_ENTRY; i <= IPV6_ADDR_ENTRY; i++) { + entry = &hw->ksz_switch->mac_table[i]; + entry->valid = 0; + sw_w_sta_mac_table(hw, i, + entry->mac_addr, entry->ports, + entry->override, entry->valid, + entry->use_fid, entry->fid); + } +} + +#define PHY_LINK_SUPPORT \ + (PHY_AUTO_NEG_ASYM_PAUSE | \ + PHY_AUTO_NEG_SYM_PAUSE | \ + PHY_AUTO_NEG_100BT4 | \ + PHY_AUTO_NEG_100BTX_FD | \ + PHY_AUTO_NEG_100BTX | \ + PHY_AUTO_NEG_10BT_FD | \ + PHY_AUTO_NEG_10BT) + +static inline void hw_r_phy_ctrl(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET); +} + +static inline void hw_w_phy_ctrl(struct ksz_hw *hw, int phy, u16 data) +{ + writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET); +} + +static inline void hw_r_phy_link_stat(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_STATUS_OFFSET); +} + +static inline void hw_r_phy_auto_neg(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET); +} + +static inline void hw_w_phy_auto_neg(struct ksz_hw *hw, int phy, u16 data) +{ + writew(data, hw->io + phy + KS884X_PHY_AUTO_NEG_OFFSET); +} + +static inline void hw_r_phy_rem_cap(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_REMOTE_CAP_OFFSET); +} + +static inline void hw_r_phy_crossover(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_CTRL_OFFSET); +} + +static inline void hw_w_phy_crossover(struct ksz_hw *hw, int phy, u16 data) +{ + writew(data, hw->io + phy + KS884X_PHY_CTRL_OFFSET); +} + +static inline void hw_r_phy_polarity(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET); +} + +static inline void hw_w_phy_polarity(struct ksz_hw *hw, int phy, u16 data) +{ + writew(data, hw->io + phy + KS884X_PHY_PHY_CTRL_OFFSET); +} + +static inline void hw_r_phy_link_md(struct ksz_hw *hw, int phy, u16 *data) +{ + *data = readw(hw->io + phy + KS884X_PHY_LINK_MD_OFFSET); +} + +static inline void hw_w_phy_link_md(struct ksz_hw *hw, int phy, u16 data) +{ + writew(data, hw->io + phy + KS884X_PHY_LINK_MD_OFFSET); +} + +/** + * hw_r_phy - read data from PHY register + * @hw: The hardware instance. + * @port: Port to read. + * @reg: PHY register to read. + * @val: Buffer to store the read data. + * + * This routine reads data from the PHY register. + */ +static void hw_r_phy(struct ksz_hw *hw, int port, u16 reg, u16 *val) +{ + int phy; + + phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg; + *val = readw(hw->io + phy); +} + +/** + * port_w_phy - write data to PHY register + * @hw: The hardware instance. + * @port: Port to write. + * @reg: PHY register to write. + * @val: Word data to write. + * + * This routine writes data to the PHY register. + */ +static void hw_w_phy(struct ksz_hw *hw, int port, u16 reg, u16 val) +{ + int phy; + + phy = KS884X_PHY_1_CTRL_OFFSET + port * PHY_CTRL_INTERVAL + reg; + writew(val, hw->io + phy); +} + +/* + * EEPROM access functions + */ + +#define AT93C_CODE 0 +#define AT93C_WR_OFF 0x00 +#define AT93C_WR_ALL 0x10 +#define AT93C_ER_ALL 0x20 +#define AT93C_WR_ON 0x30 + +#define AT93C_WRITE 1 +#define AT93C_READ 2 +#define AT93C_ERASE 3 + +#define EEPROM_DELAY 4 + +static inline void drop_gpio(struct ksz_hw *hw, u8 gpio) +{ + u16 data; + + data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET); + data &= ~gpio; + writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET); +} + +static inline void raise_gpio(struct ksz_hw *hw, u8 gpio) +{ + u16 data; + + data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET); + data |= gpio; + writew(data, hw->io + KS884X_EEPROM_CTRL_OFFSET); +} + +static inline u8 state_gpio(struct ksz_hw *hw, u8 gpio) +{ + u16 data; + + data = readw(hw->io + KS884X_EEPROM_CTRL_OFFSET); + return (u8)(data & gpio); +} + +static void eeprom_clk(struct ksz_hw *hw) +{ + raise_gpio(hw, EEPROM_SERIAL_CLOCK); + udelay(EEPROM_DELAY); + drop_gpio(hw, EEPROM_SERIAL_CLOCK); + udelay(EEPROM_DELAY); +} + +static u16 spi_r(struct ksz_hw *hw) +{ + int i; + u16 temp = 0; + + for (i = 15; i >= 0; i--) { + raise_gpio(hw, EEPROM_SERIAL_CLOCK); + udelay(EEPROM_DELAY); + + temp |= (state_gpio(hw, EEPROM_DATA_IN)) ? 1 << i : 0; + + drop_gpio(hw, EEPROM_SERIAL_CLOCK); + udelay(EEPROM_DELAY); + } + return temp; +} + +static void spi_w(struct ksz_hw *hw, u16 data) +{ + int i; + + for (i = 15; i >= 0; i--) { + (data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) : + drop_gpio(hw, EEPROM_DATA_OUT); + eeprom_clk(hw); + } +} + +static void spi_reg(struct ksz_hw *hw, u8 data, u8 reg) +{ + int i; + + /* Initial start bit */ + raise_gpio(hw, EEPROM_DATA_OUT); + eeprom_clk(hw); + + /* AT93C operation */ + for (i = 1; i >= 0; i--) { + (data & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) : + drop_gpio(hw, EEPROM_DATA_OUT); + eeprom_clk(hw); + } + + /* Address location */ + for (i = 5; i >= 0; i--) { + (reg & (0x01 << i)) ? raise_gpio(hw, EEPROM_DATA_OUT) : + drop_gpio(hw, EEPROM_DATA_OUT); + eeprom_clk(hw); + } +} + +#define EEPROM_DATA_RESERVED 0 +#define EEPROM_DATA_MAC_ADDR_0 1 +#define EEPROM_DATA_MAC_ADDR_1 2 +#define EEPROM_DATA_MAC_ADDR_2 3 +#define EEPROM_DATA_SUBSYS_ID 4 +#define EEPROM_DATA_SUBSYS_VEN_ID 5 +#define EEPROM_DATA_PM_CAP 6 + +/* User defined EEPROM data */ +#define EEPROM_DATA_OTHER_MAC_ADDR 9 + +/** + * eeprom_read - read from AT93C46 EEPROM + * @hw: The hardware instance. + * @reg: The register offset. + * + * This function reads a word from the AT93C46 EEPROM. + * + * Return the data value. + */ +static u16 eeprom_read(struct ksz_hw *hw, u8 reg) +{ + u16 data; + + raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT); + + spi_reg(hw, AT93C_READ, reg); + data = spi_r(hw); + + drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT); + + return data; +} + +/** + * eeprom_write - write to AT93C46 EEPROM + * @hw: The hardware instance. + * @reg: The register offset. + * @data: The data value. + * + * This procedure writes a word to the AT93C46 EEPROM. + */ +static void eeprom_write(struct ksz_hw *hw, u8 reg, u16 data) +{ + int timeout; + + raise_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT); + + /* Enable write. */ + spi_reg(hw, AT93C_CODE, AT93C_WR_ON); + drop_gpio(hw, EEPROM_CHIP_SELECT); + udelay(1); + + /* Erase the register. */ + raise_gpio(hw, EEPROM_CHIP_SELECT); + spi_reg(hw, AT93C_ERASE, reg); + drop_gpio(hw, EEPROM_CHIP_SELECT); + udelay(1); + + /* Check operation complete. */ + raise_gpio(hw, EEPROM_CHIP_SELECT); + timeout = 8; + mdelay(2); + do { + mdelay(1); + } while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout); + drop_gpio(hw, EEPROM_CHIP_SELECT); + udelay(1); + + /* Write the register. */ + raise_gpio(hw, EEPROM_CHIP_SELECT); + spi_reg(hw, AT93C_WRITE, reg); + spi_w(hw, data); + drop_gpio(hw, EEPROM_CHIP_SELECT); + udelay(1); + + /* Check operation complete. */ + raise_gpio(hw, EEPROM_CHIP_SELECT); + timeout = 8; + mdelay(2); + do { + mdelay(1); + } while (!state_gpio(hw, EEPROM_DATA_IN) && --timeout); + drop_gpio(hw, EEPROM_CHIP_SELECT); + udelay(1); + + /* Disable write. */ + raise_gpio(hw, EEPROM_CHIP_SELECT); + spi_reg(hw, AT93C_CODE, AT93C_WR_OFF); + + drop_gpio(hw, EEPROM_ACCESS_ENABLE | EEPROM_CHIP_SELECT); +} + +/* + * Link detection routines + */ + +static u16 advertised_flow_ctrl(struct ksz_port *port, u16 ctrl) +{ + ctrl &= ~PORT_AUTO_NEG_SYM_PAUSE; + switch (port->flow_ctrl) { + case PHY_FLOW_CTRL: + ctrl |= PORT_AUTO_NEG_SYM_PAUSE; + break; + /* Not supported. */ + case PHY_TX_ONLY: + case PHY_RX_ONLY: + default: + break; + } + return ctrl; +} + +static void set_flow_ctrl(struct ksz_hw *hw, int rx, int tx) +{ + u32 rx_cfg; + u32 tx_cfg; + + rx_cfg = hw->rx_cfg; + tx_cfg = hw->tx_cfg; + if (rx) + hw->rx_cfg |= DMA_RX_FLOW_ENABLE; + else + hw->rx_cfg &= ~DMA_RX_FLOW_ENABLE; + if (tx) + hw->tx_cfg |= DMA_TX_FLOW_ENABLE; + else + hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE; + if (hw->enabled) { + if (rx_cfg != hw->rx_cfg) + writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); + if (tx_cfg != hw->tx_cfg) + writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL); + } +} + +static void determine_flow_ctrl(struct ksz_hw *hw, struct ksz_port *port, + u16 local, u16 remote) +{ + int rx; + int tx; + + if (hw->overrides & PAUSE_FLOW_CTRL) + return; + + rx = tx = 0; + if (port->force_link) + rx = tx = 1; + if (remote & PHY_AUTO_NEG_SYM_PAUSE) { + if (local & PHY_AUTO_NEG_SYM_PAUSE) { + rx = tx = 1; + } else if ((remote & PHY_AUTO_NEG_ASYM_PAUSE) && + (local & PHY_AUTO_NEG_PAUSE) == + PHY_AUTO_NEG_ASYM_PAUSE) { + tx = 1; + } + } else if (remote & PHY_AUTO_NEG_ASYM_PAUSE) { + if ((local & PHY_AUTO_NEG_PAUSE) == PHY_AUTO_NEG_PAUSE) + rx = 1; + } + if (!hw->ksz_switch) + set_flow_ctrl(hw, rx, tx); +} + +static inline void port_cfg_change(struct ksz_hw *hw, struct ksz_port *port, + struct ksz_port_info *info, u16 link_status) +{ + if ((hw->features & HALF_DUPLEX_SIGNAL_BUG) && + !(hw->overrides & PAUSE_FLOW_CTRL)) { + u32 cfg = hw->tx_cfg; + + /* Disable flow control in the half duplex mode. */ + if (1 == info->duplex) + hw->tx_cfg &= ~DMA_TX_FLOW_ENABLE; + if (hw->enabled && cfg != hw->tx_cfg) + writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL); + } +} + +/** + * port_get_link_speed - get current link status + * @port: The port instance. + * + * This routine reads PHY registers to determine the current link status of the + * switch ports. + */ +static void port_get_link_speed(struct ksz_port *port) +{ + uint interrupt; + struct ksz_port_info *info; + struct ksz_port_info *linked = NULL; + struct ksz_hw *hw = port->hw; + u16 data; + u16 status; + u8 local; + u8 remote; + int i; + int p; + int change = 0; + + interrupt = hw_block_intr(hw); + + for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) { + info = &hw->port_info[p]; + port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data); + port_r16(hw, p, KS884X_PORT_STATUS_OFFSET, &status); + + /* + * Link status is changing all the time even when there is no + * cable connection! + */ + remote = status & (PORT_AUTO_NEG_COMPLETE | + PORT_STATUS_LINK_GOOD); + local = (u8) data; + + /* No change to status. */ + if (local == info->advertised && remote == info->partner) + continue; + + info->advertised = local; + info->partner = remote; + if (status & PORT_STATUS_LINK_GOOD) { + + /* Remember the first linked port. */ + if (!linked) + linked = info; + + info->tx_rate = 10 * TX_RATE_UNIT; + if (status & PORT_STATUS_SPEED_100MBIT) + info->tx_rate = 100 * TX_RATE_UNIT; + + info->duplex = 1; + if (status & PORT_STATUS_FULL_DUPLEX) + info->duplex = 2; + + if (media_connected != info->state) { + hw_r_phy(hw, p, KS884X_PHY_AUTO_NEG_OFFSET, + &data); + hw_r_phy(hw, p, KS884X_PHY_REMOTE_CAP_OFFSET, + &status); + determine_flow_ctrl(hw, port, data, status); + if (hw->ksz_switch) { + port_cfg_back_pressure(hw, p, + (1 == info->duplex)); + } + change |= 1 << i; + port_cfg_change(hw, port, info, status); + } + info->state = media_connected; + } else { + if (media_disconnected != info->state) { + change |= 1 << i; + + /* Indicate the link just goes down. */ + hw->port_mib[p].link_down = 1; + } + info->state = media_disconnected; + } + hw->port_mib[p].state = (u8) info->state; + } + + if (linked && media_disconnected == port->linked->state) + port->linked = linked; + + hw_restore_intr(hw, interrupt); +} + +#define PHY_RESET_TIMEOUT 10 + +/** + * port_set_link_speed - set port speed + * @port: The port instance. + * + * This routine sets the link speed of the switch ports. + */ +static void port_set_link_speed(struct ksz_port *port) +{ + struct ksz_port_info *info; + struct ksz_hw *hw = port->hw; + u16 data; + u16 cfg; + u8 status; + int i; + int p; + + for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) { + info = &hw->port_info[p]; + + port_r16(hw, p, KS884X_PORT_CTRL_4_OFFSET, &data); + port_r8(hw, p, KS884X_PORT_STATUS_OFFSET, &status); + + cfg = 0; + if (status & PORT_STATUS_LINK_GOOD) + cfg = data; + + data |= PORT_AUTO_NEG_ENABLE; + data = advertised_flow_ctrl(port, data); + + data |= PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_100BTX | + PORT_AUTO_NEG_10BT_FD | PORT_AUTO_NEG_10BT; + + /* Check if manual configuration is specified by the user. */ + if (port->speed || port->duplex) { + if (10 == port->speed) + data &= ~(PORT_AUTO_NEG_100BTX_FD | + PORT_AUTO_NEG_100BTX); + else if (100 == port->speed) + data &= ~(PORT_AUTO_NEG_10BT_FD | + PORT_AUTO_NEG_10BT); + if (1 == port->duplex) + data &= ~(PORT_AUTO_NEG_100BTX_FD | + PORT_AUTO_NEG_10BT_FD); + else if (2 == port->duplex) + data &= ~(PORT_AUTO_NEG_100BTX | + PORT_AUTO_NEG_10BT); + } + if (data != cfg) { + data |= PORT_AUTO_NEG_RESTART; + port_w16(hw, p, KS884X_PORT_CTRL_4_OFFSET, data); + } + } +} + +/** + * port_force_link_speed - force port speed + * @port: The port instance. + * + * This routine forces the link speed of the switch ports. + */ +static void port_force_link_speed(struct ksz_port *port) +{ + struct ksz_hw *hw = port->hw; + u16 data; + int i; + int phy; + int p; + + for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) { + phy = KS884X_PHY_1_CTRL_OFFSET + p * PHY_CTRL_INTERVAL; + hw_r_phy_ctrl(hw, phy, &data); + + data &= ~PHY_AUTO_NEG_ENABLE; + + if (10 == port->speed) + data &= ~PHY_SPEED_100MBIT; + else if (100 == port->speed) + data |= PHY_SPEED_100MBIT; + if (1 == port->duplex) + data &= ~PHY_FULL_DUPLEX; + else if (2 == port->duplex) + data |= PHY_FULL_DUPLEX; + hw_w_phy_ctrl(hw, phy, data); + } +} + +static void port_set_power_saving(struct ksz_port *port, int enable) +{ + struct ksz_hw *hw = port->hw; + int i; + int p; + + for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) + port_cfg(hw, p, + KS884X_PORT_CTRL_4_OFFSET, PORT_POWER_DOWN, enable); +} + +/* + * KSZ8841 power management functions + */ + +/** + * hw_chk_wol_pme_status - check PMEN pin + * @hw: The hardware instance. + * + * This function is used to check PMEN pin is asserted. + * + * Return 1 if PMEN pin is asserted; otherwise, 0. + */ +static int hw_chk_wol_pme_status(struct ksz_hw *hw) +{ + struct dev_info *hw_priv = container_of(hw, struct dev_info, hw); + struct pci_dev *pdev = hw_priv->pdev; + u16 data; + + if (!pdev->pm_cap) + return 0; + pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data); + return (data & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS; +} + +/** + * hw_clr_wol_pme_status - clear PMEN pin + * @hw: The hardware instance. + * + * This routine is used to clear PME_Status to deassert PMEN pin. + */ +static void hw_clr_wol_pme_status(struct ksz_hw *hw) +{ + struct dev_info *hw_priv = container_of(hw, struct dev_info, hw); + struct pci_dev *pdev = hw_priv->pdev; + u16 data; + + if (!pdev->pm_cap) + return; + + /* Clear PME_Status to deassert PMEN pin. */ + pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data); + data |= PCI_PM_CTRL_PME_STATUS; + pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data); +} + +/** + * hw_cfg_wol_pme - enable or disable Wake-on-LAN + * @hw: The hardware instance. + * @set: The flag indicating whether to enable or disable. + * + * This routine is used to enable or disable Wake-on-LAN. + */ +static void hw_cfg_wol_pme(struct ksz_hw *hw, int set) +{ + struct dev_info *hw_priv = container_of(hw, struct dev_info, hw); + struct pci_dev *pdev = hw_priv->pdev; + u16 data; + + if (!pdev->pm_cap) + return; + pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &data); + data &= ~PCI_PM_CTRL_STATE_MASK; + if (set) + data |= PCI_PM_CTRL_PME_ENABLE | PCI_D3hot; + else + data &= ~PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, data); +} + +/** + * hw_cfg_wol - configure Wake-on-LAN features + * @hw: The hardware instance. + * @frame: The pattern frame bit. + * @set: The flag indicating whether to enable or disable. + * + * This routine is used to enable or disable certain Wake-on-LAN features. + */ +static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set) +{ + u16 data; + + data = readw(hw->io + KS8841_WOL_CTRL_OFFSET); + if (set) + data |= frame; + else + data &= ~frame; + writew(data, hw->io + KS8841_WOL_CTRL_OFFSET); +} + +/** + * hw_set_wol_frame - program Wake-on-LAN pattern + * @hw: The hardware instance. + * @i: The frame index. + * @mask_size: The size of the mask. + * @mask: Mask to ignore certain bytes in the pattern. + * @frame_size: The size of the frame. + * @pattern: The frame data. + * + * This routine is used to program Wake-on-LAN pattern. + */ +static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, + const u8 *mask, uint frame_size, const u8 *pattern) +{ + int bits; + int from; + int len; + int to; + u32 crc; + u8 data[64]; + u8 val = 0; + + if (frame_size > mask_size * 8) + frame_size = mask_size * 8; + if (frame_size > 64) + frame_size = 64; + + i *= 0x10; + writel(0, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i); + writel(0, hw->io + KS8841_WOL_FRAME_BYTE2_OFFSET + i); + + bits = len = from = to = 0; + do { + if (bits) { + if ((val & 1)) + data[to++] = pattern[from]; + val >>= 1; + ++from; + --bits; + } else { + val = mask[len]; + writeb(val, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i + + len); + ++len; + if (val) + bits = 8; + else + from += 8; + } + } while (from < (int) frame_size); + if (val) { + bits = mask[len - 1]; + val <<= (from % 8); + bits &= ~val; + writeb(bits, hw->io + KS8841_WOL_FRAME_BYTE0_OFFSET + i + len - + 1); + } + crc = ether_crc(to, data); + writel(crc, hw->io + KS8841_WOL_FRAME_CRC_OFFSET + i); +} + +/** + * hw_add_wol_arp - add ARP pattern + * @hw: The hardware instance. + * @ip_addr: The IPv4 address assigned to the device. + * + * This routine is used to add ARP pattern for waking up the host. + */ +static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr) +{ + static const u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 }; + u8 pattern[42] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x06, + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + memcpy(&pattern[38], ip_addr, 4); + hw_set_wol_frame(hw, 3, 6, mask, 42, pattern); +} + +/** + * hw_add_wol_bcast - add broadcast pattern + * @hw: The hardware instance. + * + * This routine is used to add broadcast pattern for waking up the host. + */ +static void hw_add_wol_bcast(struct ksz_hw *hw) +{ + static const u8 mask[] = { 0x3F }; + static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern); +} + +/** + * hw_add_wol_mcast - add multicast pattern + * @hw: The hardware instance. + * + * This routine is used to add multicast pattern for waking up the host. + * + * It is assumed the multicast packet is the ICMPv6 neighbor solicitation used + * by IPv6 ping command. Note that multicast packets are filtred through the + * multicast hash table, so not all multicast packets can wake up the host. + */ +static void hw_add_wol_mcast(struct ksz_hw *hw) +{ + static const u8 mask[] = { 0x3F }; + u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 }; + + memcpy(&pattern[3], &hw->override_addr[3], 3); + hw_set_wol_frame(hw, 1, 1, mask, 6, pattern); +} + +/** + * hw_add_wol_ucast - add unicast pattern + * @hw: The hardware instance. + * + * This routine is used to add unicast pattern to wakeup the host. + * + * It is assumed the unicast packet is directed to the device, as the hardware + * can only receive them in normal case. + */ +static void hw_add_wol_ucast(struct ksz_hw *hw) +{ + static const u8 mask[] = { 0x3F }; + + hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr); +} + +/** + * hw_enable_wol - enable Wake-on-LAN + * @hw: The hardware instance. + * @wol_enable: The Wake-on-LAN settings. + * @net_addr: The IPv4 address assigned to the device. + * + * This routine is used to enable Wake-on-LAN depending on driver settings. + */ +static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr) +{ + hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC)); + hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST)); + hw_add_wol_ucast(hw); + hw_cfg_wol(hw, KS8841_WOL_FRAME1_ENABLE, (wol_enable & WAKE_MCAST)); + hw_add_wol_mcast(hw); + hw_cfg_wol(hw, KS8841_WOL_FRAME2_ENABLE, (wol_enable & WAKE_BCAST)); + hw_cfg_wol(hw, KS8841_WOL_FRAME3_ENABLE, (wol_enable & WAKE_ARP)); + hw_add_wol_arp(hw, net_addr); +} + +/** + * hw_init - check driver is correct for the hardware + * @hw: The hardware instance. + * + * This function checks the hardware is correct for this driver and sets the + * hardware up for proper initialization. + * + * Return number of ports or 0 if not right. + */ +static int hw_init(struct ksz_hw *hw) +{ + int rc = 0; + u16 data; + u16 revision; + + /* Set bus speed to 125MHz. */ + writew(BUS_SPEED_125_MHZ, hw->io + KS884X_BUS_CTRL_OFFSET); + + /* Check KSZ884x chip ID. */ + data = readw(hw->io + KS884X_CHIP_ID_OFFSET); + + revision = (data & KS884X_REVISION_MASK) >> KS884X_REVISION_SHIFT; + data &= KS884X_CHIP_ID_MASK_41; + if (REG_CHIP_ID_41 == data) + rc = 1; + else if (REG_CHIP_ID_42 == data) + rc = 2; + else + return 0; + + /* Setup hardware features or bug workarounds. */ + if (revision <= 1) { + hw->features |= SMALL_PACKET_TX_BUG; + if (1 == rc) + hw->features |= HALF_DUPLEX_SIGNAL_BUG; + } + return rc; +} + +/** + * hw_reset - reset the hardware + * @hw: The hardware instance. + * + * This routine resets the hardware. + */ +static void hw_reset(struct ksz_hw *hw) +{ + writew(GLOBAL_SOFTWARE_RESET, hw->io + KS884X_GLOBAL_CTRL_OFFSET); + + /* Wait for device to reset. */ + mdelay(10); + + /* Write 0 to clear device reset. */ + writew(0, hw->io + KS884X_GLOBAL_CTRL_OFFSET); +} + +/** + * hw_setup - setup the hardware + * @hw: The hardware instance. + * + * This routine setup the hardware for proper operation. + */ +static void hw_setup(struct ksz_hw *hw) +{ +#if SET_DEFAULT_LED + u16 data; + + /* Change default LED mode. */ + data = readw(hw->io + KS8842_SWITCH_CTRL_5_OFFSET); + data &= ~LED_MODE; + data |= SET_DEFAULT_LED; + writew(data, hw->io + KS8842_SWITCH_CTRL_5_OFFSET); +#endif + + /* Setup transmit control. */ + hw->tx_cfg = (DMA_TX_PAD_ENABLE | DMA_TX_CRC_ENABLE | + (DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_TX_ENABLE); + + /* Setup receive control. */ + hw->rx_cfg = (DMA_RX_BROADCAST | DMA_RX_UNICAST | + (DMA_BURST_DEFAULT << DMA_BURST_SHIFT) | DMA_RX_ENABLE); + hw->rx_cfg |= KS884X_DMA_RX_MULTICAST; + + /* Hardware cannot handle UDP packet in IP fragments. */ + hw->rx_cfg |= (DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP); + + if (hw->all_multi) + hw->rx_cfg |= DMA_RX_ALL_MULTICAST; + if (hw->promiscuous) + hw->rx_cfg |= DMA_RX_PROMISCUOUS; +} + +/** + * hw_setup_intr - setup interrupt mask + * @hw: The hardware instance. + * + * This routine setup the interrupt mask for proper operation. + */ +static void hw_setup_intr(struct ksz_hw *hw) +{ + hw->intr_mask = KS884X_INT_MASK | KS884X_INT_RX_OVERRUN; +} + +static void ksz_check_desc_num(struct ksz_desc_info *info) +{ +#define MIN_DESC_SHIFT 2 + + int alloc = info->alloc; + int shift; + + shift = 0; + while (!(alloc & 1)) { + shift++; + alloc >>= 1; + } + if (alloc != 1 || shift < MIN_DESC_SHIFT) { + pr_alert("Hardware descriptor numbers not right!\n"); + while (alloc) { + shift++; + alloc >>= 1; + } + if (shift < MIN_DESC_SHIFT) + shift = MIN_DESC_SHIFT; + alloc = 1 << shift; + info->alloc = alloc; + } + info->mask = info->alloc - 1; +} + +static void hw_init_desc(struct ksz_desc_info *desc_info, int transmit) +{ + int i; + u32 phys = desc_info->ring_phys; + struct ksz_hw_desc *desc = desc_info->ring_virt; + struct ksz_desc *cur = desc_info->ring; + struct ksz_desc *previous = NULL; + + for (i = 0; i < desc_info->alloc; i++) { + cur->phw = desc++; + phys += desc_info->size; + previous = cur++; + previous->phw->next = cpu_to_le32(phys); + } + previous->phw->next = cpu_to_le32(desc_info->ring_phys); + previous->sw.buf.rx.end_of_ring = 1; + previous->phw->buf.data = cpu_to_le32(previous->sw.buf.data); + + desc_info->avail = desc_info->alloc; + desc_info->last = desc_info->next = 0; + + desc_info->cur = desc_info->ring; +} + +/** + * hw_set_desc_base - set descriptor base addresses + * @hw: The hardware instance. + * @tx_addr: The transmit descriptor base. + * @rx_addr: The receive descriptor base. + * + * This routine programs the descriptor base addresses after reset. + */ +static void hw_set_desc_base(struct ksz_hw *hw, u32 tx_addr, u32 rx_addr) +{ + /* Set base address of Tx/Rx descriptors. */ + writel(tx_addr, hw->io + KS_DMA_TX_ADDR); + writel(rx_addr, hw->io + KS_DMA_RX_ADDR); +} + +static void hw_reset_pkts(struct ksz_desc_info *info) +{ + info->cur = info->ring; + info->avail = info->alloc; + info->last = info->next = 0; +} + +static inline void hw_resume_rx(struct ksz_hw *hw) +{ + writel(DMA_START, hw->io + KS_DMA_RX_START); +} + +/** + * hw_start_rx - start receiving + * @hw: The hardware instance. + * + * This routine starts the receive function of the hardware. + */ +static void hw_start_rx(struct ksz_hw *hw) +{ + writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); + + /* Notify when the receive stops. */ + hw->intr_mask |= KS884X_INT_RX_STOPPED; + + writel(DMA_START, hw->io + KS_DMA_RX_START); + hw_ack_intr(hw, KS884X_INT_RX_STOPPED); + hw->rx_stop++; + + /* Variable overflows. */ + if (0 == hw->rx_stop) + hw->rx_stop = 2; +} + +/* + * hw_stop_rx - stop receiving + * @hw: The hardware instance. + * + * This routine stops the receive function of the hardware. + */ +static void hw_stop_rx(struct ksz_hw *hw) +{ + hw->rx_stop = 0; + hw_turn_off_intr(hw, KS884X_INT_RX_STOPPED); + writel((hw->rx_cfg & ~DMA_RX_ENABLE), hw->io + KS_DMA_RX_CTRL); +} + +/** + * hw_start_tx - start transmitting + * @hw: The hardware instance. + * + * This routine starts the transmit function of the hardware. + */ +static void hw_start_tx(struct ksz_hw *hw) +{ + writel(hw->tx_cfg, hw->io + KS_DMA_TX_CTRL); +} + +/** + * hw_stop_tx - stop transmitting + * @hw: The hardware instance. + * + * This routine stops the transmit function of the hardware. + */ +static void hw_stop_tx(struct ksz_hw *hw) +{ + writel((hw->tx_cfg & ~DMA_TX_ENABLE), hw->io + KS_DMA_TX_CTRL); +} + +/** + * hw_disable - disable hardware + * @hw: The hardware instance. + * + * This routine disables the hardware. + */ +static void hw_disable(struct ksz_hw *hw) +{ + hw_stop_rx(hw); + hw_stop_tx(hw); + hw->enabled = 0; +} + +/** + * hw_enable - enable hardware + * @hw: The hardware instance. + * + * This routine enables the hardware. + */ +static void hw_enable(struct ksz_hw *hw) +{ + hw_start_tx(hw); + hw_start_rx(hw); + hw->enabled = 1; +} + +/** + * hw_alloc_pkt - allocate enough descriptors for transmission + * @hw: The hardware instance. + * @length: The length of the packet. + * @physical: Number of descriptors required. + * + * This function allocates descriptors for transmission. + * + * Return 0 if not successful; 1 for buffer copy; or number of descriptors. + */ +static int hw_alloc_pkt(struct ksz_hw *hw, int length, int physical) +{ + /* Always leave one descriptor free. */ + if (hw->tx_desc_info.avail <= 1) + return 0; + + /* Allocate a descriptor for transmission and mark it current. */ + get_tx_pkt(&hw->tx_desc_info, &hw->tx_desc_info.cur); + hw->tx_desc_info.cur->sw.buf.tx.first_seg = 1; + + /* Keep track of number of transmit descriptors used so far. */ + ++hw->tx_int_cnt; + hw->tx_size += length; + + /* Cannot hold on too much data. */ + if (hw->tx_size >= MAX_TX_HELD_SIZE) + hw->tx_int_cnt = hw->tx_int_mask + 1; + + if (physical > hw->tx_desc_info.avail) + return 1; + + return hw->tx_desc_info.avail; +} + +/** + * hw_send_pkt - mark packet for transmission + * @hw: The hardware instance. + * + * This routine marks the packet for transmission in PCI version. + */ +static void hw_send_pkt(struct ksz_hw *hw) +{ + struct ksz_desc *cur = hw->tx_desc_info.cur; + + cur->sw.buf.tx.last_seg = 1; + + /* Interrupt only after specified number of descriptors used. */ + if (hw->tx_int_cnt > hw->tx_int_mask) { + cur->sw.buf.tx.intr = 1; + hw->tx_int_cnt = 0; + hw->tx_size = 0; + } + + /* KSZ8842 supports port directed transmission. */ + cur->sw.buf.tx.dest_port = hw->dst_ports; + + release_desc(cur); + + writel(0, hw->io + KS_DMA_TX_START); +} + +static int empty_addr(u8 *addr) +{ + u32 *addr1 = (u32 *) addr; + u16 *addr2 = (u16 *) &addr[4]; + + return 0 == *addr1 && 0 == *addr2; +} + +/** + * hw_set_addr - set MAC address + * @hw: The hardware instance. + * + * This routine programs the MAC address of the hardware when the address is + * overrided. + */ +static void hw_set_addr(struct ksz_hw *hw) +{ + int i; + + for (i = 0; i < MAC_ADDR_LEN; i++) + writeb(hw->override_addr[MAC_ADDR_ORDER(i)], + hw->io + KS884X_ADDR_0_OFFSET + i); + + sw_set_addr(hw, hw->override_addr); +} + +/** + * hw_read_addr - read MAC address + * @hw: The hardware instance. + * + * This routine retrieves the MAC address of the hardware. + */ +static void hw_read_addr(struct ksz_hw *hw) +{ + int i; + + for (i = 0; i < MAC_ADDR_LEN; i++) + hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io + + KS884X_ADDR_0_OFFSET + i); + + if (!hw->mac_override) { + memcpy(hw->override_addr, hw->perm_addr, MAC_ADDR_LEN); + if (empty_addr(hw->override_addr)) { + memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, + MAC_ADDR_LEN); + memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS, + MAC_ADDR_LEN); + hw->override_addr[5] += hw->id; + hw_set_addr(hw); + } + } +} + +static void hw_ena_add_addr(struct ksz_hw *hw, int index, u8 *mac_addr) +{ + int i; + u32 mac_addr_lo; + u32 mac_addr_hi; + + mac_addr_hi = 0; + for (i = 0; i < 2; i++) { + mac_addr_hi <<= 8; + mac_addr_hi |= mac_addr[i]; + } + mac_addr_hi |= ADD_ADDR_ENABLE; + mac_addr_lo = 0; + for (i = 2; i < 6; i++) { + mac_addr_lo <<= 8; + mac_addr_lo |= mac_addr[i]; + } + index *= ADD_ADDR_INCR; + + writel(mac_addr_lo, hw->io + index + KS_ADD_ADDR_0_LO); + writel(mac_addr_hi, hw->io + index + KS_ADD_ADDR_0_HI); +} + +static void hw_set_add_addr(struct ksz_hw *hw) +{ + int i; + + for (i = 0; i < ADDITIONAL_ENTRIES; i++) { + if (empty_addr(hw->address[i])) + writel(0, hw->io + ADD_ADDR_INCR * i + + KS_ADD_ADDR_0_HI); + else + hw_ena_add_addr(hw, i, hw->address[i]); + } +} + +static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr) +{ + int i; + int j = ADDITIONAL_ENTRIES; + + if (!memcmp(hw->override_addr, mac_addr, MAC_ADDR_LEN)) + return 0; + for (i = 0; i < hw->addr_list_size; i++) { + if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) + return 0; + if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i])) + j = i; + } + if (j < ADDITIONAL_ENTRIES) { + memcpy(hw->address[j], mac_addr, MAC_ADDR_LEN); + hw_ena_add_addr(hw, j, hw->address[j]); + return 0; + } + return -1; +} + +static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr) +{ + int i; + + for (i = 0; i < hw->addr_list_size; i++) { + if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) { + memset(hw->address[i], 0, MAC_ADDR_LEN); + writel(0, hw->io + ADD_ADDR_INCR * i + + KS_ADD_ADDR_0_HI); + return 0; + } + } + return -1; +} + +/** + * hw_clr_multicast - clear multicast addresses + * @hw: The hardware instance. + * + * This routine removes all multicast addresses set in the hardware. + */ +static void hw_clr_multicast(struct ksz_hw *hw) +{ + int i; + + for (i = 0; i < HW_MULTICAST_SIZE; i++) { + hw->multi_bits[i] = 0; + + writeb(0, hw->io + KS884X_MULTICAST_0_OFFSET + i); + } +} + +/** + * hw_set_grp_addr - set multicast addresses + * @hw: The hardware instance. + * + * This routine programs multicast addresses for the hardware to accept those + * addresses. + */ +static void hw_set_grp_addr(struct ksz_hw *hw) +{ + int i; + int index; + int position; + int value; + + memset(hw->multi_bits, 0, sizeof(u8) * HW_MULTICAST_SIZE); + + for (i = 0; i < hw->multi_list_size; i++) { + position = (ether_crc(6, hw->multi_list[i]) >> 26) & 0x3f; + index = position >> 3; + value = 1 << (position & 7); + hw->multi_bits[index] |= (u8) value; + } + + for (i = 0; i < HW_MULTICAST_SIZE; i++) + writeb(hw->multi_bits[i], hw->io + KS884X_MULTICAST_0_OFFSET + + i); +} + +/** + * hw_set_multicast - enable or disable all multicast receiving + * @hw: The hardware instance. + * @multicast: To turn on or off the all multicast feature. + * + * This routine enables/disables the hardware to accept all multicast packets. + */ +static void hw_set_multicast(struct ksz_hw *hw, u8 multicast) +{ + /* Stop receiving for reconfiguration. */ + hw_stop_rx(hw); + + if (multicast) + hw->rx_cfg |= DMA_RX_ALL_MULTICAST; + else + hw->rx_cfg &= ~DMA_RX_ALL_MULTICAST; + + if (hw->enabled) + hw_start_rx(hw); +} + +/** + * hw_set_promiscuous - enable or disable promiscuous receiving + * @hw: The hardware instance. + * @prom: To turn on or off the promiscuous feature. + * + * This routine enables/disables the hardware to accept all packets. + */ +static void hw_set_promiscuous(struct ksz_hw *hw, u8 prom) +{ + /* Stop receiving for reconfiguration. */ + hw_stop_rx(hw); + + if (prom) + hw->rx_cfg |= DMA_RX_PROMISCUOUS; + else + hw->rx_cfg &= ~DMA_RX_PROMISCUOUS; + + if (hw->enabled) + hw_start_rx(hw); +} + +/** + * sw_enable - enable the switch + * @hw: The hardware instance. + * @enable: The flag to enable or disable the switch + * + * This routine is used to enable/disable the switch in KSZ8842. + */ +static void sw_enable(struct ksz_hw *hw, int enable) +{ + int port; + + for (port = 0; port < SWITCH_PORT_NUM; port++) { + if (hw->dev_count > 1) { + /* Set port-base vlan membership with host port. */ + sw_cfg_port_base_vlan(hw, port, + HOST_MASK | (1 << port)); + port_set_stp_state(hw, port, STP_STATE_DISABLED); + } else { + sw_cfg_port_base_vlan(hw, port, PORT_MASK); + port_set_stp_state(hw, port, STP_STATE_FORWARDING); + } + } + if (hw->dev_count > 1) + port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE); + else + port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_FORWARDING); + + if (enable) + enable = KS8842_START; + writew(enable, hw->io + KS884X_CHIP_ID_OFFSET); +} + +/** + * sw_setup - setup the switch + * @hw: The hardware instance. + * + * This routine setup the hardware switch engine for default operation. + */ +static void sw_setup(struct ksz_hw *hw) +{ + int port; + + sw_set_global_ctrl(hw); + + /* Enable switch broadcast storm protection at 10% percent rate. */ + sw_init_broad_storm(hw); + hw_cfg_broad_storm(hw, BROADCAST_STORM_PROTECTION_RATE); + for (port = 0; port < SWITCH_PORT_NUM; port++) + sw_ena_broad_storm(hw, port); + + sw_init_prio(hw); + + sw_init_mirror(hw); + + sw_init_prio_rate(hw); + + sw_init_vlan(hw); + + if (hw->features & STP_SUPPORT) + sw_init_stp(hw); + if (!sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_TX_FLOW_CTRL | SWITCH_RX_FLOW_CTRL)) + hw->overrides |= PAUSE_FLOW_CTRL; + sw_enable(hw, 1); +} + +/** + * ksz_start_timer - start kernel timer + * @info: Kernel timer information. + * @time: The time tick. + * + * This routine starts the kernel timer after the specified time tick. + */ +static void ksz_start_timer(struct ksz_timer_info *info, int time) +{ + info->cnt = 0; + info->timer.expires = jiffies + time; + add_timer(&info->timer); + + /* infinity */ + info->max = -1; +} + +/** + * ksz_stop_timer - stop kernel timer + * @info: Kernel timer information. + * + * This routine stops the kernel timer. + */ +static void ksz_stop_timer(struct ksz_timer_info *info) +{ + if (info->max) { + info->max = 0; + del_timer_sync(&info->timer); + } +} + +static void ksz_init_timer(struct ksz_timer_info *info, int period, + void (*function)(unsigned long), void *data) +{ + info->max = 0; + info->period = period; + init_timer(&info->timer); + info->timer.function = function; + info->timer.data = (unsigned long) data; +} + +static void ksz_update_timer(struct ksz_timer_info *info) +{ + ++info->cnt; + if (info->max > 0) { + if (info->cnt < info->max) { + info->timer.expires = jiffies + info->period; + add_timer(&info->timer); + } else + info->max = 0; + } else if (info->max < 0) { + info->timer.expires = jiffies + info->period; + add_timer(&info->timer); + } +} + +/** + * ksz_alloc_soft_desc - allocate software descriptors + * @desc_info: Descriptor information structure. + * @transmit: Indication that descriptors are for transmit. + * + * This local function allocates software descriptors for manipulation in + * memory. + * + * Return 0 if successful. + */ +static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) +{ + desc_info->ring = kmalloc(sizeof(struct ksz_desc) * desc_info->alloc, + GFP_KERNEL); + if (!desc_info->ring) + return 1; + memset((void *) desc_info->ring, 0, + sizeof(struct ksz_desc) * desc_info->alloc); + hw_init_desc(desc_info, transmit); + return 0; +} + +/** + * ksz_alloc_desc - allocate hardware descriptors + * @adapter: Adapter information structure. + * + * This local function allocates hardware descriptors for receiving and + * transmitting. + * + * Return 0 if successful. + */ +static int ksz_alloc_desc(struct dev_info *adapter) +{ + struct ksz_hw *hw = &adapter->hw; + int offset; + + /* Allocate memory for RX & TX descriptors. */ + adapter->desc_pool.alloc_size = + hw->rx_desc_info.size * hw->rx_desc_info.alloc + + hw->tx_desc_info.size * hw->tx_desc_info.alloc + + DESC_ALIGNMENT; + + adapter->desc_pool.alloc_virt = + pci_alloc_consistent( + adapter->pdev, adapter->desc_pool.alloc_size, + &adapter->desc_pool.dma_addr); + if (adapter->desc_pool.alloc_virt == NULL) { + adapter->desc_pool.alloc_size = 0; + return 1; + } + memset(adapter->desc_pool.alloc_virt, 0, adapter->desc_pool.alloc_size); + + /* Align to the next cache line boundary. */ + offset = (((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT) ? + (DESC_ALIGNMENT - + ((ulong) adapter->desc_pool.alloc_virt % DESC_ALIGNMENT)) : 0); + adapter->desc_pool.virt = adapter->desc_pool.alloc_virt + offset; + adapter->desc_pool.phys = adapter->desc_pool.dma_addr + offset; + + /* Allocate receive/transmit descriptors. */ + hw->rx_desc_info.ring_virt = (struct ksz_hw_desc *) + adapter->desc_pool.virt; + hw->rx_desc_info.ring_phys = adapter->desc_pool.phys; + offset = hw->rx_desc_info.alloc * hw->rx_desc_info.size; + hw->tx_desc_info.ring_virt = (struct ksz_hw_desc *) + (adapter->desc_pool.virt + offset); + hw->tx_desc_info.ring_phys = adapter->desc_pool.phys + offset; + + if (ksz_alloc_soft_desc(&hw->rx_desc_info, 0)) + return 1; + if (ksz_alloc_soft_desc(&hw->tx_desc_info, 1)) + return 1; + + return 0; +} + +/** + * free_dma_buf - release DMA buffer resources + * @adapter: Adapter information structure. + * + * This routine is just a helper function to release the DMA buffer resources. + */ +static void free_dma_buf(struct dev_info *adapter, struct ksz_dma_buf *dma_buf, + int direction) +{ + pci_unmap_single(adapter->pdev, dma_buf->dma, dma_buf->len, direction); + dev_kfree_skb(dma_buf->skb); + dma_buf->skb = NULL; + dma_buf->dma = 0; +} + +/** + * ksz_init_rx_buffers - initialize receive descriptors + * @adapter: Adapter information structure. + * + * This routine initializes DMA buffers for receiving. + */ +static void ksz_init_rx_buffers(struct dev_info *adapter) +{ + int i; + struct ksz_desc *desc; + struct ksz_dma_buf *dma_buf; + struct ksz_hw *hw = &adapter->hw; + struct ksz_desc_info *info = &hw->rx_desc_info; + + for (i = 0; i < hw->rx_desc_info.alloc; i++) { + get_rx_pkt(info, &desc); + + dma_buf = DMA_BUFFER(desc); + if (dma_buf->skb && dma_buf->len != adapter->mtu) + free_dma_buf(adapter, dma_buf, PCI_DMA_FROMDEVICE); + dma_buf->len = adapter->mtu; + if (!dma_buf->skb) + dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC); + if (dma_buf->skb && !dma_buf->dma) { + dma_buf->skb->dev = adapter->dev; + dma_buf->dma = pci_map_single( + adapter->pdev, + skb_tail_pointer(dma_buf->skb), + dma_buf->len, + PCI_DMA_FROMDEVICE); + } + + /* Set descriptor. */ + set_rx_buf(desc, dma_buf->dma); + set_rx_len(desc, dma_buf->len); + release_desc(desc); + } +} + +/** + * ksz_alloc_mem - allocate memory for hardware descriptors + * @adapter: Adapter information structure. + * + * This function allocates memory for use by hardware descriptors for receiving + * and transmitting. + * + * Return 0 if successful. + */ +static int ksz_alloc_mem(struct dev_info *adapter) +{ + struct ksz_hw *hw = &adapter->hw; + + /* Determine the number of receive and transmit descriptors. */ + hw->rx_desc_info.alloc = NUM_OF_RX_DESC; + hw->tx_desc_info.alloc = NUM_OF_TX_DESC; + + /* Determine how many descriptors to skip transmit interrupt. */ + hw->tx_int_cnt = 0; + hw->tx_int_mask = NUM_OF_TX_DESC / 4; + if (hw->tx_int_mask > 8) + hw->tx_int_mask = 8; + while (hw->tx_int_mask) { + hw->tx_int_cnt++; + hw->tx_int_mask >>= 1; + } + if (hw->tx_int_cnt) { + hw->tx_int_mask = (1 << (hw->tx_int_cnt - 1)) - 1; + hw->tx_int_cnt = 0; + } + + /* Determine the descriptor size. */ + hw->rx_desc_info.size = + (((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) / + DESC_ALIGNMENT) * DESC_ALIGNMENT); + hw->tx_desc_info.size = + (((sizeof(struct ksz_hw_desc) + DESC_ALIGNMENT - 1) / + DESC_ALIGNMENT) * DESC_ALIGNMENT); + if (hw->rx_desc_info.size != sizeof(struct ksz_hw_desc)) + pr_alert("Hardware descriptor size not right!\n"); + ksz_check_desc_num(&hw->rx_desc_info); + ksz_check_desc_num(&hw->tx_desc_info); + + /* Allocate descriptors. */ + if (ksz_alloc_desc(adapter)) + return 1; + + return 0; +} + +/** + * ksz_free_desc - free software and hardware descriptors + * @adapter: Adapter information structure. + * + * This local routine frees the software and hardware descriptors allocated by + * ksz_alloc_desc(). + */ +static void ksz_free_desc(struct dev_info *adapter) +{ + struct ksz_hw *hw = &adapter->hw; + + /* Reset descriptor. */ + hw->rx_desc_info.ring_virt = NULL; + hw->tx_desc_info.ring_virt = NULL; + hw->rx_desc_info.ring_phys = 0; + hw->tx_desc_info.ring_phys = 0; + + /* Free memory. */ + if (adapter->desc_pool.alloc_virt) + pci_free_consistent( + adapter->pdev, + adapter->desc_pool.alloc_size, + adapter->desc_pool.alloc_virt, + adapter->desc_pool.dma_addr); + + /* Reset resource pool. */ + adapter->desc_pool.alloc_size = 0; + adapter->desc_pool.alloc_virt = NULL; + + kfree(hw->rx_desc_info.ring); + hw->rx_desc_info.ring = NULL; + kfree(hw->tx_desc_info.ring); + hw->tx_desc_info.ring = NULL; +} + +/** + * ksz_free_buffers - free buffers used in the descriptors + * @adapter: Adapter information structure. + * @desc_info: Descriptor information structure. + * + * This local routine frees buffers used in the DMA buffers. + */ +static void ksz_free_buffers(struct dev_info *adapter, + struct ksz_desc_info *desc_info, int direction) +{ + int i; + struct ksz_dma_buf *dma_buf; + struct ksz_desc *desc = desc_info->ring; + + for (i = 0; i < desc_info->alloc; i++) { + dma_buf = DMA_BUFFER(desc); + if (dma_buf->skb) + free_dma_buf(adapter, dma_buf, direction); + desc++; + } +} + +/** + * ksz_free_mem - free all resources used by descriptors + * @adapter: Adapter information structure. + * + * This local routine frees all the resources allocated by ksz_alloc_mem(). + */ +static void ksz_free_mem(struct dev_info *adapter) +{ + /* Free transmit buffers. */ + ksz_free_buffers(adapter, &adapter->hw.tx_desc_info, + PCI_DMA_TODEVICE); + + /* Free receive buffers. */ + ksz_free_buffers(adapter, &adapter->hw.rx_desc_info, + PCI_DMA_FROMDEVICE); + + /* Free descriptors. */ + ksz_free_desc(adapter); +} + +static void get_mib_counters(struct ksz_hw *hw, int first, int cnt, + u64 *counter) +{ + int i; + int mib; + int port; + struct ksz_port_mib *port_mib; + + memset(counter, 0, sizeof(u64) * TOTAL_PORT_COUNTER_NUM); + for (i = 0, port = first; i < cnt; i++, port++) { + port_mib = &hw->port_mib[port]; + for (mib = port_mib->mib_start; mib < hw->mib_cnt; mib++) + counter[mib] += port_mib->counter[mib]; + } +} + +/** + * send_packet - send packet + * @skb: Socket buffer. + * @dev: Network device. + * + * This routine is used to send a packet out to the network. + */ +static void send_packet(struct sk_buff *skb, struct net_device *dev) +{ + struct ksz_desc *desc; + struct ksz_desc *first; + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_desc_info *info = &hw->tx_desc_info; + struct ksz_dma_buf *dma_buf; + int len; + int last_frag = skb_shinfo(skb)->nr_frags; + + /* + * KSZ8842 with multiple device interfaces needs to be told which port + * to send. + */ + if (hw->dev_count > 1) + hw->dst_ports = 1 << priv->port.first_port; + + /* Hardware will pad the length to 60. */ + len = skb->len; + + /* Remember the very first descriptor. */ + first = info->cur; + desc = first; + + dma_buf = DMA_BUFFER(desc); + if (last_frag) { + int frag; + skb_frag_t *this_frag; + + dma_buf->len = skb_headlen(skb); + + dma_buf->dma = pci_map_single( + hw_priv->pdev, skb->data, dma_buf->len, + PCI_DMA_TODEVICE); + set_tx_buf(desc, dma_buf->dma); + set_tx_len(desc, dma_buf->len); + + frag = 0; + do { + this_frag = &skb_shinfo(skb)->frags[frag]; + + /* Get a new descriptor. */ + get_tx_pkt(info, &desc); + + /* Keep track of descriptors used so far. */ + ++hw->tx_int_cnt; + + dma_buf = DMA_BUFFER(desc); + dma_buf->len = this_frag->size; + + dma_buf->dma = pci_map_single( + hw_priv->pdev, + page_address(this_frag->page) + + this_frag->page_offset, + dma_buf->len, + PCI_DMA_TODEVICE); + set_tx_buf(desc, dma_buf->dma); + set_tx_len(desc, dma_buf->len); + + frag++; + if (frag == last_frag) + break; + + /* Do not release the last descriptor here. */ + release_desc(desc); + } while (1); + + /* current points to the last descriptor. */ + info->cur = desc; + + /* Release the first descriptor. */ + release_desc(first); + } else { + dma_buf->len = len; + + dma_buf->dma = pci_map_single( + hw_priv->pdev, skb->data, dma_buf->len, + PCI_DMA_TODEVICE); + set_tx_buf(desc, dma_buf->dma); + set_tx_len(desc, dma_buf->len); + } + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + (desc)->sw.buf.tx.csum_gen_tcp = 1; + (desc)->sw.buf.tx.csum_gen_udp = 1; + } + + /* + * The last descriptor holds the packet so that it can be returned to + * network subsystem after all descriptors are transmitted. + */ + dma_buf->skb = skb; + + hw_send_pkt(hw); + + /* Update transmit statistics. */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; +} + +/** + * transmit_cleanup - clean up transmit descriptors + * @dev: Network device. + * + * This routine is called to clean up the transmitted buffers. + */ +static void transmit_cleanup(struct dev_info *hw_priv, int normal) +{ + int last; + union desc_stat status; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_desc_info *info = &hw->tx_desc_info; + struct ksz_desc *desc; + struct ksz_dma_buf *dma_buf; + struct net_device *dev = NULL; + + spin_lock(&hw_priv->hwlock); + last = info->last; + + while (info->avail < info->alloc) { + /* Get next descriptor which is not hardware owned. */ + desc = &info->ring[last]; + status.data = le32_to_cpu(desc->phw->ctrl.data); + if (status.tx.hw_owned) { + if (normal) + break; + else + reset_desc(desc, status); + } + + dma_buf = DMA_BUFFER(desc); + pci_unmap_single( + hw_priv->pdev, dma_buf->dma, dma_buf->len, + PCI_DMA_TODEVICE); + + /* This descriptor contains the last buffer in the packet. */ + if (dma_buf->skb) { + dev = dma_buf->skb->dev; + + /* Release the packet back to network subsystem. */ + dev_kfree_skb_irq(dma_buf->skb); + dma_buf->skb = NULL; + } + + /* Free the transmitted descriptor. */ + last++; + last &= info->mask; + info->avail++; + } + info->last = last; + spin_unlock(&hw_priv->hwlock); + + /* Notify the network subsystem that the packet has been sent. */ + if (dev) + dev->trans_start = jiffies; +} + +/** + * transmit_done - transmit done processing + * @dev: Network device. + * + * This routine is called when the transmit interrupt is triggered, indicating + * either a packet is sent successfully or there are transmit errors. + */ +static void tx_done(struct dev_info *hw_priv) +{ + struct ksz_hw *hw = &hw_priv->hw; + int port; + + transmit_cleanup(hw_priv, 1); + + for (port = 0; port < hw->dev_count; port++) { + struct net_device *dev = hw->port_info[port].pdev; + + if (netif_running(dev) && netif_queue_stopped(dev)) + netif_wake_queue(dev); + } +} + +static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb) +{ + skb->dev = old->dev; + skb->protocol = old->protocol; + skb->ip_summed = old->ip_summed; + skb->csum = old->csum; + skb_set_network_header(skb, ETH_HLEN); + + dev_kfree_skb(old); +} + +/** + * netdev_tx - send out packet + * @skb: Socket buffer. + * @dev: Network device. + * + * This function is used by the upper network layer to send out a packet. + * + * Return 0 if successful; otherwise an error code indicating failure. + */ +static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + int left; + int num = 1; + int rc = 0; + + if (hw->features & SMALL_PACKET_TX_BUG) { + struct sk_buff *org_skb = skb; + + if (skb->len <= 48) { + if (skb_end_pointer(skb) - skb->data >= 50) { + memset(&skb->data[skb->len], 0, 50 - skb->len); + skb->len = 50; + } else { + skb = dev_alloc_skb(50); + if (!skb) + return NETDEV_TX_BUSY; + memcpy(skb->data, org_skb->data, org_skb->len); + memset(&skb->data[org_skb->len], 0, + 50 - org_skb->len); + skb->len = 50; + copy_old_skb(org_skb, skb); + } + } + } + + spin_lock_irq(&hw_priv->hwlock); + + num = skb_shinfo(skb)->nr_frags + 1; + left = hw_alloc_pkt(hw, skb->len, num); + if (left) { + if (left < num || + ((CHECKSUM_PARTIAL == skb->ip_summed) && + (ETH_P_IPV6 == htons(skb->protocol)))) { + struct sk_buff *org_skb = skb; + + skb = dev_alloc_skb(org_skb->len); + if (!skb) { + rc = NETDEV_TX_BUSY; + goto unlock; + } + skb_copy_and_csum_dev(org_skb, skb->data); + org_skb->ip_summed = CHECKSUM_NONE; + skb->len = org_skb->len; + copy_old_skb(org_skb, skb); + } + send_packet(skb, dev); + if (left <= num) + netif_stop_queue(dev); + } else { + /* Stop the transmit queue until packet is allocated. */ + netif_stop_queue(dev); + rc = NETDEV_TX_BUSY; + } +unlock: + spin_unlock_irq(&hw_priv->hwlock); + + return rc; +} + +/** + * netdev_tx_timeout - transmit timeout processing + * @dev: Network device. + * + * This routine is called when the transmit timer expires. That indicates the + * hardware is not running correctly because transmit interrupts are not + * triggered to free up resources so that the transmit routine can continue + * sending out packets. The hardware is reset to correct the problem. + */ +static void netdev_tx_timeout(struct net_device *dev) +{ + static unsigned long last_reset; + + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + int port; + + if (hw->dev_count > 1) { + /* + * Only reset the hardware if time between calls is long + * enough. + */ + if (jiffies - last_reset <= dev->watchdog_timeo) + hw_priv = NULL; + } + + last_reset = jiffies; + if (hw_priv) { + hw_dis_intr(hw); + hw_disable(hw); + + transmit_cleanup(hw_priv, 0); + hw_reset_pkts(&hw->rx_desc_info); + hw_reset_pkts(&hw->tx_desc_info); + ksz_init_rx_buffers(hw_priv); + + hw_reset(hw); + + hw_set_desc_base(hw, + hw->tx_desc_info.ring_phys, + hw->rx_desc_info.ring_phys); + hw_set_addr(hw); + if (hw->all_multi) + hw_set_multicast(hw, hw->all_multi); + else if (hw->multi_list_size) + hw_set_grp_addr(hw); + + if (hw->dev_count > 1) { + hw_set_add_addr(hw); + for (port = 0; port < SWITCH_PORT_NUM; port++) { + struct net_device *port_dev; + + port_set_stp_state(hw, port, + STP_STATE_DISABLED); + + port_dev = hw->port_info[port].pdev; + if (netif_running(port_dev)) + port_set_stp_state(hw, port, + STP_STATE_SIMPLE); + } + } + + hw_enable(hw); + hw_ena_intr(hw); + } + + dev->trans_start = jiffies; + netif_wake_queue(dev); +} + +static inline void csum_verified(struct sk_buff *skb) +{ + unsigned short protocol; + struct iphdr *iph; + + protocol = skb->protocol; + skb_reset_network_header(skb); + iph = (struct iphdr *) skb_network_header(skb); + if (protocol == htons(ETH_P_8021Q)) { + protocol = iph->tot_len; + skb_set_network_header(skb, VLAN_HLEN); + iph = (struct iphdr *) skb_network_header(skb); + } + if (protocol == htons(ETH_P_IP)) { + if (iph->protocol == IPPROTO_TCP) + skb->ip_summed = CHECKSUM_UNNECESSARY; + } +} + +static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw, + struct ksz_desc *desc, union desc_stat status) +{ + int packet_len; + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_dma_buf *dma_buf; + struct sk_buff *skb; + int rx_status; + + /* Received length includes 4-byte CRC. */ + packet_len = status.rx.frame_len - 4; + + dma_buf = DMA_BUFFER(desc); + pci_dma_sync_single_for_cpu( + hw_priv->pdev, dma_buf->dma, packet_len + 4, + PCI_DMA_FROMDEVICE); + + do { + /* skb->data != skb->head */ + skb = dev_alloc_skb(packet_len + 2); + if (!skb) { + dev->stats.rx_dropped++; + return -ENOMEM; + } + + /* + * Align socket buffer in 4-byte boundary for better + * performance. + */ + skb_reserve(skb, 2); + + memcpy(skb_put(skb, packet_len), + dma_buf->skb->data, packet_len); + } while (0); + + skb->protocol = eth_type_trans(skb, dev); + + if (hw->rx_cfg & (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP)) + csum_verified(skb); + + /* Update receive statistics. */ + dev->stats.rx_packets++; + dev->stats.rx_bytes += packet_len; + + /* Notify upper layer for received packet. */ + rx_status = netif_rx(skb); + + return 0; +} + +static int dev_rcv_packets(struct dev_info *hw_priv) +{ + int next; + union desc_stat status; + struct ksz_hw *hw = &hw_priv->hw; + struct net_device *dev = hw->port_info[0].pdev; + struct ksz_desc_info *info = &hw->rx_desc_info; + int left = info->alloc; + struct ksz_desc *desc; + int received = 0; + + next = info->next; + while (left--) { + /* Get next descriptor which is not hardware owned. */ + desc = &info->ring[next]; + status.data = le32_to_cpu(desc->phw->ctrl.data); + if (status.rx.hw_owned) + break; + + /* Status valid only when last descriptor bit is set. */ + if (status.rx.last_desc && status.rx.first_desc) { + if (rx_proc(dev, hw, desc, status)) + goto release_packet; + received++; + } + +release_packet: + release_desc(desc); + next++; + next &= info->mask; + } + info->next = next; + + return received; +} + +static int port_rcv_packets(struct dev_info *hw_priv) +{ + int next; + union desc_stat status; + struct ksz_hw *hw = &hw_priv->hw; + struct net_device *dev = hw->port_info[0].pdev; + struct ksz_desc_info *info = &hw->rx_desc_info; + int left = info->alloc; + struct ksz_desc *desc; + int received = 0; + + next = info->next; + while (left--) { + /* Get next descriptor which is not hardware owned. */ + desc = &info->ring[next]; + status.data = le32_to_cpu(desc->phw->ctrl.data); + if (status.rx.hw_owned) + break; + + if (hw->dev_count > 1) { + /* Get received port number. */ + int p = HW_TO_DEV_PORT(status.rx.src_port); + + dev = hw->port_info[p].pdev; + if (!netif_running(dev)) + goto release_packet; + } + + /* Status valid only when last descriptor bit is set. */ + if (status.rx.last_desc && status.rx.first_desc) { + if (rx_proc(dev, hw, desc, status)) + goto release_packet; + received++; + } + +release_packet: + release_desc(desc); + next++; + next &= info->mask; + } + info->next = next; + + return received; +} + +static int dev_rcv_special(struct dev_info *hw_priv) +{ + int next; + union desc_stat status; + struct ksz_hw *hw = &hw_priv->hw; + struct net_device *dev = hw->port_info[0].pdev; + struct ksz_desc_info *info = &hw->rx_desc_info; + int left = info->alloc; + struct ksz_desc *desc; + int received = 0; + + next = info->next; + while (left--) { + /* Get next descriptor which is not hardware owned. */ + desc = &info->ring[next]; + status.data = le32_to_cpu(desc->phw->ctrl.data); + if (status.rx.hw_owned) + break; + + if (hw->dev_count > 1) { + /* Get received port number. */ + int p = HW_TO_DEV_PORT(status.rx.src_port); + + dev = hw->port_info[p].pdev; + if (!netif_running(dev)) + goto release_packet; + } + + /* Status valid only when last descriptor bit is set. */ + if (status.rx.last_desc && status.rx.first_desc) { + /* + * Receive without error. With receive errors + * disabled, packets with receive errors will be + * dropped, so no need to check the error bit. + */ + if (!status.rx.error || (status.data & + KS_DESC_RX_ERROR_COND) == + KS_DESC_RX_ERROR_TOO_LONG) { + if (rx_proc(dev, hw, desc, status)) + goto release_packet; + received++; + } else { + struct dev_priv *priv = netdev_priv(dev); + + /* Update receive error statistics. */ + priv->port.counter[OID_COUNTER_RCV_ERROR]++; + } + } + +release_packet: + release_desc(desc); + next++; + next &= info->mask; + } + info->next = next; + + return received; +} + +static void rx_proc_task(unsigned long data) +{ + struct dev_info *hw_priv = (struct dev_info *) data; + struct ksz_hw *hw = &hw_priv->hw; + + if (!hw->enabled) + return; + if (unlikely(!hw_priv->dev_rcv(hw_priv))) { + + /* In case receive process is suspended because of overrun. */ + hw_resume_rx(hw); + + /* tasklets are interruptible. */ + spin_lock_irq(&hw_priv->hwlock); + hw_turn_on_intr(hw, KS884X_INT_RX_MASK); + spin_unlock_irq(&hw_priv->hwlock); + } else { + hw_ack_intr(hw, KS884X_INT_RX); + tasklet_schedule(&hw_priv->rx_tasklet); + } +} + +static void tx_proc_task(unsigned long data) +{ + struct dev_info *hw_priv = (struct dev_info *) data; + struct ksz_hw *hw = &hw_priv->hw; + + hw_ack_intr(hw, KS884X_INT_TX_MASK); + + tx_done(hw_priv); + + /* tasklets are interruptible. */ + spin_lock_irq(&hw_priv->hwlock); + hw_turn_on_intr(hw, KS884X_INT_TX); + spin_unlock_irq(&hw_priv->hwlock); +} + +static inline void handle_rx_stop(struct ksz_hw *hw) +{ + /* Receive just has been stopped. */ + if (0 == hw->rx_stop) + hw->intr_mask &= ~KS884X_INT_RX_STOPPED; + else if (hw->rx_stop > 1) { + if (hw->enabled && (hw->rx_cfg & DMA_RX_ENABLE)) { + hw_start_rx(hw); + } else { + hw->intr_mask &= ~KS884X_INT_RX_STOPPED; + hw->rx_stop = 0; + } + } else + /* Receive just has been started. */ + hw->rx_stop++; +} + +/** + * netdev_intr - interrupt handling + * @irq: Interrupt number. + * @dev_id: Network device. + * + * This function is called by upper network layer to signal interrupt. + * + * Return IRQ_HANDLED if interrupt is handled. + */ +static irqreturn_t netdev_intr(int irq, void *dev_id) +{ + uint int_enable = 0; + struct net_device *dev = (struct net_device *) dev_id; + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + hw_read_intr(hw, &int_enable); + + /* Not our interrupt! */ + if (!int_enable) + return IRQ_NONE; + + do { + hw_ack_intr(hw, int_enable); + int_enable &= hw->intr_mask; + + if (unlikely(int_enable & KS884X_INT_TX_MASK)) { + hw_dis_intr_bit(hw, KS884X_INT_TX_MASK); + tasklet_schedule(&hw_priv->tx_tasklet); + } + + if (likely(int_enable & KS884X_INT_RX)) { + hw_dis_intr_bit(hw, KS884X_INT_RX); + tasklet_schedule(&hw_priv->rx_tasklet); + } + + if (unlikely(int_enable & KS884X_INT_RX_OVERRUN)) { + dev->stats.rx_fifo_errors++; + hw_resume_rx(hw); + } + + if (unlikely(int_enable & KS884X_INT_PHY)) { + struct ksz_port *port = &priv->port; + + hw->features |= LINK_INT_WORKING; + port_get_link_speed(port); + } + + if (unlikely(int_enable & KS884X_INT_RX_STOPPED)) { + handle_rx_stop(hw); + break; + } + + if (unlikely(int_enable & KS884X_INT_TX_STOPPED)) { + u32 data; + + hw->intr_mask &= ~KS884X_INT_TX_STOPPED; + pr_info("Tx stopped\n"); + data = readl(hw->io + KS_DMA_TX_CTRL); + if (!(data & DMA_TX_ENABLE)) + pr_info("Tx disabled\n"); + break; + } + } while (0); + + hw_ena_intr(hw); + + return IRQ_HANDLED; +} + +/* + * Linux network device functions + */ + +static unsigned long next_jiffies; + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void netdev_netpoll(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + + hw_dis_intr(&hw_priv->hw); + netdev_intr(dev->irq, dev); +} +#endif + +static void bridge_change(struct ksz_hw *hw) +{ + int port; + u8 member; + struct ksz_switch *sw = hw->ksz_switch; + + /* No ports in forwarding state. */ + if (!sw->member) { + port_set_stp_state(hw, SWITCH_PORT_NUM, STP_STATE_SIMPLE); + sw_block_addr(hw); + } + for (port = 0; port < SWITCH_PORT_NUM; port++) { + if (STP_STATE_FORWARDING == sw->port_cfg[port].stp_state) + member = HOST_MASK | sw->member; + else + member = HOST_MASK | (1 << port); + if (member != sw->port_cfg[port].member) + sw_cfg_port_base_vlan(hw, port, member); + } +} + +/** + * netdev_close - close network device + * @dev: Network device. + * + * This function process the close operation of network device. This is caused + * by the user command "ifconfig ethX down." + * + * Return 0 if successful; otherwise an error code indicating failure. + */ +static int netdev_close(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_port *port = &priv->port; + struct ksz_hw *hw = &hw_priv->hw; + int pi; + + netif_stop_queue(dev); + + ksz_stop_timer(&priv->monitor_timer_info); + + /* Need to shut the port manually in multiple device interfaces mode. */ + if (hw->dev_count > 1) { + port_set_stp_state(hw, port->first_port, STP_STATE_DISABLED); + + /* Port is closed. Need to change bridge setting. */ + if (hw->features & STP_SUPPORT) { + pi = 1 << port->first_port; + if (hw->ksz_switch->member & pi) { + hw->ksz_switch->member &= ~pi; + bridge_change(hw); + } + } + } + if (port->first_port > 0) + hw_del_addr(hw, dev->dev_addr); + if (!hw_priv->wol_enable) + port_set_power_saving(port, true); + + if (priv->multicast) + --hw->all_multi; + if (priv->promiscuous) + --hw->promiscuous; + + hw_priv->opened--; + if (!(hw_priv->opened)) { + ksz_stop_timer(&hw_priv->mib_timer_info); + flush_work(&hw_priv->mib_read); + + hw_dis_intr(hw); + hw_disable(hw); + hw_clr_multicast(hw); + + /* Delay for receive task to stop scheduling itself. */ + msleep(2000 / HZ); + + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); + free_irq(dev->irq, hw_priv->dev); + + transmit_cleanup(hw_priv, 0); + hw_reset_pkts(&hw->rx_desc_info); + hw_reset_pkts(&hw->tx_desc_info); + + /* Clean out static MAC table when the switch is shutdown. */ + if (hw->features & STP_SUPPORT) + sw_clr_sta_mac_table(hw); + } + + return 0; +} + +static void hw_cfg_huge_frame(struct dev_info *hw_priv, struct ksz_hw *hw) +{ + if (hw->ksz_switch) { + u32 data; + + data = readw(hw->io + KS8842_SWITCH_CTRL_2_OFFSET); + if (hw->features & RX_HUGE_FRAME) + data |= SWITCH_HUGE_PACKET; + else + data &= ~SWITCH_HUGE_PACKET; + writew(data, hw->io + KS8842_SWITCH_CTRL_2_OFFSET); + } + if (hw->features & RX_HUGE_FRAME) { + hw->rx_cfg |= DMA_RX_ERROR; + hw_priv->dev_rcv = dev_rcv_special; + } else { + hw->rx_cfg &= ~DMA_RX_ERROR; + if (hw->dev_count > 1) + hw_priv->dev_rcv = port_rcv_packets; + else + hw_priv->dev_rcv = dev_rcv_packets; + } +} + +static int prepare_hardware(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + int rc = 0; + + /* Remember the network device that requests interrupts. */ + hw_priv->dev = dev; + rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); + if (rc) + return rc; + tasklet_enable(&hw_priv->rx_tasklet); + tasklet_enable(&hw_priv->tx_tasklet); + + hw->promiscuous = 0; + hw->all_multi = 0; + hw->multi_list_size = 0; + + hw_reset(hw); + + hw_set_desc_base(hw, + hw->tx_desc_info.ring_phys, hw->rx_desc_info.ring_phys); + hw_set_addr(hw); + hw_cfg_huge_frame(hw_priv, hw); + ksz_init_rx_buffers(hw_priv); + return 0; +} + +static void set_media_state(struct net_device *dev, int media_state) +{ + struct dev_priv *priv = netdev_priv(dev); + + if (media_state == priv->media_state) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + netif_info(priv, link, dev, "link %s\n", + media_state == priv->media_state ? "on" : "off"); +} + +/** + * netdev_open - open network device + * @dev: Network device. + * + * This function process the open operation of network device. This is caused + * by the user command "ifconfig ethX up." + * + * Return 0 if successful; otherwise an error code indicating failure. + */ +static int netdev_open(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port *port = &priv->port; + int i; + int p; + int rc = 0; + + priv->multicast = 0; + priv->promiscuous = 0; + + /* Reset device statistics. */ + memset(&dev->stats, 0, sizeof(struct net_device_stats)); + memset((void *) port->counter, 0, + (sizeof(u64) * OID_COUNTER_LAST)); + + if (!(hw_priv->opened)) { + rc = prepare_hardware(dev); + if (rc) + return rc; + for (i = 0; i < hw->mib_port_cnt; i++) { + if (next_jiffies < jiffies) + next_jiffies = jiffies + HZ * 2; + else + next_jiffies += HZ * 1; + hw_priv->counter[i].time = next_jiffies; + hw->port_mib[i].state = media_disconnected; + port_init_cnt(hw, i); + } + if (hw->ksz_switch) + hw->port_mib[HOST_PORT].state = media_connected; + else { + hw_add_wol_bcast(hw); + hw_cfg_wol_pme(hw, 0); + hw_clr_wol_pme_status(&hw_priv->hw); + } + } + port_set_power_saving(port, false); + + for (i = 0, p = port->first_port; i < port->port_cnt; i++, p++) { + /* + * Initialize to invalid value so that link detection + * is done. + */ + hw->port_info[p].partner = 0xFF; + hw->port_info[p].state = media_disconnected; + } + + /* Need to open the port in multiple device interfaces mode. */ + if (hw->dev_count > 1) { + port_set_stp_state(hw, port->first_port, STP_STATE_SIMPLE); + if (port->first_port > 0) + hw_add_addr(hw, dev->dev_addr); + } + + port_get_link_speed(port); + if (port->force_link) + port_force_link_speed(port); + else + port_set_link_speed(port); + + if (!(hw_priv->opened)) { + hw_setup_intr(hw); + hw_enable(hw); + hw_ena_intr(hw); + + if (hw->mib_port_cnt) + ksz_start_timer(&hw_priv->mib_timer_info, + hw_priv->mib_timer_info.period); + } + + hw_priv->opened++; + + ksz_start_timer(&priv->monitor_timer_info, + priv->monitor_timer_info.period); + + priv->media_state = port->linked->state; + + set_media_state(dev, media_connected); + netif_start_queue(dev); + + return 0; +} + +/* RX errors = rx_errors */ +/* RX dropped = rx_dropped */ +/* RX overruns = rx_fifo_errors */ +/* RX frame = rx_crc_errors + rx_frame_errors + rx_length_errors */ +/* TX errors = tx_errors */ +/* TX dropped = tx_dropped */ +/* TX overruns = tx_fifo_errors */ +/* TX carrier = tx_aborted_errors + tx_carrier_errors + tx_window_errors */ +/* collisions = collisions */ + +/** + * netdev_query_statistics - query network device statistics + * @dev: Network device. + * + * This function returns the statistics of the network device. The device + * needs not be opened. + * + * Return network device statistics. + */ +static struct net_device_stats *netdev_query_statistics(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct ksz_port *port = &priv->port; + struct ksz_hw *hw = &priv->adapter->hw; + struct ksz_port_mib *mib; + int i; + int p; + + dev->stats.rx_errors = port->counter[OID_COUNTER_RCV_ERROR]; + dev->stats.tx_errors = port->counter[OID_COUNTER_XMIT_ERROR]; + + /* Reset to zero to add count later. */ + dev->stats.multicast = 0; + dev->stats.collisions = 0; + dev->stats.rx_length_errors = 0; + dev->stats.rx_crc_errors = 0; + dev->stats.rx_frame_errors = 0; + dev->stats.tx_window_errors = 0; + + for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) { + mib = &hw->port_mib[p]; + + dev->stats.multicast += (unsigned long) + mib->counter[MIB_COUNTER_RX_MULTICAST]; + + dev->stats.collisions += (unsigned long) + mib->counter[MIB_COUNTER_TX_TOTAL_COLLISION]; + + dev->stats.rx_length_errors += (unsigned long)( + mib->counter[MIB_COUNTER_RX_UNDERSIZE] + + mib->counter[MIB_COUNTER_RX_FRAGMENT] + + mib->counter[MIB_COUNTER_RX_OVERSIZE] + + mib->counter[MIB_COUNTER_RX_JABBER]); + dev->stats.rx_crc_errors += (unsigned long) + mib->counter[MIB_COUNTER_RX_CRC_ERR]; + dev->stats.rx_frame_errors += (unsigned long)( + mib->counter[MIB_COUNTER_RX_ALIGNMENT_ERR] + + mib->counter[MIB_COUNTER_RX_SYMBOL_ERR]); + + dev->stats.tx_window_errors += (unsigned long) + mib->counter[MIB_COUNTER_TX_LATE_COLLISION]; + } + + return &dev->stats; +} + +/** + * netdev_set_mac_address - set network device MAC address + * @dev: Network device. + * @addr: Buffer of MAC address. + * + * This function is used to set the MAC address of the network device. + * + * Return 0 to indicate success. + */ +static int netdev_set_mac_address(struct net_device *dev, void *addr) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct sockaddr *mac = addr; + uint interrupt; + + if (priv->port.first_port > 0) + hw_del_addr(hw, dev->dev_addr); + else { + hw->mac_override = 1; + memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN); + } + + memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); + + interrupt = hw_block_intr(hw); + + if (priv->port.first_port > 0) + hw_add_addr(hw, dev->dev_addr); + else + hw_set_addr(hw); + hw_restore_intr(hw, interrupt); + + return 0; +} + +static void dev_set_promiscuous(struct net_device *dev, struct dev_priv *priv, + struct ksz_hw *hw, int promiscuous) +{ + if (promiscuous != priv->promiscuous) { + u8 prev_state = hw->promiscuous; + + if (promiscuous) + ++hw->promiscuous; + else + --hw->promiscuous; + priv->promiscuous = promiscuous; + + /* Turn on/off promiscuous mode. */ + if (hw->promiscuous <= 1 && prev_state <= 1) + hw_set_promiscuous(hw, hw->promiscuous); + + /* + * Port is not in promiscuous mode, meaning it is released + * from the bridge. + */ + if ((hw->features & STP_SUPPORT) && !promiscuous && + (dev->priv_flags & IFF_BRIDGE_PORT)) { + struct ksz_switch *sw = hw->ksz_switch; + int port = priv->port.first_port; + + port_set_stp_state(hw, port, STP_STATE_DISABLED); + port = 1 << port; + if (sw->member & port) { + sw->member &= ~port; + bridge_change(hw); + } + } + } +} + +static void dev_set_multicast(struct dev_priv *priv, struct ksz_hw *hw, + int multicast) +{ + if (multicast != priv->multicast) { + u8 all_multi = hw->all_multi; + + if (multicast) + ++hw->all_multi; + else + --hw->all_multi; + priv->multicast = multicast; + + /* Turn on/off all multicast mode. */ + if (hw->all_multi <= 1 && all_multi <= 1) + hw_set_multicast(hw, hw->all_multi); + } +} + +/** + * netdev_set_rx_mode + * @dev: Network device. + * + * This routine is used to set multicast addresses or put the network device + * into promiscuous mode. + */ +static void netdev_set_rx_mode(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct netdev_hw_addr *ha; + int multicast = (dev->flags & IFF_ALLMULTI); + + dev_set_promiscuous(dev, priv, hw, (dev->flags & IFF_PROMISC)); + + if (hw_priv->hw.dev_count > 1) + multicast |= (dev->flags & IFF_MULTICAST); + dev_set_multicast(priv, hw, multicast); + + /* Cannot use different hashes in multiple device interfaces mode. */ + if (hw_priv->hw.dev_count > 1) + return; + + if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) { + int i = 0; + + /* List too big to support so turn on all multicast mode. */ + if (netdev_mc_count(dev) > MAX_MULTICAST_LIST) { + if (MAX_MULTICAST_LIST != hw->multi_list_size) { + hw->multi_list_size = MAX_MULTICAST_LIST; + ++hw->all_multi; + hw_set_multicast(hw, hw->all_multi); + } + return; + } + + netdev_for_each_mc_addr(ha, dev) { + if (i >= MAX_MULTICAST_LIST) + break; + memcpy(hw->multi_list[i++], ha->addr, MAC_ADDR_LEN); + } + hw->multi_list_size = (u8) i; + hw_set_grp_addr(hw); + } else { + if (MAX_MULTICAST_LIST == hw->multi_list_size) { + --hw->all_multi; + hw_set_multicast(hw, hw->all_multi); + } + hw->multi_list_size = 0; + hw_clr_multicast(hw); + } +} + +static int netdev_change_mtu(struct net_device *dev, int new_mtu) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + int hw_mtu; + + if (netif_running(dev)) + return -EBUSY; + + /* Cannot use different MTU in multiple device interfaces mode. */ + if (hw->dev_count > 1) + if (dev != hw_priv->dev) + return 0; + if (new_mtu < 60) + return -EINVAL; + + if (dev->mtu != new_mtu) { + hw_mtu = new_mtu + ETHERNET_HEADER_SIZE + 4; + if (hw_mtu > MAX_RX_BUF_SIZE) + return -EINVAL; + if (hw_mtu > REGULAR_RX_BUF_SIZE) { + hw->features |= RX_HUGE_FRAME; + hw_mtu = MAX_RX_BUF_SIZE; + } else { + hw->features &= ~RX_HUGE_FRAME; + hw_mtu = REGULAR_RX_BUF_SIZE; + } + hw_mtu = (hw_mtu + 3) & ~3; + hw_priv->mtu = hw_mtu; + dev->mtu = new_mtu; + } + return 0; +} + +/** + * netdev_ioctl - I/O control processing + * @dev: Network device. + * @ifr: Interface request structure. + * @cmd: I/O control code. + * + * This function is used to process I/O control calls. + * + * Return 0 to indicate success. + */ +static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port *port = &priv->port; + int rc; + int result = 0; + struct mii_ioctl_data *data = if_mii(ifr); + + if (down_interruptible(&priv->proc_sem)) + return -ERESTARTSYS; + + /* assume success */ + rc = 0; + switch (cmd) { + /* Get address of MII PHY in use. */ + case SIOCGMIIPHY: + data->phy_id = priv->id; + + /* Fallthrough... */ + + /* Read MII PHY register. */ + case SIOCGMIIREG: + if (data->phy_id != priv->id || data->reg_num >= 6) + result = -EIO; + else + hw_r_phy(hw, port->linked->port_id, data->reg_num, + &data->val_out); + break; + + /* Write MII PHY register. */ + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + result = -EPERM; + else if (data->phy_id != priv->id || data->reg_num >= 6) + result = -EIO; + else + hw_w_phy(hw, port->linked->port_id, data->reg_num, + data->val_in); + break; + + default: + result = -EOPNOTSUPP; + } + + up(&priv->proc_sem); + + return result; +} + +/* + * MII support + */ + +/** + * mdio_read - read PHY register + * @dev: Network device. + * @phy_id: The PHY id. + * @reg_num: The register number. + * + * This function returns the PHY register value. + * + * Return the register value. + */ +static int mdio_read(struct net_device *dev, int phy_id, int reg_num) +{ + struct dev_priv *priv = netdev_priv(dev); + struct ksz_port *port = &priv->port; + struct ksz_hw *hw = port->hw; + u16 val_out; + + hw_r_phy(hw, port->linked->port_id, reg_num << 1, &val_out); + return val_out; +} + +/** + * mdio_write - set PHY register + * @dev: Network device. + * @phy_id: The PHY id. + * @reg_num: The register number. + * @val: The register value. + * + * This procedure sets the PHY register value. + */ +static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) +{ + struct dev_priv *priv = netdev_priv(dev); + struct ksz_port *port = &priv->port; + struct ksz_hw *hw = port->hw; + int i; + int pi; + + for (i = 0, pi = port->first_port; i < port->port_cnt; i++, pi++) + hw_w_phy(hw, pi, reg_num << 1, val); +} + +/* + * ethtool support + */ + +#define EEPROM_SIZE 0x40 + +static u16 eeprom_data[EEPROM_SIZE] = { 0 }; + +#define ADVERTISED_ALL \ + (ADVERTISED_10baseT_Half | \ + ADVERTISED_10baseT_Full | \ + ADVERTISED_100baseT_Half | \ + ADVERTISED_100baseT_Full) + +/* These functions use the MII functions in mii.c. */ + +/** + * netdev_get_settings - get network device settings + * @dev: Network device. + * @cmd: Ethtool command. + * + * This function queries the PHY and returns its state in the ethtool command. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + + mutex_lock(&hw_priv->lock); + mii_ethtool_gset(&priv->mii_if, cmd); + cmd->advertising |= SUPPORTED_TP; + mutex_unlock(&hw_priv->lock); + + /* Save advertised settings for workaround in next function. */ + priv->advertising = cmd->advertising; + return 0; +} + +/** + * netdev_set_settings - set network device settings + * @dev: Network device. + * @cmd: Ethtool command. + * + * This function sets the PHY according to the ethtool command. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_port *port = &priv->port; + u32 speed = ethtool_cmd_speed(cmd); + int rc; + + /* + * ethtool utility does not change advertised setting if auto + * negotiation is not specified explicitly. + */ + if (cmd->autoneg && priv->advertising == cmd->advertising) { + cmd->advertising |= ADVERTISED_ALL; + if (10 == speed) + cmd->advertising &= + ~(ADVERTISED_100baseT_Full | + ADVERTISED_100baseT_Half); + else if (100 == speed) + cmd->advertising &= + ~(ADVERTISED_10baseT_Full | + ADVERTISED_10baseT_Half); + if (0 == cmd->duplex) + cmd->advertising &= + ~(ADVERTISED_100baseT_Full | + ADVERTISED_10baseT_Full); + else if (1 == cmd->duplex) + cmd->advertising &= + ~(ADVERTISED_100baseT_Half | + ADVERTISED_10baseT_Half); + } + mutex_lock(&hw_priv->lock); + if (cmd->autoneg && + (cmd->advertising & ADVERTISED_ALL) == + ADVERTISED_ALL) { + port->duplex = 0; + port->speed = 0; + port->force_link = 0; + } else { + port->duplex = cmd->duplex + 1; + if (1000 != speed) + port->speed = speed; + if (cmd->autoneg) + port->force_link = 0; + else + port->force_link = 1; + } + rc = mii_ethtool_sset(&priv->mii_if, cmd); + mutex_unlock(&hw_priv->lock); + return rc; +} + +/** + * netdev_nway_reset - restart auto-negotiation + * @dev: Network device. + * + * This function restarts the PHY for auto-negotiation. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_nway_reset(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + int rc; + + mutex_lock(&hw_priv->lock); + rc = mii_nway_restart(&priv->mii_if); + mutex_unlock(&hw_priv->lock); + return rc; +} + +/** + * netdev_get_link - get network device link status + * @dev: Network device. + * + * This function gets the link status from the PHY. + * + * Return true if PHY is linked and false otherwise. + */ +static u32 netdev_get_link(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + int rc; + + rc = mii_link_ok(&priv->mii_if); + return rc; +} + +/** + * netdev_get_drvinfo - get network driver information + * @dev: Network device. + * @info: Ethtool driver info data structure. + * + * This procedure returns the driver information. + */ +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(hw_priv->pdev)); +} + +/** + * netdev_get_regs_len - get length of register dump + * @dev: Network device. + * + * This function returns the length of the register dump. + * + * Return length of the register dump. + */ +static struct hw_regs { + int start; + int end; +} hw_regs_range[] = { + { KS_DMA_TX_CTRL, KS884X_INTERRUPTS_STATUS }, + { KS_ADD_ADDR_0_LO, KS_ADD_ADDR_F_HI }, + { KS884X_ADDR_0_OFFSET, KS8841_WOL_FRAME_BYTE2_OFFSET }, + { KS884X_SIDER_P, KS8842_SGCR7_P }, + { KS8842_MACAR1_P, KS8842_TOSR8_P }, + { KS884X_P1MBCR_P, KS8842_P3ERCR_P }, + { 0, 0 } +}; + +static int netdev_get_regs_len(struct net_device *dev) +{ + struct hw_regs *range = hw_regs_range; + int regs_len = 0x10 * sizeof(u32); + + while (range->end > range->start) { + regs_len += (range->end - range->start + 3) / 4 * 4; + range++; + } + return regs_len; +} + +/** + * netdev_get_regs - get register dump + * @dev: Network device. + * @regs: Ethtool registers data structure. + * @ptr: Buffer to store the register values. + * + * This procedure dumps the register values in the provided buffer. + */ +static void netdev_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *ptr) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + int *buf = (int *) ptr; + struct hw_regs *range = hw_regs_range; + int len; + + mutex_lock(&hw_priv->lock); + regs->version = 0; + for (len = 0; len < 0x40; len += 4) { + pci_read_config_dword(hw_priv->pdev, len, buf); + buf++; + } + while (range->end > range->start) { + for (len = range->start; len < range->end; len += 4) { + *buf = readl(hw->io + len); + buf++; + } + range++; + } + mutex_unlock(&hw_priv->lock); +} + +#define WOL_SUPPORT \ + (WAKE_PHY | WAKE_MAGIC | \ + WAKE_UCAST | WAKE_MCAST | \ + WAKE_BCAST | WAKE_ARP) + +/** + * netdev_get_wol - get Wake-on-LAN support + * @dev: Network device. + * @wol: Ethtool Wake-on-LAN data structure. + * + * This procedure returns Wake-on-LAN support. + */ +static void netdev_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + + wol->supported = hw_priv->wol_support; + wol->wolopts = hw_priv->wol_enable; + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +/** + * netdev_set_wol - set Wake-on-LAN support + * @dev: Network device. + * @wol: Ethtool Wake-on-LAN data structure. + * + * This function sets Wake-on-LAN support. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + + /* Need to find a way to retrieve the device IP address. */ + static const u8 net_addr[] = { 192, 168, 1, 1 }; + + if (wol->wolopts & ~hw_priv->wol_support) + return -EINVAL; + + hw_priv->wol_enable = wol->wolopts; + + /* Link wakeup cannot really be disabled. */ + if (wol->wolopts) + hw_priv->wol_enable |= WAKE_PHY; + hw_enable_wol(&hw_priv->hw, hw_priv->wol_enable, net_addr); + return 0; +} + +/** + * netdev_get_msglevel - get debug message level + * @dev: Network device. + * + * This function returns current debug message level. + * + * Return current debug message flags. + */ +static u32 netdev_get_msglevel(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + + return priv->msg_enable; +} + +/** + * netdev_set_msglevel - set debug message level + * @dev: Network device. + * @value: Debug message flags. + * + * This procedure sets debug message level. + */ +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + struct dev_priv *priv = netdev_priv(dev); + + priv->msg_enable = value; +} + +/** + * netdev_get_eeprom_len - get EEPROM length + * @dev: Network device. + * + * This function returns the length of the EEPROM. + * + * Return length of the EEPROM. + */ +static int netdev_get_eeprom_len(struct net_device *dev) +{ + return EEPROM_SIZE * 2; +} + +/** + * netdev_get_eeprom - get EEPROM data + * @dev: Network device. + * @eeprom: Ethtool EEPROM data structure. + * @data: Buffer to store the EEPROM data. + * + * This function dumps the EEPROM data in the provided buffer. + * + * Return 0 if successful; otherwise an error code. + */ +#define EEPROM_MAGIC 0x10A18842 + +static int netdev_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + u8 *eeprom_byte = (u8 *) eeprom_data; + int i; + int len; + + len = (eeprom->offset + eeprom->len + 1) / 2; + for (i = eeprom->offset / 2; i < len; i++) + eeprom_data[i] = eeprom_read(&hw_priv->hw, i); + eeprom->magic = EEPROM_MAGIC; + memcpy(data, &eeprom_byte[eeprom->offset], eeprom->len); + + return 0; +} + +/** + * netdev_set_eeprom - write EEPROM data + * @dev: Network device. + * @eeprom: Ethtool EEPROM data structure. + * @data: Data buffer. + * + * This function modifies the EEPROM data one byte at a time. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + u16 eeprom_word[EEPROM_SIZE]; + u8 *eeprom_byte = (u8 *) eeprom_word; + int i; + int len; + + if (eeprom->magic != EEPROM_MAGIC) + return -EINVAL; + + len = (eeprom->offset + eeprom->len + 1) / 2; + for (i = eeprom->offset / 2; i < len; i++) + eeprom_data[i] = eeprom_read(&hw_priv->hw, i); + memcpy(eeprom_word, eeprom_data, EEPROM_SIZE * 2); + memcpy(&eeprom_byte[eeprom->offset], data, eeprom->len); + for (i = 0; i < EEPROM_SIZE; i++) + if (eeprom_word[i] != eeprom_data[i]) { + eeprom_data[i] = eeprom_word[i]; + eeprom_write(&hw_priv->hw, i, eeprom_data[i]); + } + + return 0; +} + +/** + * netdev_get_pauseparam - get flow control parameters + * @dev: Network device. + * @pause: Ethtool PAUSE settings data structure. + * + * This procedure returns the PAUSE control flow settings. + */ +static void netdev_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + pause->autoneg = (hw->overrides & PAUSE_FLOW_CTRL) ? 0 : 1; + if (!hw->ksz_switch) { + pause->rx_pause = + (hw->rx_cfg & DMA_RX_FLOW_ENABLE) ? 1 : 0; + pause->tx_pause = + (hw->tx_cfg & DMA_TX_FLOW_ENABLE) ? 1 : 0; + } else { + pause->rx_pause = + (sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_RX_FLOW_CTRL)) ? 1 : 0; + pause->tx_pause = + (sw_chk(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_TX_FLOW_CTRL)) ? 1 : 0; + } +} + +/** + * netdev_set_pauseparam - set flow control parameters + * @dev: Network device. + * @pause: Ethtool PAUSE settings data structure. + * + * This function sets the PAUSE control flow settings. + * Not implemented yet. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port *port = &priv->port; + + mutex_lock(&hw_priv->lock); + if (pause->autoneg) { + if (!pause->rx_pause && !pause->tx_pause) + port->flow_ctrl = PHY_NO_FLOW_CTRL; + else + port->flow_ctrl = PHY_FLOW_CTRL; + hw->overrides &= ~PAUSE_FLOW_CTRL; + port->force_link = 0; + if (hw->ksz_switch) { + sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_RX_FLOW_CTRL, 1); + sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_TX_FLOW_CTRL, 1); + } + port_set_link_speed(port); + } else { + hw->overrides |= PAUSE_FLOW_CTRL; + if (hw->ksz_switch) { + sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_RX_FLOW_CTRL, pause->rx_pause); + sw_cfg(hw, KS8842_SWITCH_CTRL_1_OFFSET, + SWITCH_TX_FLOW_CTRL, pause->tx_pause); + } else + set_flow_ctrl(hw, pause->rx_pause, pause->tx_pause); + } + mutex_unlock(&hw_priv->lock); + + return 0; +} + +/** + * netdev_get_ringparam - get tx/rx ring parameters + * @dev: Network device. + * @pause: Ethtool RING settings data structure. + * + * This procedure returns the TX/RX ring settings. + */ +static void netdev_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + ring->tx_max_pending = (1 << 9); + ring->tx_pending = hw->tx_desc_info.alloc; + ring->rx_max_pending = (1 << 9); + ring->rx_pending = hw->rx_desc_info.alloc; +} + +#define STATS_LEN (TOTAL_PORT_COUNTER_NUM) + +static struct { + char string[ETH_GSTRING_LEN]; +} ethtool_stats_keys[STATS_LEN] = { + { "rx_lo_priority_octets" }, + { "rx_hi_priority_octets" }, + { "rx_undersize_packets" }, + { "rx_fragments" }, + { "rx_oversize_packets" }, + { "rx_jabbers" }, + { "rx_symbol_errors" }, + { "rx_crc_errors" }, + { "rx_align_errors" }, + { "rx_mac_ctrl_packets" }, + { "rx_pause_packets" }, + { "rx_bcast_packets" }, + { "rx_mcast_packets" }, + { "rx_ucast_packets" }, + { "rx_64_or_less_octet_packets" }, + { "rx_65_to_127_octet_packets" }, + { "rx_128_to_255_octet_packets" }, + { "rx_256_to_511_octet_packets" }, + { "rx_512_to_1023_octet_packets" }, + { "rx_1024_to_1522_octet_packets" }, + + { "tx_lo_priority_octets" }, + { "tx_hi_priority_octets" }, + { "tx_late_collisions" }, + { "tx_pause_packets" }, + { "tx_bcast_packets" }, + { "tx_mcast_packets" }, + { "tx_ucast_packets" }, + { "tx_deferred" }, + { "tx_total_collisions" }, + { "tx_excessive_collisions" }, + { "tx_single_collisions" }, + { "tx_mult_collisions" }, + + { "rx_discards" }, + { "tx_discards" }, +}; + +/** + * netdev_get_strings - get statistics identity strings + * @dev: Network device. + * @stringset: String set identifier. + * @buf: Buffer to store the strings. + * + * This procedure returns the strings used to identify the statistics. + */ +static void netdev_get_strings(struct net_device *dev, u32 stringset, u8 *buf) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + if (ETH_SS_STATS == stringset) + memcpy(buf, ðtool_stats_keys, + ETH_GSTRING_LEN * hw->mib_cnt); +} + +/** + * netdev_get_sset_count - get statistics size + * @dev: Network device. + * @sset: The statistics set number. + * + * This function returns the size of the statistics to be reported. + * + * Return size of the statistics to be reported. + */ +static int netdev_get_sset_count(struct net_device *dev, int sset) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + switch (sset) { + case ETH_SS_STATS: + return hw->mib_cnt; + default: + return -EOPNOTSUPP; + } +} + +/** + * netdev_get_ethtool_stats - get network device statistics + * @dev: Network device. + * @stats: Ethtool statistics data structure. + * @data: Buffer to store the statistics. + * + * This procedure returns the statistics. + */ +static void netdev_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port *port = &priv->port; + int n_stats = stats->n_stats; + int i; + int n; + int p; + int rc; + u64 counter[TOTAL_PORT_COUNTER_NUM]; + + mutex_lock(&hw_priv->lock); + n = SWITCH_PORT_NUM; + for (i = 0, p = port->first_port; i < port->mib_port_cnt; i++, p++) { + if (media_connected == hw->port_mib[p].state) { + hw_priv->counter[p].read = 1; + + /* Remember first port that requests read. */ + if (n == SWITCH_PORT_NUM) + n = p; + } + } + mutex_unlock(&hw_priv->lock); + + if (n < SWITCH_PORT_NUM) + schedule_work(&hw_priv->mib_read); + + if (1 == port->mib_port_cnt && n < SWITCH_PORT_NUM) { + p = n; + rc = wait_event_interruptible_timeout( + hw_priv->counter[p].counter, + 2 == hw_priv->counter[p].read, + HZ * 1); + } else + for (i = 0, p = n; i < port->mib_port_cnt - n; i++, p++) { + if (0 == i) { + rc = wait_event_interruptible_timeout( + hw_priv->counter[p].counter, + 2 == hw_priv->counter[p].read, + HZ * 2); + } else if (hw->port_mib[p].cnt_ptr) { + rc = wait_event_interruptible_timeout( + hw_priv->counter[p].counter, + 2 == hw_priv->counter[p].read, + HZ * 1); + } + } + + get_mib_counters(hw, port->first_port, port->mib_port_cnt, counter); + n = hw->mib_cnt; + if (n > n_stats) + n = n_stats; + n_stats -= n; + for (i = 0; i < n; i++) + *data++ = counter[i]; +} + +/** + * netdev_set_features - set receive checksum support + * @dev: Network device. + * @features: New device features (offloads). + * + * This function sets receive checksum support setting. + * + * Return 0 if successful; otherwise an error code. + */ +static int netdev_set_features(struct net_device *dev, u32 features) +{ + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + + mutex_lock(&hw_priv->lock); + + /* see note in hw_setup() */ + if (features & NETIF_F_RXCSUM) + hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP; + else + hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP); + + if (hw->enabled) + writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); + + mutex_unlock(&hw_priv->lock); + + return 0; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_drvinfo = netdev_get_drvinfo, + .get_regs_len = netdev_get_regs_len, + .get_regs = netdev_get_regs, + .get_wol = netdev_get_wol, + .set_wol = netdev_set_wol, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_eeprom_len = netdev_get_eeprom_len, + .get_eeprom = netdev_get_eeprom, + .set_eeprom = netdev_set_eeprom, + .get_pauseparam = netdev_get_pauseparam, + .set_pauseparam = netdev_set_pauseparam, + .get_ringparam = netdev_get_ringparam, + .get_strings = netdev_get_strings, + .get_sset_count = netdev_get_sset_count, + .get_ethtool_stats = netdev_get_ethtool_stats, +}; + +/* + * Hardware monitoring + */ + +static void update_link(struct net_device *dev, struct dev_priv *priv, + struct ksz_port *port) +{ + if (priv->media_state != port->linked->state) { + priv->media_state = port->linked->state; + if (netif_running(dev)) + set_media_state(dev, media_connected); + } +} + +static void mib_read_work(struct work_struct *work) +{ + struct dev_info *hw_priv = + container_of(work, struct dev_info, mib_read); + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port_mib *mib; + int i; + + next_jiffies = jiffies; + for (i = 0; i < hw->mib_port_cnt; i++) { + mib = &hw->port_mib[i]; + + /* Reading MIB counters or requested to read. */ + if (mib->cnt_ptr || 1 == hw_priv->counter[i].read) { + + /* Need to process receive interrupt. */ + if (port_r_cnt(hw, i)) + break; + hw_priv->counter[i].read = 0; + + /* Finish reading counters. */ + if (0 == mib->cnt_ptr) { + hw_priv->counter[i].read = 2; + wake_up_interruptible( + &hw_priv->counter[i].counter); + } + } else if (jiffies >= hw_priv->counter[i].time) { + /* Only read MIB counters when the port is connected. */ + if (media_connected == mib->state) + hw_priv->counter[i].read = 1; + next_jiffies += HZ * 1 * hw->mib_port_cnt; + hw_priv->counter[i].time = next_jiffies; + + /* Port is just disconnected. */ + } else if (mib->link_down) { + mib->link_down = 0; + + /* Read counters one last time after link is lost. */ + hw_priv->counter[i].read = 1; + } + } +} + +static void mib_monitor(unsigned long ptr) +{ + struct dev_info *hw_priv = (struct dev_info *) ptr; + + mib_read_work(&hw_priv->mib_read); + + /* This is used to verify Wake-on-LAN is working. */ + if (hw_priv->pme_wait) { + if (hw_priv->pme_wait <= jiffies) { + hw_clr_wol_pme_status(&hw_priv->hw); + hw_priv->pme_wait = 0; + } + } else if (hw_chk_wol_pme_status(&hw_priv->hw)) { + + /* PME is asserted. Wait 2 seconds to clear it. */ + hw_priv->pme_wait = jiffies + HZ * 2; + } + + ksz_update_timer(&hw_priv->mib_timer_info); +} + +/** + * dev_monitor - periodic monitoring + * @ptr: Network device pointer. + * + * This routine is run in a kernel timer to monitor the network device. + */ +static void dev_monitor(unsigned long ptr) +{ + struct net_device *dev = (struct net_device *) ptr; + struct dev_priv *priv = netdev_priv(dev); + struct dev_info *hw_priv = priv->adapter; + struct ksz_hw *hw = &hw_priv->hw; + struct ksz_port *port = &priv->port; + + if (!(hw->features & LINK_INT_WORKING)) + port_get_link_speed(port); + update_link(dev, priv, port); + + ksz_update_timer(&priv->monitor_timer_info); +} + +/* + * Linux network device interface functions + */ + +/* Driver exported variables */ + +static int msg_enable; + +static char *macaddr = ":"; +static char *mac1addr = ":"; + +/* + * This enables multiple network device mode for KSZ8842, which contains a + * switch with two physical ports. Some users like to take control of the + * ports for running Spanning Tree Protocol. The driver will create an + * additional eth? device for the other port. + * + * Some limitations are the network devices cannot have different MTU and + * multicast hash tables. + */ +static int multi_dev; + +/* + * As most users select multiple network device mode to use Spanning Tree + * Protocol, this enables a feature in which most unicast and multicast packets + * are forwarded inside the switch and not passed to the host. Only packets + * that need the host's attention are passed to it. This prevents the host + * wasting CPU time to examine each and every incoming packets and do the + * forwarding itself. + * + * As the hack requires the private bridge header, the driver cannot compile + * with just the kernel headers. + * + * Enabling STP support also turns on multiple network device mode. + */ +static int stp; + +/* + * This enables fast aging in the KSZ8842 switch. Not sure what situation + * needs that. However, fast aging is used to flush the dynamic MAC table when + * STP suport is enabled. + */ +static int fast_aging; + +/** + * netdev_init - initialize network device. + * @dev: Network device. + * + * This function initializes the network device. + * + * Return 0 if successful; otherwise an error code indicating failure. + */ +static int __init netdev_init(struct net_device *dev) +{ + struct dev_priv *priv = netdev_priv(dev); + + /* 500 ms timeout */ + ksz_init_timer(&priv->monitor_timer_info, 500 * HZ / 1000, + dev_monitor, dev); + + /* 500 ms timeout */ + dev->watchdog_timeo = HZ / 2; + + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; + + /* + * Hardware does not really support IPv6 checksum generation, but + * driver actually runs faster with this on. + */ + dev->hw_features |= NETIF_F_IPV6_CSUM; + + dev->features |= dev->hw_features; + + sema_init(&priv->proc_sem, 1); + + priv->mii_if.phy_id_mask = 0x1; + priv->mii_if.reg_num_mask = 0x7; + priv->mii_if.dev = dev; + priv->mii_if.mdio_read = mdio_read; + priv->mii_if.mdio_write = mdio_write; + priv->mii_if.phy_id = priv->port.first_port + 1; + + priv->msg_enable = netif_msg_init(msg_enable, + (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)); + + return 0; +} + +static const struct net_device_ops netdev_ops = { + .ndo_init = netdev_init, + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_get_stats = netdev_query_statistics, + .ndo_start_xmit = netdev_tx, + .ndo_tx_timeout = netdev_tx_timeout, + .ndo_change_mtu = netdev_change_mtu, + .ndo_set_features = netdev_set_features, + .ndo_set_mac_address = netdev_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = netdev_ioctl, + .ndo_set_rx_mode = netdev_set_rx_mode, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = netdev_netpoll, +#endif +}; + +static void netdev_free(struct net_device *dev) +{ + if (dev->watchdog_timeo) + unregister_netdev(dev); + + free_netdev(dev); +} + +struct platform_info { + struct dev_info dev_info; + struct net_device *netdev[SWITCH_PORT_NUM]; +}; + +static int net_device_present; + +static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) +{ + int i; + int j; + int got_num; + int num; + + i = j = num = got_num = 0; + while (j < MAC_ADDR_LEN) { + if (macaddr[i]) { + int digit; + + got_num = 1; + digit = hex_to_bin(macaddr[i]); + if (digit >= 0) + num = num * 16 + digit; + else if (':' == macaddr[i]) + got_num = 2; + else + break; + } else if (got_num) + got_num = 2; + else + break; + if (2 == got_num) { + if (MAIN_PORT == port) { + hw_priv->hw.override_addr[j++] = (u8) num; + hw_priv->hw.override_addr[5] += + hw_priv->hw.id; + } else { + hw_priv->hw.ksz_switch->other_addr[j++] = + (u8) num; + hw_priv->hw.ksz_switch->other_addr[5] += + hw_priv->hw.id; + } + num = got_num = 0; + } + i++; + } + if (MAC_ADDR_LEN == j) { + if (MAIN_PORT == port) + hw_priv->hw.mac_override = 1; + } +} + +#define KS884X_DMA_MASK (~0x0UL) + +static void read_other_addr(struct ksz_hw *hw) +{ + int i; + u16 data[3]; + struct ksz_switch *sw = hw->ksz_switch; + + for (i = 0; i < 3; i++) + data[i] = eeprom_read(hw, i + EEPROM_DATA_OTHER_MAC_ADDR); + if ((data[0] || data[1] || data[2]) && data[0] != 0xffff) { + sw->other_addr[5] = (u8) data[0]; + sw->other_addr[4] = (u8)(data[0] >> 8); + sw->other_addr[3] = (u8) data[1]; + sw->other_addr[2] = (u8)(data[1] >> 8); + sw->other_addr[1] = (u8) data[2]; + sw->other_addr[0] = (u8)(data[2] >> 8); + } +} + +#ifndef PCI_VENDOR_ID_MICREL_KS +#define PCI_VENDOR_ID_MICREL_KS 0x16c6 +#endif + +static int __devinit pcidev_init(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct net_device *dev; + struct dev_priv *priv; + struct dev_info *hw_priv; + struct ksz_hw *hw; + struct platform_info *info; + struct ksz_port *port; + unsigned long reg_base; + unsigned long reg_len; + int cnt; + int i; + int mib_port_count; + int pi; + int port_count; + int result; + char banner[sizeof(version)]; + struct ksz_switch *sw = NULL; + + result = pci_enable_device(pdev); + if (result) + return result; + + result = -ENODEV; + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) + return result; + + reg_base = pci_resource_start(pdev, 0); + reg_len = pci_resource_len(pdev, 0); + if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) + return result; + + if (!request_mem_region(reg_base, reg_len, DRV_NAME)) + return result; + pci_set_master(pdev); + + result = -ENOMEM; + + info = kzalloc(sizeof(struct platform_info), GFP_KERNEL); + if (!info) + goto pcidev_init_dev_err; + + hw_priv = &info->dev_info; + hw_priv->pdev = pdev; + + hw = &hw_priv->hw; + + hw->io = ioremap(reg_base, reg_len); + if (!hw->io) + goto pcidev_init_io_err; + + cnt = hw_init(hw); + if (!cnt) { + if (msg_enable & NETIF_MSG_PROBE) + pr_alert("chip not detected\n"); + result = -ENODEV; + goto pcidev_init_alloc_err; + } + + snprintf(banner, sizeof(banner), "%s", version); + banner[13] = cnt + '0'; /* Replace x in "Micrel KSZ884x" */ + dev_info(&hw_priv->pdev->dev, "%s\n", banner); + dev_dbg(&hw_priv->pdev->dev, "Mem = %p; IRQ = %d\n", hw->io, pdev->irq); + + /* Assume device is KSZ8841. */ + hw->dev_count = 1; + port_count = 1; + mib_port_count = 1; + hw->addr_list_size = 0; + hw->mib_cnt = PORT_COUNTER_NUM; + hw->mib_port_cnt = 1; + + /* KSZ8842 has a switch with multiple ports. */ + if (2 == cnt) { + if (fast_aging) + hw->overrides |= FAST_AGING; + + hw->mib_cnt = TOTAL_PORT_COUNTER_NUM; + + /* Multiple network device interfaces are required. */ + if (multi_dev) { + hw->dev_count = SWITCH_PORT_NUM; + hw->addr_list_size = SWITCH_PORT_NUM - 1; + } + + /* Single network device has multiple ports. */ + if (1 == hw->dev_count) { + port_count = SWITCH_PORT_NUM; + mib_port_count = SWITCH_PORT_NUM; + } + hw->mib_port_cnt = TOTAL_PORT_NUM; + hw->ksz_switch = kzalloc(sizeof(struct ksz_switch), GFP_KERNEL); + if (!hw->ksz_switch) + goto pcidev_init_alloc_err; + + sw = hw->ksz_switch; + } + for (i = 0; i < hw->mib_port_cnt; i++) + hw->port_mib[i].mib_start = 0; + + hw->parent = hw_priv; + + /* Default MTU is 1500. */ + hw_priv->mtu = (REGULAR_RX_BUF_SIZE + 3) & ~3; + + if (ksz_alloc_mem(hw_priv)) + goto pcidev_init_mem_err; + + hw_priv->hw.id = net_device_present; + + spin_lock_init(&hw_priv->hwlock); + mutex_init(&hw_priv->lock); + + /* tasklet is enabled. */ + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); + + /* tasklet_enable will decrement the atomic counter. */ + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); + + for (i = 0; i < TOTAL_PORT_NUM; i++) + init_waitqueue_head(&hw_priv->counter[i].counter); + + if (macaddr[0] != ':') + get_mac_addr(hw_priv, macaddr, MAIN_PORT); + + /* Read MAC address and initialize override address if not overrided. */ + hw_read_addr(hw); + + /* Multiple device interfaces mode requires a second MAC address. */ + if (hw->dev_count > 1) { + memcpy(sw->other_addr, hw->override_addr, MAC_ADDR_LEN); + read_other_addr(hw); + if (mac1addr[0] != ':') + get_mac_addr(hw_priv, mac1addr, OTHER_PORT); + } + + hw_setup(hw); + if (hw->ksz_switch) + sw_setup(hw); + else { + hw_priv->wol_support = WOL_SUPPORT; + hw_priv->wol_enable = 0; + } + + INIT_WORK(&hw_priv->mib_read, mib_read_work); + + /* 500 ms timeout */ + ksz_init_timer(&hw_priv->mib_timer_info, 500 * HZ / 1000, + mib_monitor, hw_priv); + + for (i = 0; i < hw->dev_count; i++) { + dev = alloc_etherdev(sizeof(struct dev_priv)); + if (!dev) + goto pcidev_init_reg_err; + info->netdev[i] = dev; + + priv = netdev_priv(dev); + priv->adapter = hw_priv; + priv->id = net_device_present++; + + port = &priv->port; + port->port_cnt = port_count; + port->mib_port_cnt = mib_port_count; + port->first_port = i; + port->flow_ctrl = PHY_FLOW_CTRL; + + port->hw = hw; + port->linked = &hw->port_info[port->first_port]; + + for (cnt = 0, pi = i; cnt < port_count; cnt++, pi++) { + hw->port_info[pi].port_id = pi; + hw->port_info[pi].pdev = dev; + hw->port_info[pi].state = media_disconnected; + } + + dev->mem_start = (unsigned long) hw->io; + dev->mem_end = dev->mem_start + reg_len - 1; + dev->irq = pdev->irq; + if (MAIN_PORT == i) + memcpy(dev->dev_addr, hw_priv->hw.override_addr, + MAC_ADDR_LEN); + else { + memcpy(dev->dev_addr, sw->other_addr, + MAC_ADDR_LEN); + if (!memcmp(sw->other_addr, hw->override_addr, + MAC_ADDR_LEN)) + dev->dev_addr[5] += port->first_port; + } + + dev->netdev_ops = &netdev_ops; + SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); + if (register_netdev(dev)) + goto pcidev_init_reg_err; + port_set_power_saving(port, true); + } + + pci_dev_get(hw_priv->pdev); + pci_set_drvdata(pdev, info); + return 0; + +pcidev_init_reg_err: + for (i = 0; i < hw->dev_count; i++) { + if (info->netdev[i]) { + netdev_free(info->netdev[i]); + info->netdev[i] = NULL; + } + } + +pcidev_init_mem_err: + ksz_free_mem(hw_priv); + kfree(hw->ksz_switch); + +pcidev_init_alloc_err: + iounmap(hw->io); + +pcidev_init_io_err: + kfree(info); + +pcidev_init_dev_err: + release_mem_region(reg_base, reg_len); + + return result; +} + +static void pcidev_exit(struct pci_dev *pdev) +{ + int i; + struct platform_info *info = pci_get_drvdata(pdev); + struct dev_info *hw_priv = &info->dev_info; + + pci_set_drvdata(pdev, NULL); + + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + for (i = 0; i < hw_priv->hw.dev_count; i++) { + if (info->netdev[i]) + netdev_free(info->netdev[i]); + } + if (hw_priv->hw.io) + iounmap(hw_priv->hw.io); + ksz_free_mem(hw_priv); + kfree(hw_priv->hw.ksz_switch); + pci_dev_put(hw_priv->pdev); + kfree(info); +} + +#ifdef CONFIG_PM +static int pcidev_resume(struct pci_dev *pdev) +{ + int i; + struct platform_info *info = pci_get_drvdata(pdev); + struct dev_info *hw_priv = &info->dev_info; + struct ksz_hw *hw = &hw_priv->hw; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_enable_wake(pdev, PCI_D0, 0); + + if (hw_priv->wol_enable) + hw_cfg_wol_pme(hw, 0); + for (i = 0; i < hw->dev_count; i++) { + if (info->netdev[i]) { + struct net_device *dev = info->netdev[i]; + + if (netif_running(dev)) { + netdev_open(dev); + netif_device_attach(dev); + } + } + } + return 0; +} + +static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int i; + struct platform_info *info = pci_get_drvdata(pdev); + struct dev_info *hw_priv = &info->dev_info; + struct ksz_hw *hw = &hw_priv->hw; + + /* Need to find a way to retrieve the device IP address. */ + static const u8 net_addr[] = { 192, 168, 1, 1 }; + + for (i = 0; i < hw->dev_count; i++) { + if (info->netdev[i]) { + struct net_device *dev = info->netdev[i]; + + if (netif_running(dev)) { + netif_device_detach(dev); + netdev_close(dev); + } + } + } + if (hw_priv->wol_enable) { + hw_enable_wol(hw, hw_priv->wol_enable, net_addr); + hw_cfg_wol_pme(hw, 1); + } + + pci_save_state(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return 0; +} +#endif + +static char pcidev_name[] = "ksz884xp"; + +static struct pci_device_id pcidev_table[] = { + { PCI_VENDOR_ID_MICREL_KS, 0x8841, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_MICREL_KS, 0x8842, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, pcidev_table); + +static struct pci_driver pci_device_driver = { +#ifdef CONFIG_PM + .suspend = pcidev_suspend, + .resume = pcidev_resume, +#endif + .name = pcidev_name, + .id_table = pcidev_table, + .probe = pcidev_init, + .remove = pcidev_exit +}; + +static int __init ksz884x_init_module(void) +{ + return pci_register_driver(&pci_device_driver); +} + +static void __exit ksz884x_cleanup_module(void) +{ + pci_unregister_driver(&pci_device_driver); +} + +module_init(ksz884x_init_module); +module_exit(ksz884x_cleanup_module); + +MODULE_DESCRIPTION("KSZ8841/2 PCI network driver"); +MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>"); +MODULE_LICENSE("GPL"); + +module_param_named(message, msg_enable, int, 0); +MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); + +module_param(macaddr, charp, 0); +module_param(mac1addr, charp, 0); +module_param(fast_aging, int, 0); +module_param(multi_dev, int, 0); +module_param(stp, int, 0); +MODULE_PARM_DESC(macaddr, "MAC address"); +MODULE_PARM_DESC(mac1addr, "Second MAC address"); +MODULE_PARM_DESC(fast_aging, "Fast aging"); +MODULE_PARM_DESC(multi_dev, "Multiple device interfaces"); +MODULE_PARM_DESC(stp, "STP support"); -- cgit v1.2.3 From afc4b13df143122f99a0eb10bfefb216c2806de0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko <jpirko@redhat.com> Date: Tue, 16 Aug 2011 06:29:01 +0000 Subject: net: remove use of ndo_set_multicast_list in drivers replace it by ndo_set_rx_mode Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- arch/ia64/hp/sim/simeth.c | 2 +- arch/um/drivers/net_kern.c | 2 +- arch/xtensa/platforms/iss/network.c | 2 +- drivers/infiniband/hw/nes/nes_nic.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 2 +- drivers/media/dvb/dvb-core/dvb_net.c | 2 +- drivers/net/appletalk/cops.c | 2 +- drivers/net/appletalk/ltpc.c | 2 +- drivers/net/arcnet/com20020.c | 2 +- drivers/net/bonding/bond_main.c | 2 +- drivers/net/cris/eth_v10.c | 2 +- drivers/net/defxx.c | 2 +- drivers/net/dummy.c | 2 +- drivers/net/ethernet/3com/3c501.c | 2 +- drivers/net/ethernet/3com/3c509.c | 2 +- drivers/net/ethernet/3com/3c515.c | 2 +- drivers/net/ethernet/3com/3c574_cs.c | 2 +- drivers/net/ethernet/3com/3c589_cs.c | 2 +- drivers/net/ethernet/3com/3c59x.c | 4 ++-- drivers/net/ethernet/3com/typhoon.c | 2 +- drivers/net/ethernet/8390/3c503.c | 2 +- drivers/net/ethernet/8390/8390.c | 2 +- drivers/net/ethernet/8390/8390p.c | 2 +- drivers/net/ethernet/8390/ac3200.c | 2 +- drivers/net/ethernet/8390/ax88796.c | 2 +- drivers/net/ethernet/8390/axnet_cs.c | 2 +- drivers/net/ethernet/8390/e2100.c | 2 +- drivers/net/ethernet/8390/etherh.c | 2 +- drivers/net/ethernet/8390/hp-plus.c | 2 +- drivers/net/ethernet/8390/hydra.c | 2 +- drivers/net/ethernet/8390/mac8390.c | 2 +- drivers/net/ethernet/8390/ne-h8300.c | 2 +- drivers/net/ethernet/8390/ne2k-pci.c | 2 +- drivers/net/ethernet/8390/pcnet_cs.c | 2 +- drivers/net/ethernet/8390/smc-mca.c | 2 +- drivers/net/ethernet/8390/smc-ultra.c | 2 +- drivers/net/ethernet/8390/smc-ultra32.c | 2 +- drivers/net/ethernet/8390/wd.c | 2 +- drivers/net/ethernet/8390/zorro8390.c | 2 +- drivers/net/ethernet/adaptec/starfire.c | 2 +- drivers/net/ethernet/adi/bfin_mac.c | 2 +- drivers/net/ethernet/aeroflex/greth.c | 2 +- drivers/net/ethernet/alteon/acenic.c | 2 +- drivers/net/ethernet/amd/a2065.c | 2 +- drivers/net/ethernet/amd/am79c961a.c | 2 +- drivers/net/ethernet/amd/amd8111e.c | 2 +- drivers/net/ethernet/amd/ariadne.c | 2 +- drivers/net/ethernet/amd/atarilance.c | 2 +- drivers/net/ethernet/amd/au1000_eth.c | 2 +- drivers/net/ethernet/amd/declance.c | 2 +- drivers/net/ethernet/amd/depca.c | 2 +- drivers/net/ethernet/amd/hplance.c | 2 +- drivers/net/ethernet/amd/lance.c | 2 +- drivers/net/ethernet/amd/mvme147.c | 2 +- drivers/net/ethernet/amd/ni65.c | 2 +- drivers/net/ethernet/amd/nmclan_cs.c | 2 +- drivers/net/ethernet/amd/pcnet32.c | 2 +- drivers/net/ethernet/amd/sun3lance.c | 2 +- drivers/net/ethernet/amd/sunlance.c | 2 +- drivers/net/ethernet/apple/bmac.c | 2 +- drivers/net/ethernet/apple/cs89x0.c | 2 +- drivers/net/ethernet/apple/mac89x0.c | 2 +- drivers/net/ethernet/apple/mace.c | 2 +- drivers/net/ethernet/apple/macmace.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 2 +- drivers/net/ethernet/atheros/atlx/atl1.c | 2 +- drivers/net/ethernet/atheros/atlx/atl2.c | 2 +- drivers/net/ethernet/broadcom/b44.c | 2 +- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 +- drivers/net/ethernet/broadcom/sb1250-mac.c | 2 +- drivers/net/ethernet/broadcom/tg3.c | 2 +- drivers/net/ethernet/brocade/bna/bnad.c | 1 - drivers/net/ethernet/cadence/at91_ether.c | 2 +- drivers/net/ethernet/cadence/macb.c | 2 +- drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 2 +- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 2 +- drivers/net/ethernet/cisco/enic/enic_main.c | 2 -- drivers/net/ethernet/davicom/dm9000.c | 2 +- drivers/net/ethernet/dec/ewrk3.c | 2 +- drivers/net/ethernet/dec/tulip/de2104x.c | 2 +- drivers/net/ethernet/dec/tulip/de4x5.c | 2 +- drivers/net/ethernet/dec/tulip/dmfe.c | 2 +- drivers/net/ethernet/dec/tulip/tulip_core.c | 2 +- drivers/net/ethernet/dec/tulip/uli526x.c | 2 +- drivers/net/ethernet/dec/tulip/winbond-840.c | 2 +- drivers/net/ethernet/dlink/de620.c | 2 +- drivers/net/ethernet/dlink/dl2k.c | 2 +- drivers/net/ethernet/dlink/sundance.c | 2 +- drivers/net/ethernet/ethoc.c | 2 +- drivers/net/ethernet/fealnx.c | 2 +- drivers/net/ethernet/freescale/fec.c | 2 +- drivers/net/ethernet/freescale/fec_mpc52xx.c | 2 +- drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 2 +- drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/net/ethernet/freescale/ucc_geth.c | 2 +- drivers/net/ethernet/fujitsu/at1700.c | 2 +- drivers/net/ethernet/fujitsu/eth16i.c | 2 +- drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 2 +- drivers/net/ethernet/hp/hp100.c | 4 ++-- drivers/net/ethernet/i825xx/3c505.c | 2 +- drivers/net/ethernet/i825xx/3c523.c | 2 +- drivers/net/ethernet/i825xx/3c527.c | 2 +- drivers/net/ethernet/i825xx/82596.c | 2 +- drivers/net/ethernet/i825xx/eepro.c | 2 +- drivers/net/ethernet/i825xx/eexpress.c | 2 +- drivers/net/ethernet/i825xx/ether1.c | 2 +- drivers/net/ethernet/i825xx/lib82596.c | 2 +- drivers/net/ethernet/i825xx/lp486e.c | 2 +- drivers/net/ethernet/i825xx/ni52.c | 2 +- drivers/net/ethernet/i825xx/sun3_82586.c | 2 +- drivers/net/ethernet/i825xx/znet.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +- drivers/net/ethernet/ibm/emac/core.c | 4 ++-- drivers/net/ethernet/ibm/ibmveth.c | 2 +- drivers/net/ethernet/ibm/iseries_veth.c | 2 +- drivers/net/ethernet/icplus/ipg.c | 2 +- drivers/net/ethernet/intel/e100.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 1 - drivers/net/ethernet/intel/igbvf/netdev.c | 2 +- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 - drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 - drivers/net/ethernet/jme.c | 2 +- drivers/net/ethernet/korina.c | 2 +- drivers/net/ethernet/lantiq_etop.c | 2 +- drivers/net/ethernet/marvell/skge.c | 2 +- drivers/net/ethernet/marvell/sky2.c | 4 ++-- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +- drivers/net/ethernet/micrel/ks8695net.c | 2 +- drivers/net/ethernet/microchip/enc28j60.c | 2 +- drivers/net/ethernet/mipsnet.c | 2 +- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 2 +- drivers/net/ethernet/natsemi/ibmlana.c | 2 +- drivers/net/ethernet/natsemi/jazzsonic.c | 2 +- drivers/net/ethernet/natsemi/macsonic.c | 2 +- drivers/net/ethernet/natsemi/natsemi.c | 2 +- drivers/net/ethernet/natsemi/ns83820.c | 2 +- drivers/net/ethernet/natsemi/xtsonic.c | 2 +- drivers/net/ethernet/neterion/s2io.c | 2 +- drivers/net/ethernet/neterion/vxge/vxge-main.c | 2 +- drivers/net/ethernet/netx-eth.c | 2 +- drivers/net/ethernet/nuvoton/w90p910_ether.c | 2 +- drivers/net/ethernet/nvidia/forcedeth.c | 4 ++-- drivers/net/ethernet/octeon/octeon_mgmt.c | 1 - drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 2 +- drivers/net/ethernet/packetengines/hamachi.c | 2 +- drivers/net/ethernet/packetengines/yellowfin.c | 2 +- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 +- drivers/net/ethernet/qlogic/qla3xxx.c | 1 - drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 2 +- drivers/net/ethernet/racal/ni5010.c | 2 +- drivers/net/ethernet/rdc/r6040.c | 2 +- drivers/net/ethernet/realtek/8139cp.c | 2 +- drivers/net/ethernet/realtek/8139too.c | 2 +- drivers/net/ethernet/realtek/atp.c | 2 +- drivers/net/ethernet/realtek/r8169.c | 2 +- drivers/net/ethernet/realtek/sc92031.c | 2 +- drivers/net/ethernet/renesas/sh_eth.c | 2 +- drivers/net/ethernet/seeq/ether3.c | 2 +- drivers/net/ethernet/seeq/seeq8005.c | 2 +- drivers/net/ethernet/seeq/sgiseeq.c | 2 +- drivers/net/ethernet/sfc/efx.c | 2 +- drivers/net/ethernet/sgi/ioc3-eth.c | 2 +- drivers/net/ethernet/sis/sis190.c | 2 +- drivers/net/ethernet/sis/sis900.c | 2 +- drivers/net/ethernet/smsc/epic100.c | 2 +- drivers/net/ethernet/smsc/smc911x.c | 2 +- drivers/net/ethernet/smsc/smc9194.c | 2 +- drivers/net/ethernet/smsc/smc91c92_cs.c | 2 +- drivers/net/ethernet/smsc/smc91x.c | 2 +- drivers/net/ethernet/smsc/smsc911x.c | 2 +- drivers/net/ethernet/smsc/smsc9420.c | 2 +- drivers/net/ethernet/sun/cassini.c | 2 +- drivers/net/ethernet/sun/sunbmac.c | 2 +- drivers/net/ethernet/sun/sungem.c | 2 +- drivers/net/ethernet/sun/sunhme.c | 2 +- drivers/net/ethernet/sun/sunqe.c | 2 +- drivers/net/ethernet/sun/sunvnet.c | 2 +- drivers/net/ethernet/tehuti/tehuti.c | 2 +- drivers/net/ethernet/ti/cpmac.c | 2 +- drivers/net/ethernet/ti/davinci_emac.c | 2 +- drivers/net/ethernet/ti/tlan.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 2 +- drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 2 +- drivers/net/ethernet/toshiba/spider_net.c | 2 +- drivers/net/ethernet/toshiba/tc35815.c | 2 +- drivers/net/ethernet/tundra/tsi108_eth.c | 2 +- drivers/net/ethernet/via/via-rhine.c | 2 +- drivers/net/ethernet/via/via-velocity.c | 2 +- drivers/net/ethernet/xilinx/ll_temac_main.c | 1 - drivers/net/ethernet/xircom/xirc2ps_cs.c | 2 +- drivers/net/ethernet/xscale/ixp4xx_eth.c | 2 +- drivers/net/macvlan.c | 2 +- drivers/net/skfp/skfddi.c | 2 +- drivers/net/tokenring/3c359.c | 2 +- drivers/net/tokenring/ibmtr.c | 2 +- drivers/net/tokenring/lanstreamer.c | 2 +- drivers/net/tokenring/olympic.c | 2 +- drivers/net/tokenring/smctr.c | 2 +- drivers/net/tokenring/tms380tr.c | 2 +- drivers/net/tun.c | 2 +- drivers/net/usb/asix.c | 6 +++--- drivers/net/usb/catc.c | 2 +- drivers/net/usb/dm9601.c | 2 +- drivers/net/usb/int51x1.c | 2 +- drivers/net/usb/kaweth.c | 2 +- drivers/net/usb/mcs7830.c | 2 +- drivers/net/usb/pegasus.c | 2 +- drivers/net/usb/rtl8150.c | 2 +- drivers/net/usb/smsc75xx.c | 2 +- drivers/net/usb/smsc95xx.c | 2 +- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- drivers/net/wan/sbni.c | 2 +- drivers/net/wireless/airo.c | 4 ++-- drivers/net/wireless/hostap/hostap_main.c | 6 +++--- drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- drivers/net/wireless/libertas/main.c | 2 +- drivers/net/wireless/libertas/mesh.c | 2 +- drivers/net/wireless/mwifiex/main.c | 2 +- drivers/net/wireless/orinoco/main.c | 2 +- drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- drivers/net/wireless/ray_cs.c | 2 +- drivers/net/wireless/rndis_wlan.c | 2 +- drivers/net/wireless/zd1201.c | 2 +- drivers/s390/net/lcs.c | 2 +- drivers/s390/net/qeth_l2_main.c | 2 +- drivers/s390/net/qeth_l3_main.c | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/et131x/et131x_netdev.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/octeon/ethernet.c | 12 ++++++------ drivers/staging/rtl8187se/r8180_core.c | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 2 +- drivers/staging/rtl8192u/r8192U_core.c | 2 +- drivers/staging/slicoss/slicoss.c | 2 +- drivers/staging/vt6655/device_main.c | 2 +- drivers/staging/vt6656/main_usb.c | 2 +- drivers/staging/wlags49_h2/wl_netdev.c | 2 +- drivers/staging/wlan-ng/p80211netdev.c | 2 +- net/8021q/vlan_dev.c | 1 - net/atm/lec.c | 2 +- net/bluetooth/bnep/netdev.c | 2 +- net/bridge/br_device.c | 2 +- net/dsa/slave.c | 3 --- net/irda/irlan/irlan_eth.c | 2 +- net/mac80211/iface.c | 4 ++-- 251 files changed, 258 insertions(+), 271 deletions(-) (limited to 'drivers/net/ethernet/micrel') diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 7e81966ce481..47afcc61f6e5 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -172,7 +172,7 @@ static const struct net_device_ops simeth_netdev_ops = { .ndo_stop = simeth_close, .ndo_start_xmit = simeth_tx, .ndo_get_stats = simeth_get_stats, - .ndo_set_multicast_list = set_multicast_list, /* not yet used */ + .ndo_set_rx_mode = set_multicast_list, /* not yet used */ }; diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 22745b47c829..a492e59883a3 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -368,7 +368,7 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_open = uml_net_open, .ndo_stop = uml_net_close, .ndo_start_xmit = uml_net_start_xmit, - .ndo_set_multicast_list = uml_net_set_multicast_list, + .ndo_set_rx_mode = uml_net_set_multicast_list, .ndo_tx_timeout = uml_net_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index f717e20d961b..7dde24456427 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -633,7 +633,7 @@ static const struct net_device_ops iss_netdev_ops = { .ndo_set_mac_address = iss_net_set_mac, //.ndo_do_ioctl = iss_net_ioctl, .ndo_tx_timeout = iss_net_tx_timeout, - .ndo_set_multicast_list = iss_net_set_multicast_list, + .ndo_set_rx_mode = iss_net_set_multicast_list, }; static int iss_net_configure(int index, char *init) diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 9d7ffebff213..66e12298d917 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1638,7 +1638,7 @@ static const struct net_device_ops nes_netdev_ops = { .ndo_get_stats = nes_netdev_get_stats, .ndo_tx_timeout = nes_netdev_tx_timeout, .ndo_set_mac_address = nes_netdev_set_mac_address, - .ndo_set_multicast_list = nes_netdev_set_multicast_list, + .ndo_set_rx_mode = nes_netdev_set_multicast_list, .ndo_change_mtu = nes_netdev_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_fix_features = nes_fix_features, diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 43f89ba0a908..aa30915c71ea 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -996,7 +996,7 @@ static const struct net_device_ops ipoib_netdev_ops = { .ndo_fix_features = ipoib_fix_features, .ndo_start_xmit = ipoib_start_xmit, .ndo_tx_timeout = ipoib_timeout, - .ndo_set_multicast_list = ipoib_set_mcast_list, + .ndo_set_rx_mode = ipoib_set_mcast_list, .ndo_neigh_setup = ipoib_neigh_setup_dev, }; diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 51752a9ef7a4..93d9869e0f15 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1230,7 +1230,7 @@ static const struct net_device_ops dvb_netdev_ops = { .ndo_open = dvb_net_open, .ndo_stop = dvb_net_stop, .ndo_start_xmit = dvb_net_tx, - .ndo_set_multicast_list = dvb_net_set_multicast_list, + .ndo_set_rx_mode = dvb_net_set_multicast_list, .ndo_set_mac_address = dvb_net_set_mac, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 748c9f526e71..9abd4eb86dc1 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -264,7 +264,7 @@ static const struct net_device_ops cops_netdev_ops = { .ndo_start_xmit = cops_send_packet, .ndo_tx_timeout = cops_timeout, .ndo_do_ioctl = cops_ioctl, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, }; /* diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 34ffb5422628..6057b30417a2 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1014,7 +1014,7 @@ static int __init ltpc_probe_dma(int base, int dma) static const struct net_device_ops ltpc_netdev = { .ndo_start_xmit = ltpc_xmit, .ndo_do_ioctl = ltpc_ioctl, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, }; struct net_device * __init ltpc_probe(void) diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 7bfb91f32857..7b96c5f47e8d 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -154,7 +154,7 @@ const struct net_device_ops com20020_netdev_ops = { .ndo_stop = arcnet_close, .ndo_start_xmit = arcnet_send_packet, .ndo_tx_timeout = arcnet_timeout, - .ndo_set_multicast_list = com20020_set_mc_list, + .ndo_set_rx_mode = com20020_set_mc_list, }; /* Set up the struct net_device associated with this card. Called after diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c3e46832599e..e61a4e573536 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4266,7 +4266,7 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_get_stats64 = bond_get_stats, .ndo_do_ioctl = bond_do_ioctl, .ndo_change_rx_flags = bond_change_rx_flags, - .ndo_set_multicast_list = bond_set_multicast_list, + .ndo_set_rx_mode = bond_set_multicast_list, .ndo_change_mtu = bond_change_mtu, .ndo_set_mac_address = bond_set_mac_address, .ndo_neigh_setup = bond_neigh_setup, diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index e66aceb57cef..7cb2785e209d 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -261,7 +261,7 @@ static const struct net_device_ops e100_netdev_ops = { .ndo_start_xmit = e100_send_packet, .ndo_tx_timeout = e100_tx_timeout, .ndo_get_stats = e100_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_do_ioctl = e100_ioctl, .ndo_set_mac_address = e100_set_mac_address, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index 417e14385623..4ad80f771099 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -483,7 +483,7 @@ static const struct net_device_ops dfx_netdev_ops = { .ndo_stop = dfx_close, .ndo_start_xmit = dfx_xmt_queue_pkt, .ndo_get_stats = dfx_ctl_get_stats, - .ndo_set_multicast_list = dfx_ctl_set_multicast_list, + .ndo_set_rx_mode = dfx_ctl_set_multicast_list, .ndo_set_mac_address = dfx_ctl_set_mac_address, }; diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 39cf9b9bd673..a7c5e8831e8c 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -116,7 +116,7 @@ static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_set_mac_address = dummy_set_address, .ndo_get_stats64 = dummy_get_stats64, }; diff --git a/drivers/net/ethernet/3com/3c501.c b/drivers/net/ethernet/3com/3c501.c index 5420f6de27df..68da81d476f3 100644 --- a/drivers/net/ethernet/3com/3c501.c +++ b/drivers/net/ethernet/3com/3c501.c @@ -201,7 +201,7 @@ static const struct net_device_ops el_netdev_ops = { .ndo_stop = el1_close, .ndo_start_xmit = el_start_xmit, .ndo_tx_timeout = el_timeout, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c index 44b28b2d7003..92053e6fc980 100644 --- a/drivers/net/ethernet/3com/3c509.c +++ b/drivers/net/ethernet/3com/3c509.c @@ -545,7 +545,7 @@ static const struct net_device_ops netdev_ops = { .ndo_stop = el3_close, .ndo_start_xmit = el3_start_xmit, .ndo_get_stats = el3_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = el3_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/3com/3c515.c b/drivers/net/ethernet/3com/3c515.c index d2bb4b254c57..f67a5d3a200c 100644 --- a/drivers/net/ethernet/3com/3c515.c +++ b/drivers/net/ethernet/3com/3c515.c @@ -569,7 +569,7 @@ static const struct net_device_ops netdev_ops = { .ndo_start_xmit = corkscrew_start_xmit, .ndo_tx_timeout = corkscrew_timeout, .ndo_get_stats = corkscrew_get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c index 34c5e1cbf65d..9c01bc9235b3 100644 --- a/drivers/net/ethernet/3com/3c574_cs.c +++ b/drivers/net/ethernet/3com/3c574_cs.c @@ -255,7 +255,7 @@ static const struct net_device_ops el3_netdev_ops = { .ndo_tx_timeout = el3_tx_timeout, .ndo_get_stats = el3_get_stats, .ndo_do_ioctl = el3_ioctl, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c index 4a1a35809807..972f80ecc510 100644 --- a/drivers/net/ethernet/3com/3c589_cs.c +++ b/drivers/net/ethernet/3com/3c589_cs.c @@ -184,7 +184,7 @@ static const struct net_device_ops el3_netdev_ops = { .ndo_tx_timeout = el3_tx_timeout, .ndo_set_config = el3_config, .ndo_get_stats = el3_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 8cc22568ebd3..6e1f5959a654 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1055,7 +1055,7 @@ static const struct net_device_ops boomrang_netdev_ops = { #ifdef CONFIG_PCI .ndo_do_ioctl = vortex_ioctl, #endif - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -1073,7 +1073,7 @@ static const struct net_device_ops vortex_netdev_ops = { #ifdef CONFIG_PCI .ndo_do_ioctl = vortex_ioctl, #endif - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index 1d5091a1e49a..f1dc9acf6105 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -2266,7 +2266,7 @@ static const struct net_device_ops typhoon_netdev_ops = { .ndo_open = typhoon_open, .ndo_stop = typhoon_close, .ndo_start_xmit = typhoon_start_tx, - .ndo_set_multicast_list = typhoon_set_rx_mode, + .ndo_set_rx_mode = typhoon_set_rx_mode, .ndo_tx_timeout = typhoon_tx_timeout, .ndo_get_stats = typhoon_get_stats, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/8390/3c503.c b/drivers/net/ethernet/8390/3c503.c index 84e68f1b9adf..fbab1367505f 100644 --- a/drivers/net/ethernet/8390/3c503.c +++ b/drivers/net/ethernet/8390/3c503.c @@ -176,7 +176,7 @@ static const struct net_device_ops el2_netdev_ops = { .ndo_start_xmit = eip_start_xmit, .ndo_tx_timeout = eip_tx_timeout, .ndo_get_stats = eip_get_stats, - .ndo_set_multicast_list = eip_set_multicast_list, + .ndo_set_rx_mode = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/8390.c b/drivers/net/ethernet/8390/8390.c index 7c7518be1756..5db1f55abef4 100644 --- a/drivers/net/ethernet/8390/8390.c +++ b/drivers/net/ethernet/8390/8390.c @@ -61,7 +61,7 @@ const struct net_device_ops ei_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/8390p.c b/drivers/net/ethernet/8390/8390p.c index a2a64ea0b691..e8fc2e87e840 100644 --- a/drivers/net/ethernet/8390/8390p.c +++ b/drivers/net/ethernet/8390/8390p.c @@ -66,7 +66,7 @@ const struct net_device_ops eip_netdev_ops = { .ndo_start_xmit = eip_start_xmit, .ndo_tx_timeout = eip_tx_timeout, .ndo_get_stats = eip_get_stats, - .ndo_set_multicast_list = eip_set_multicast_list, + .ndo_set_rx_mode = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/ac3200.c b/drivers/net/ethernet/8390/ac3200.c index f07b2e980fbc..5337dd0a59b0 100644 --- a/drivers/net/ethernet/8390/ac3200.c +++ b/drivers/net/ethernet/8390/ac3200.c @@ -151,7 +151,7 @@ static const struct net_device_ops ac_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index e7cb8c8b9776..e9f8432f55b4 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -543,7 +543,7 @@ static const struct net_device_ops ax_netdev_ops = { .ndo_start_xmit = ax_ei_start_xmit, .ndo_tx_timeout = ax_ei_tx_timeout, .ndo_get_stats = ax_ei_get_stats, - .ndo_set_multicast_list = ax_ei_set_multicast_list, + .ndo_set_rx_mode = ax_ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c index 3e4b926c30dc..bba51cdc74a1 100644 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ b/drivers/net/ethernet/8390/axnet_cs.c @@ -134,7 +134,7 @@ static const struct net_device_ops axnet_netdev_ops = { .ndo_start_xmit = axnet_start_xmit, .ndo_tx_timeout = axnet_tx_timeout, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/8390/e2100.c b/drivers/net/ethernet/8390/e2100.c index d50a9998ae77..d16dc53c1813 100644 --- a/drivers/net/ethernet/8390/e2100.c +++ b/drivers/net/ethernet/8390/e2100.c @@ -168,7 +168,7 @@ static const struct net_device_ops e21_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c index cf851faef311..48c4948750d1 100644 --- a/drivers/net/ethernet/8390/etherh.c +++ b/drivers/net/ethernet/8390/etherh.c @@ -644,7 +644,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_start_xmit = __ei_start_xmit, .ndo_tx_timeout = __ei_tx_timeout, .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_set_rx_mode = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/hp-plus.c b/drivers/net/ethernet/8390/hp-plus.c index 29917363ebfb..eeac843dcd2d 100644 --- a/drivers/net/ethernet/8390/hp-plus.c +++ b/drivers/net/ethernet/8390/hp-plus.c @@ -165,7 +165,7 @@ static const struct net_device_ops hpp_netdev_ops = { .ndo_start_xmit = eip_start_xmit, .ndo_tx_timeout = eip_tx_timeout, .ndo_get_stats = eip_get_stats, - .ndo_set_multicast_list = eip_set_multicast_list, + .ndo_set_rx_mode = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/hydra.c b/drivers/net/ethernet/8390/hydra.c index 1cd481c04202..3dac937a67c4 100644 --- a/drivers/net/ethernet/8390/hydra.c +++ b/drivers/net/ethernet/8390/hydra.c @@ -101,7 +101,7 @@ static const struct net_device_ops hydra_netdev_ops = { .ndo_start_xmit = __ei_start_xmit, .ndo_tx_timeout = __ei_tx_timeout, .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_set_rx_mode = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c index f84f5e6ededb..af5d9822cad9 100644 --- a/drivers/net/ethernet/8390/mac8390.c +++ b/drivers/net/ethernet/8390/mac8390.c @@ -494,7 +494,7 @@ static const struct net_device_ops mac8390_netdev_ops = { .ndo_start_xmit = __ei_start_xmit, .ndo_tx_timeout = __ei_tx_timeout, .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_set_rx_mode = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/ne-h8300.c b/drivers/net/ethernet/8390/ne-h8300.c index 7298a34bc795..cd36a6a5f408 100644 --- a/drivers/net/ethernet/8390/ne-h8300.c +++ b/drivers/net/ethernet/8390/ne-h8300.c @@ -200,7 +200,7 @@ static const struct net_device_ops ne_netdev_ops = { .ndo_start_xmit = __ei_start_xmit, .ndo_tx_timeout = __ei_tx_timeout, .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_set_rx_mode = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c index 3c333cb5d34e..39923425ba25 100644 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ b/drivers/net/ethernet/8390/ne2k-pci.c @@ -207,7 +207,7 @@ static const struct net_device_ops ne2k_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c index 40107614b5dc..053b2551a72d 100644 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ b/drivers/net/ethernet/8390/pcnet_cs.c @@ -227,7 +227,7 @@ static const struct net_device_ops pcnet_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_get_stats = ei_get_stats, .ndo_do_ioctl = ei_ioctl, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_tx_timeout = ei_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/8390/smc-mca.c b/drivers/net/ethernet/8390/smc-mca.c index 34934fb23b97..77efec44fea0 100644 --- a/drivers/net/ethernet/8390/smc-mca.c +++ b/drivers/net/ethernet/8390/smc-mca.c @@ -191,7 +191,7 @@ static const struct net_device_ops ultramca_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/smc-ultra.c b/drivers/net/ethernet/8390/smc-ultra.c index ba44ede29198..1cc306a83ff7 100644 --- a/drivers/net/ethernet/8390/smc-ultra.c +++ b/drivers/net/ethernet/8390/smc-ultra.c @@ -192,7 +192,7 @@ static const struct net_device_ops ultra_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/smc-ultra32.c b/drivers/net/ethernet/8390/smc-ultra32.c index e459c3b2510a..bb87053eb3da 100644 --- a/drivers/net/ethernet/8390/smc-ultra32.c +++ b/drivers/net/ethernet/8390/smc-ultra32.c @@ -160,7 +160,7 @@ static const struct net_device_ops ultra32_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/wd.c b/drivers/net/ethernet/8390/wd.c index 8831a3393ecf..c175fadb597b 100644 --- a/drivers/net/ethernet/8390/wd.c +++ b/drivers/net/ethernet/8390/wd.c @@ -153,7 +153,7 @@ static const struct net_device_ops wd_netdev_ops = { .ndo_start_xmit = ei_start_xmit, .ndo_tx_timeout = ei_tx_timeout, .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_set_rx_mode = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c index 15e7751a273c..3aa9fe9999b5 100644 --- a/drivers/net/ethernet/8390/zorro8390.c +++ b/drivers/net/ethernet/8390/zorro8390.c @@ -278,7 +278,7 @@ static const struct net_device_ops zorro8390_netdev_ops = { .ndo_start_xmit = __ei_start_xmit, .ndo_tx_timeout = __ei_tx_timeout, .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_set_rx_mode = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index 7ae1f990a98e..df51fdd72353 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c @@ -639,7 +639,7 @@ static const struct net_device_ops netdev_ops = { .ndo_start_xmit = start_tx, .ndo_tx_timeout = tx_timeout, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = &set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = netdev_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index 6c019e148546..b6d69c91db96 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -1449,7 +1449,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = { .ndo_start_xmit = bfin_mac_hard_start_xmit, .ndo_set_mac_address = bfin_mac_set_mac_address, .ndo_tx_timeout = bfin_mac_timeout, - .ndo_set_multicast_list = bfin_mac_set_multicast_list, + .ndo_set_rx_mode = bfin_mac_set_multicast_list, .ndo_do_ioctl = bfin_mac_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 16ce45c11934..a5f6b07f8f3e 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1539,7 +1539,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev) } if (greth->multicast) { - greth_netdev_ops.ndo_set_multicast_list = greth_set_multicast_list; + greth_netdev_ops.ndo_set_rx_mode = greth_set_multicast_list; dev->flags |= IFF_MULTICAST; } else { dev->flags &= ~IFF_MULTICAST; diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index 31798f5f5d06..1d6f2db794fd 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -449,7 +449,7 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_tx_timeout = ace_watchdog, .ndo_get_stats = ace_get_stats, .ndo_start_xmit = ace_start_xmit, - .ndo_set_multicast_list = ace_set_multicast_list, + .ndo_set_rx_mode = ace_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ace_set_mac_addr, .ndo_change_mtu = ace_change_mtu, diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c index e1e1b07d9b8d..825e5d4ef4c3 100644 --- a/drivers/net/ethernet/amd/a2065.c +++ b/drivers/net/ethernet/amd/a2065.c @@ -664,7 +664,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_stop = lance_close, .ndo_start_xmit = lance_start_xmit, .ndo_tx_timeout = lance_tx_timeout, - .ndo_set_multicast_list = lance_set_multicast, + .ndo_set_rx_mode = lance_set_multicast, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c index 52fe21e1e2cd..c2b630c5e852 100644 --- a/drivers/net/ethernet/amd/am79c961a.c +++ b/drivers/net/ethernet/amd/am79c961a.c @@ -659,7 +659,7 @@ static const struct net_device_ops am79c961_netdev_ops = { .ndo_open = am79c961_open, .ndo_stop = am79c961_close, .ndo_start_xmit = am79c961_sendpacket, - .ndo_set_multicast_list = am79c961_setmulticastlist, + .ndo_set_rx_mode = am79c961_setmulticastlist, .ndo_tx_timeout = am79c961_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index 78002ef9c0e5..a9745f4ddbfe 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -1798,7 +1798,7 @@ static const struct net_device_ops amd8111e_netdev_ops = { .ndo_start_xmit = amd8111e_start_xmit, .ndo_tx_timeout = amd8111e_tx_timeout, .ndo_get_stats = amd8111e_get_stats, - .ndo_set_multicast_list = amd8111e_set_multicast_list, + .ndo_set_rx_mode = amd8111e_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = amd8111e_set_mac_address, .ndo_do_ioctl = amd8111e_ioctl, diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c index 7ed78f402042..eb18e1fe65c8 100644 --- a/drivers/net/ethernet/amd/ariadne.c +++ b/drivers/net/ethernet/amd/ariadne.c @@ -704,7 +704,7 @@ static const struct net_device_ops ariadne_netdev_ops = { .ndo_start_xmit = ariadne_start_xmit, .ndo_tx_timeout = ariadne_tx_timeout, .ndo_get_stats = ariadne_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index 1264d781b554..15bfa28d6c53 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -456,7 +456,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_open = lance_open, .ndo_stop = lance_close, .ndo_start_xmit = lance_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_set_mac_address = lance_set_mac_address, .ndo_tx_timeout = lance_tx_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index b9debcfb61a0..82386677bb8c 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -1010,7 +1010,7 @@ static const struct net_device_ops au1000_netdev_ops = { .ndo_open = au1000_open, .ndo_stop = au1000_close, .ndo_start_xmit = au1000_tx, - .ndo_set_multicast_list = au1000_multicast_list, + .ndo_set_rx_mode = au1000_multicast_list, .ndo_do_ioctl = au1000_ioctl, .ndo_tx_timeout = au1000_tx_timeout, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index d5598f6584a3..73f8d4fa682d 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -1015,7 +1015,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_stop = lance_close, .ndo_start_xmit = lance_start_xmit, .ndo_tx_timeout = lance_tx_timeout, - .ndo_set_multicast_list = lance_set_multicast, + .ndo_set_rx_mode = lance_set_multicast, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c index f2015a851977..681970c07f22 100644 --- a/drivers/net/ethernet/amd/depca.c +++ b/drivers/net/ethernet/amd/depca.c @@ -572,7 +572,7 @@ static const struct net_device_ops depca_netdev_ops = { .ndo_open = depca_open, .ndo_start_xmit = depca_start_xmit, .ndo_stop = depca_close, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_do_ioctl = depca_ioctl, .ndo_tx_timeout = depca_tx_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/amd/hplance.c b/drivers/net/ethernet/amd/hplance.c index a900d5bf2948..86aa0d546a5b 100644 --- a/drivers/net/ethernet/amd/hplance.c +++ b/drivers/net/ethernet/amd/hplance.c @@ -74,7 +74,7 @@ static const struct net_device_ops hplance_netdev_ops = { .ndo_open = hplance_open, .ndo_stop = hplance_close, .ndo_start_xmit = lance_start_xmit, - .ndo_set_multicast_list = lance_set_multicast, + .ndo_set_rx_mode = lance_set_multicast, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c index 02336edce748..a6e2e840884e 100644 --- a/drivers/net/ethernet/amd/lance.c +++ b/drivers/net/ethernet/amd/lance.c @@ -459,7 +459,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_start_xmit = lance_start_xmit, .ndo_stop = lance_close, .ndo_get_stats = lance_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = lance_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/mvme147.c b/drivers/net/ethernet/amd/mvme147.c index 3a7ad840d5b5..56bc47a94186 100644 --- a/drivers/net/ethernet/amd/mvme147.c +++ b/drivers/net/ethernet/amd/mvme147.c @@ -61,7 +61,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_open = m147lance_open, .ndo_stop = m147lance_close, .ndo_start_xmit = lance_start_xmit, - .ndo_set_multicast_list = lance_set_multicast, + .ndo_set_rx_mode = lance_set_multicast, .ndo_tx_timeout = lance_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index c75ae85eb918..6e6aa7213aab 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -406,7 +406,7 @@ static const struct net_device_ops ni65_netdev_ops = { .ndo_stop = ni65_close, .ndo_start_xmit = ni65_send_packet, .ndo_tx_timeout = ni65_timeout, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 9d70b6595220..3accd5d21b08 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c @@ -430,7 +430,7 @@ static const struct net_device_ops mace_netdev_ops = { .ndo_tx_timeout = mace_tx_timeout, .ndo_set_config = mace_config, .ndo_get_stats = mace_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 8b3090dc4bcd..e19c1a73c955 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1505,7 +1505,7 @@ static const struct net_device_ops pcnet32_netdev_ops = { .ndo_start_xmit = pcnet32_start_xmit, .ndo_tx_timeout = pcnet32_tx_timeout, .ndo_get_stats = pcnet32_get_stats, - .ndo_set_multicast_list = pcnet32_set_multicast_list, + .ndo_set_rx_mode = pcnet32_set_multicast_list, .ndo_do_ioctl = pcnet32_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c index 7d9ec23aabf6..080b71fcc683 100644 --- a/drivers/net/ethernet/amd/sun3lance.c +++ b/drivers/net/ethernet/amd/sun3lance.c @@ -297,7 +297,7 @@ static const struct net_device_ops lance_netdev_ops = { .ndo_open = lance_open, .ndo_stop = lance_close, .ndo_start_xmit = lance_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_set_mac_address = NULL, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 06f2d4382dc4..8fda457f94cf 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -1298,7 +1298,7 @@ static const struct net_device_ops sparc_lance_ops = { .ndo_open = lance_open, .ndo_stop = lance_close, .ndo_start_xmit = lance_start_xmit, - .ndo_set_multicast_list = lance_set_multicast, + .ndo_set_rx_mode = lance_set_multicast, .ndo_tx_timeout = lance_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index 45e45e8d3d66..d070b229dbf7 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1237,7 +1237,7 @@ static const struct net_device_ops bmac_netdev_ops = { .ndo_open = bmac_open, .ndo_stop = bmac_close, .ndo_start_xmit = bmac_output, - .ndo_set_multicast_list = bmac_set_multicast, + .ndo_set_rx_mode = bmac_set_multicast, .ndo_set_mac_address = bmac_set_address, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/apple/cs89x0.c b/drivers/net/ethernet/apple/cs89x0.c index 537a4b2e2020..f328da24c8fa 100644 --- a/drivers/net/ethernet/apple/cs89x0.c +++ b/drivers/net/ethernet/apple/cs89x0.c @@ -488,7 +488,7 @@ static const struct net_device_ops net_ops = { .ndo_tx_timeout = net_timeout, .ndo_start_xmit = net_send_packet, .ndo_get_stats = net_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_set_mac_address = set_mac_address, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = net_poll_controller, diff --git a/drivers/net/ethernet/apple/mac89x0.c b/drivers/net/ethernet/apple/mac89x0.c index 669b317974a8..83781f316d1f 100644 --- a/drivers/net/ethernet/apple/mac89x0.c +++ b/drivers/net/ethernet/apple/mac89x0.c @@ -170,7 +170,7 @@ static const struct net_device_ops mac89x0_netdev_ops = { .ndo_stop = net_close, .ndo_start_xmit = net_send_packet, .ndo_get_stats = net_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_set_mac_address = set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 2074e9724ba3..bec87bd9195c 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -100,7 +100,7 @@ static const struct net_device_ops mace_netdev_ops = { .ndo_open = mace_open, .ndo_stop = mace_close, .ndo_start_xmit = mace_xmit_start, - .ndo_set_multicast_list = mace_set_multicast, + .ndo_set_rx_mode = mace_set_multicast, .ndo_set_mac_address = mace_set_address, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index 4286e67f9634..6cd3f8646dcd 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -185,7 +185,7 @@ static const struct net_device_ops mace_netdev_ops = { .ndo_stop = mace_close, .ndo_start_xmit = mace_xmit_start, .ndo_tx_timeout = mace_tx_timeout, - .ndo_set_multicast_list = mace_set_multicast, + .ndo_set_rx_mode = mace_set_multicast, .ndo_set_mac_address = mace_set_address, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 972244218408..acb4c1098cae 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2600,7 +2600,7 @@ static const struct net_device_ops atl1c_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_start_xmit = atl1c_xmit_frame, .ndo_set_mac_address = atl1c_set_mac_addr, - .ndo_set_multicast_list = atl1c_set_multi, + .ndo_set_rx_mode = atl1c_set_multi, .ndo_change_mtu = atl1c_change_mtu, .ndo_fix_features = atl1c_fix_features, .ndo_set_features = atl1c_set_features, diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index d8d411998fa3..1b5dc799348d 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2212,7 +2212,7 @@ static const struct net_device_ops atl1e_netdev_ops = { .ndo_stop = atl1e_close, .ndo_start_xmit = atl1e_xmit_frame, .ndo_get_stats = atl1e_get_stats, - .ndo_set_multicast_list = atl1e_set_multi, + .ndo_set_rx_mode = atl1e_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1e_set_mac_addr, .ndo_fix_features = atl1e_fix_features, diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 97e6954304ea..c34e82391f75 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2869,7 +2869,7 @@ static const struct net_device_ops atl1_netdev_ops = { .ndo_open = atl1_open, .ndo_stop = atl1_close, .ndo_start_xmit = atl1_xmit_frame, - .ndo_set_multicast_list = atlx_set_multi, + .ndo_set_rx_mode = atlx_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl1_set_mac, .ndo_change_mtu = atl1_change_mtu, diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index d4f7dda39721..1feae5928a4b 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c @@ -1325,7 +1325,7 @@ static const struct net_device_ops atl2_netdev_ops = { .ndo_open = atl2_open, .ndo_stop = atl2_close, .ndo_start_xmit = atl2_xmit_frame, - .ndo_set_multicast_list = atl2_set_multi, + .ndo_set_rx_mode = atl2_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = atl2_set_mac, .ndo_change_mtu = atl2_change_mtu, diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 41ea84e3f69c..4cf835dbc122 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -2114,7 +2114,7 @@ static const struct net_device_ops b44_netdev_ops = { .ndo_stop = b44_close, .ndo_start_xmit = b44_start_xmit, .ndo_get_stats = b44_get_stats, - .ndo_set_multicast_list = b44_set_rx_mode, + .ndo_set_rx_mode = b44_set_rx_mode, .ndo_set_mac_address = b44_set_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = b44_ioctl, diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 1d9b9858067c..05b022866076 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1603,7 +1603,7 @@ static const struct net_device_ops bcm_enet_ops = { .ndo_stop = bcm_enet_stop, .ndo_start_xmit = bcm_enet_start_xmit, .ndo_set_mac_address = bcm_enet_set_mac_address, - .ndo_set_multicast_list = bcm_enet_set_multicast_list, + .ndo_set_rx_mode = bcm_enet_set_multicast_list, .ndo_do_ioctl = bcm_enet_ioctl, .ndo_change_mtu = bcm_enet_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index ea65f7ec360a..0a1d7f279fc8 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -2176,7 +2176,7 @@ static const struct net_device_ops sbmac_netdev_ops = { .ndo_open = sbmac_open, .ndo_stop = sbmac_close, .ndo_start_xmit = sbmac_start_tx, - .ndo_set_multicast_list = sbmac_set_rx_mode, + .ndo_set_rx_mode = sbmac_set_rx_mode, .ndo_tx_timeout = sbmac_tx_timeout, .ndo_do_ioctl = sbmac_mii_ioctl, .ndo_change_mtu = sb1250_change_mtu, diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index dc3fbf61910b..6da9c57bcce5 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -15177,7 +15177,7 @@ static const struct net_device_ops tg3_netdev_ops = { .ndo_start_xmit = tg3_start_xmit, .ndo_get_stats64 = tg3_get_stats64, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = tg3_set_rx_mode, + .ndo_set_rx_mode = tg3_set_rx_mode, .ndo_set_mac_address = tg3_set_mac_addr, .ndo_do_ioctl = tg3_ioctl, .ndo_tx_timeout = tg3_tx_timeout, diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 5ad07eab7bec..bdfda0779a84 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -2957,7 +2957,6 @@ static const struct net_device_ops bnad_netdev_ops = { .ndo_start_xmit = bnad_start_xmit, .ndo_get_stats64 = bnad_get_stats64, .ndo_set_rx_mode = bnad_set_rx_mode, - .ndo_set_multicast_list = bnad_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnad_set_mac_address, .ndo_change_mtu = bnad_change_mtu, diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 29dc43523cec..1b0ba8c819f7 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -968,7 +968,7 @@ static const struct net_device_ops at91ether_netdev_ops = { .ndo_stop = at91ether_close, .ndo_start_xmit = at91ether_start_xmit, .ndo_get_stats = at91ether_stats, - .ndo_set_multicast_list = at91ether_set_multicast_list, + .ndo_set_rx_mode = at91ether_set_multicast_list, .ndo_set_mac_address = set_mac_address, .ndo_do_ioctl = at91ether_ioctl, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index dc4e305a1087..a437b46e5490 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1106,7 +1106,7 @@ static const struct net_device_ops macb_netdev_ops = { .ndo_open = macb_open, .ndo_stop = macb_close, .ndo_start_xmit = macb_start_xmit, - .ndo_set_multicast_list = macb_set_rx_mode, + .ndo_set_rx_mode = macb_set_rx_mode, .ndo_get_stats = macb_get_stats, .ndo_do_ioctl = macb_ioctl, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c index 3edbbc4c5112..9993f4f15433 100644 --- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c @@ -964,7 +964,7 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_start_xmit = t1_start_xmit, .ndo_get_stats = t1_get_stats, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = t1_set_rxmode, + .ndo_set_rx_mode = t1_set_rxmode, .ndo_do_ioctl = t1_ioctl, .ndo_change_mtu = t1_change_mtu, .ndo_set_mac_address = t1_set_mac_addr, diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 93b41a7ac175..29e0e4243231 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3153,7 +3153,7 @@ static const struct net_device_ops cxgb_netdev_ops = { .ndo_start_xmit = t3_eth_xmit, .ndo_get_stats = cxgb_get_stats, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = cxgb_set_rxmode, + .ndo_set_rx_mode = cxgb_set_rxmode, .ndo_do_ioctl = cxgb_ioctl, .ndo_change_mtu = cxgb_change_mtu, .ndo_set_mac_address = cxgb_set_mac_addr, diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index f342be0c51aa..c751c25d301e 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2104,7 +2104,6 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_get_stats64 = enic_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = enic_set_rx_mode, - .ndo_set_multicast_list = enic_set_rx_mode, .ndo_set_mac_address = enic_set_mac_address_dynamic, .ndo_change_mtu = enic_change_mtu, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, @@ -2126,7 +2125,6 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = enic_set_mac_address, .ndo_set_rx_mode = enic_set_rx_mode, - .ndo_set_multicast_list = enic_set_rx_mode, .ndo_change_mtu = enic_change_mtu, .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid, diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 8ef31dc4704d..24d61e14f9cd 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1339,7 +1339,7 @@ static const struct net_device_ops dm9000_netdev_ops = { .ndo_stop = dm9000_stop, .ndo_start_xmit = dm9000_start_xmit, .ndo_tx_timeout = dm9000_timeout, - .ndo_set_multicast_list = dm9000_hash_table, + .ndo_set_rx_mode = dm9000_hash_table, .ndo_do_ioctl = dm9000_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_features = dm9000_set_features, diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c index 05a5f71451a7..f9df5e4d0341 100644 --- a/drivers/net/ethernet/dec/ewrk3.c +++ b/drivers/net/ethernet/dec/ewrk3.c @@ -393,7 +393,7 @@ static const struct net_device_ops ewrk3_netdev_ops = { .ndo_open = ewrk3_open, .ndo_start_xmit = ewrk3_queue_pkt, .ndo_stop = ewrk3_close, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_do_ioctl = ewrk3_ioctl, .ndo_tx_timeout = ewrk3_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c index ce90efc6ba3c..1427739d9a51 100644 --- a/drivers/net/ethernet/dec/tulip/de2104x.c +++ b/drivers/net/ethernet/dec/tulip/de2104x.c @@ -1956,7 +1956,7 @@ bad_srom: static const struct net_device_ops de_netdev_ops = { .ndo_open = de_open, .ndo_stop = de_close, - .ndo_set_multicast_list = de_set_rx_mode, + .ndo_set_rx_mode = de_set_rx_mode, .ndo_start_xmit = de_start_xmit, .ndo_get_stats = de_get_stats, .ndo_tx_timeout = de_tx_timeout, diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index 959b41021a65..871bcaa7068d 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c @@ -1084,7 +1084,7 @@ static const struct net_device_ops de4x5_netdev_ops = { .ndo_stop = de4x5_close, .ndo_start_xmit = de4x5_queue_pkt, .ndo_get_stats = de4x5_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_do_ioctl = de4x5_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address= eth_mac_addr, diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c index 9a21ca3873fc..17b11ee1745a 100644 --- a/drivers/net/ethernet/dec/tulip/dmfe.c +++ b/drivers/net/ethernet/dec/tulip/dmfe.c @@ -356,7 +356,7 @@ static const struct net_device_ops netdev_ops = { .ndo_open = dmfe_open, .ndo_stop = dmfe_stop, .ndo_start_xmit = dmfe_start_xmit, - .ndo_set_multicast_list = dmfe_set_filter_mode, + .ndo_set_rx_mode = dmfe_set_filter_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index 1246998a677c..011f67c7ca47 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -1291,7 +1291,7 @@ static const struct net_device_ops tulip_netdev_ops = { .ndo_stop = tulip_close, .ndo_get_stats = tulip_get_stats, .ndo_do_ioctl = private_ioctl, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c index 9e63f406f72d..7a44a7a6adc8 100644 --- a/drivers/net/ethernet/dec/tulip/uli526x.c +++ b/drivers/net/ethernet/dec/tulip/uli526x.c @@ -259,7 +259,7 @@ static const struct net_device_ops netdev_ops = { .ndo_open = uli526x_open, .ndo_stop = uli526x_stop, .ndo_start_xmit = uli526x_start_xmit, - .ndo_set_multicast_list = uli526x_set_filter_mode, + .ndo_set_rx_mode = uli526x_set_filter_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 862eadf07191..4d01219ba22f 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c @@ -350,7 +350,7 @@ static const struct net_device_ops netdev_ops = { .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = tx_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/dlink/de620.c b/drivers/net/ethernet/dlink/de620.c index 1c51a7576119..3b934ab784d3 100644 --- a/drivers/net/ethernet/dlink/de620.c +++ b/drivers/net/ethernet/dlink/de620.c @@ -767,7 +767,7 @@ static const struct net_device_ops de620_netdev_ops = { .ndo_stop = de620_close, .ndo_start_xmit = de620_start_xmit, .ndo_tx_timeout = de620_timeout, - .ndo_set_multicast_list = de620_set_multicast_list, + .ndo_set_rx_mode = de620_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c index ed73e4a93508..3fa91408532f 100644 --- a/drivers/net/ethernet/dlink/dl2k.c +++ b/drivers/net/ethernet/dlink/dl2k.c @@ -92,7 +92,7 @@ static const struct net_device_ops netdev_ops = { .ndo_get_stats = get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, - .ndo_set_multicast_list = set_multicast, + .ndo_set_rx_mode = set_multicast, .ndo_do_ioctl = rio_ioctl, .ndo_tx_timeout = rio_tx_timeout, .ndo_change_mtu = change_mtu, diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c index 4793df843c24..dcd7f7a71ad4 100644 --- a/drivers/net/ethernet/dlink/sundance.c +++ b/drivers/net/ethernet/dlink/sundance.c @@ -464,7 +464,7 @@ static const struct net_device_ops netdev_ops = { .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = tx_timeout, .ndo_change_mtu = change_mtu, diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 8abbe1d82826..bdb348a5ccf6 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -888,7 +888,7 @@ static const struct net_device_ops ethoc_netdev_ops = { .ndo_do_ioctl = ethoc_ioctl, .ndo_set_config = ethoc_config, .ndo_set_mac_address = ethoc_set_mac_address, - .ndo_set_multicast_list = ethoc_set_multicast_list, + .ndo_set_rx_mode = ethoc_set_multicast_list, .ndo_change_mtu = ethoc_change_mtu, .ndo_tx_timeout = ethoc_tx_timeout, .ndo_start_xmit = ethoc_start_xmit, diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index fa8677c32384..61d2bddec1fa 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c @@ -469,7 +469,7 @@ static const struct net_device_ops netdev_ops = { .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = mii_ioctl, .ndo_tx_timeout = fealnx_tx_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index e8266ccf818a..158b82ea6df5 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1325,7 +1325,7 @@ static const struct net_device_ops fec_netdev_ops = { .ndo_open = fec_enet_open, .ndo_stop = fec_enet_close, .ndo_start_xmit = fec_enet_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = fec_timeout, diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c index cb4416e591f1..30745b56fe5d 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c @@ -828,7 +828,7 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = { .ndo_open = mpc52xx_fec_open, .ndo_stop = mpc52xx_fec_close, .ndo_start_xmit = mpc52xx_fec_start_xmit, - .ndo_set_multicast_list = mpc52xx_fec_set_multicast_list, + .ndo_set_rx_mode = mpc52xx_fec_set_multicast_list, .ndo_set_mac_address = mpc52xx_fec_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = mpc52xx_fec_ioctl, diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 329ef231a096..5bf5471f06ff 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -988,7 +988,7 @@ static const struct net_device_ops fs_enet_netdev_ops = { .ndo_get_stats = fs_enet_get_stats, .ndo_start_xmit = fs_enet_start_xmit, .ndo_tx_timeout = fs_timeout, - .ndo_set_multicast_list = fs_set_multicast_list, + .ndo_set_rx_mode = fs_set_multicast_list, .ndo_do_ioctl = fs_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 2659daad783d..29dff1ec7f2d 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -458,7 +458,7 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_stop = gfar_close, .ndo_change_mtu = gfar_change_mtu, .ndo_set_features = gfar_set_features, - .ndo_set_multicast_list = gfar_set_multi, + .ndo_set_rx_mode = gfar_set_multi, .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, .ndo_get_stats = gfar_get_stats, diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 42f8e31b0bbb..46d690a92c0b 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -3731,7 +3731,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ucc_geth_set_mac_addr, .ndo_change_mtu = eth_change_mtu, - .ndo_set_multicast_list = ucc_geth_set_multi, + .ndo_set_rx_mode = ucc_geth_set_multi, .ndo_tx_timeout = ucc_geth_timeout, .ndo_do_ioctl = ucc_geth_ioctl, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c index 65a78f965dd2..7c6c908bdf02 100644 --- a/drivers/net/ethernet/fujitsu/at1700.c +++ b/drivers/net/ethernet/fujitsu/at1700.c @@ -253,7 +253,7 @@ static const struct net_device_ops at1700_netdev_ops = { .ndo_open = net_open, .ndo_stop = net_close, .ndo_start_xmit = net_send_packet, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_tx_timeout = net_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/fujitsu/eth16i.c b/drivers/net/ethernet/fujitsu/eth16i.c index 12d28e9d0cb7..b0e2313af3d1 100644 --- a/drivers/net/ethernet/fujitsu/eth16i.c +++ b/drivers/net/ethernet/fujitsu/eth16i.c @@ -478,7 +478,7 @@ static const struct net_device_ops eth16i_netdev_ops = { .ndo_open = eth16i_open, .ndo_stop = eth16i_close, .ndo_start_xmit = eth16i_tx, - .ndo_set_multicast_list = eth16i_multicast, + .ndo_set_rx_mode = eth16i_multicast, .ndo_tx_timeout = eth16i_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index 723815e7a997..15416752c13e 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -226,7 +226,7 @@ static const struct net_device_ops fjn_netdev_ops = { .ndo_start_xmit = fjn_start_xmit, .ndo_tx_timeout = fjn_tx_timeout, .ndo_set_config = fjn_config, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index b6519c1ba7e1..6a5ee0776b28 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -430,7 +430,7 @@ static const struct net_device_ops hp100_bm_netdev_ops = { .ndo_stop = hp100_close, .ndo_start_xmit = hp100_start_xmit_bm, .ndo_get_stats = hp100_get_stats, - .ndo_set_multicast_list = hp100_set_multicast_list, + .ndo_set_rx_mode = hp100_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -441,7 +441,7 @@ static const struct net_device_ops hp100_netdev_ops = { .ndo_stop = hp100_close, .ndo_start_xmit = hp100_start_xmit, .ndo_get_stats = hp100_get_stats, - .ndo_set_multicast_list = hp100_set_multicast_list, + .ndo_set_rx_mode = hp100_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/i825xx/3c505.c b/drivers/net/ethernet/i825xx/3c505.c index 88d766ee0e1b..40e1a175fceb 100644 --- a/drivers/net/ethernet/i825xx/3c505.c +++ b/drivers/net/ethernet/i825xx/3c505.c @@ -1363,7 +1363,7 @@ static const struct net_device_ops elp_netdev_ops = { .ndo_get_stats = elp_get_stats, .ndo_start_xmit = elp_start_xmit, .ndo_tx_timeout = elp_timeout, - .ndo_set_multicast_list = elp_set_mc_list, + .ndo_set_rx_mode = elp_set_mc_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/i825xx/3c523.c b/drivers/net/ethernet/i825xx/3c523.c index bc0d1a1c2e28..d70d3df4c985 100644 --- a/drivers/net/ethernet/i825xx/3c523.c +++ b/drivers/net/ethernet/i825xx/3c523.c @@ -409,7 +409,7 @@ static const struct net_device_ops netdev_ops = { .ndo_start_xmit = elmc_send_packet, .ndo_tx_timeout = elmc_timeout, #ifdef ELMC_MULTICAST - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, #endif .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/3c527.c b/drivers/net/ethernet/i825xx/3c527.c index d9d056d207f3..474b5e71a53a 100644 --- a/drivers/net/ethernet/i825xx/3c527.c +++ b/drivers/net/ethernet/i825xx/3c527.c @@ -292,7 +292,7 @@ static const struct net_device_ops netdev_ops = { .ndo_stop = mc32_close, .ndo_start_xmit = mc32_send_packet, .ndo_get_stats = mc32_get_stats, - .ndo_set_multicast_list = mc32_set_multicast_list, + .ndo_set_rx_mode = mc32_set_multicast_list, .ndo_tx_timeout = mc32_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c index be1f1970c842..f2408a4d5d9c 100644 --- a/drivers/net/ethernet/i825xx/82596.c +++ b/drivers/net/ethernet/i825xx/82596.c @@ -1145,7 +1145,7 @@ static const struct net_device_ops i596_netdev_ops = { .ndo_open = i596_open, .ndo_stop = i596_close, .ndo_start_xmit = i596_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = i596_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/eepro.c b/drivers/net/ethernet/i825xx/eepro.c index dfeb006035df..067c46069a11 100644 --- a/drivers/net/ethernet/i825xx/eepro.c +++ b/drivers/net/ethernet/i825xx/eepro.c @@ -743,7 +743,7 @@ static const struct net_device_ops eepro_netdev_ops = { .ndo_open = eepro_open, .ndo_stop = eepro_close, .ndo_start_xmit = eepro_send_packet, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = eepro_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c index a19228563efd..3a9580f3d4dd 100644 --- a/drivers/net/ethernet/i825xx/eexpress.c +++ b/drivers/net/ethernet/i825xx/eexpress.c @@ -1047,7 +1047,7 @@ static const struct net_device_ops eexp_netdev_ops = { .ndo_open = eexp_open, .ndo_stop = eexp_close, .ndo_start_xmit = eexp_xmit, - .ndo_set_multicast_list = eexp_set_multicast, + .ndo_set_rx_mode = eexp_set_multicast, .ndo_tx_timeout = eexp_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/ether1.c b/drivers/net/ethernet/i825xx/ether1.c index b00781c02d5d..42e90a97c7a5 100644 --- a/drivers/net/ethernet/i825xx/ether1.c +++ b/drivers/net/ethernet/i825xx/ether1.c @@ -985,7 +985,7 @@ static const struct net_device_ops ether1_netdev_ops = { .ndo_open = ether1_open, .ndo_stop = ether1_close, .ndo_start_xmit = ether1_sendpacket, - .ndo_set_multicast_list = ether1_setmulticastlist, + .ndo_set_rx_mode = ether1_setmulticastlist, .ndo_tx_timeout = ether1_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c index 9e042894479b..3efbd8dbb63d 100644 --- a/drivers/net/ethernet/i825xx/lib82596.c +++ b/drivers/net/ethernet/i825xx/lib82596.c @@ -1038,7 +1038,7 @@ static const struct net_device_ops i596_netdev_ops = { .ndo_open = i596_open, .ndo_stop = i596_close, .ndo_start_xmit = i596_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = i596_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 385a95311cd2..414044b3cb11 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c @@ -954,7 +954,7 @@ static const struct net_device_ops i596_netdev_ops = { .ndo_open = i596_open, .ndo_stop = i596_close, .ndo_start_xmit = i596_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = i596_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/i825xx/ni52.c b/drivers/net/ethernet/i825xx/ni52.c index d973fc6c6b88..c0893715ef47 100644 --- a/drivers/net/ethernet/i825xx/ni52.c +++ b/drivers/net/ethernet/i825xx/ni52.c @@ -445,7 +445,7 @@ static const struct net_device_ops ni52_netdev_ops = { .ndo_get_stats = ni52_get_stats, .ndo_tx_timeout = ni52_timeout, .ndo_start_xmit = ni52_send_packet, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index b6ae53bada75..6ef5e11d1c84 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c @@ -333,7 +333,7 @@ static const struct net_device_ops sun3_82586_netdev_ops = { .ndo_open = sun3_82586_open, .ndo_stop = sun3_82586_close, .ndo_start_xmit = sun3_82586_send_packet, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_tx_timeout = sun3_82586_timeout, .ndo_get_stats = sun3_82586_get_stats, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index 8b8881718f5e..962b4c421f3f 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c @@ -356,7 +356,7 @@ static const struct net_device_ops znet_netdev_ops = { .ndo_open = znet_open, .ndo_stop = znet_close, .ndo_start_xmit = znet_send_packet, - .ndo_set_multicast_list = znet_set_multicast_list, + .ndo_set_rx_mode = znet_set_multicast_list, .ndo_tx_timeout = znet_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index be2cb4ab8b4f..583bcd32e543 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -3161,7 +3161,7 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_get_stats = ehea_get_stats, .ndo_set_mac_address = ehea_set_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = ehea_set_multicast_list, + .ndo_set_rx_mode = ehea_set_multicast_list, .ndo_change_mtu = ehea_change_mtu, .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 70cb7d8a3b53..209f56820c3e 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2661,7 +2661,7 @@ static const struct net_device_ops emac_netdev_ops = { .ndo_open = emac_open, .ndo_stop = emac_close, .ndo_get_stats = emac_stats, - .ndo_set_multicast_list = emac_set_multicast_list, + .ndo_set_rx_mode = emac_set_multicast_list, .ndo_do_ioctl = emac_ioctl, .ndo_tx_timeout = emac_tx_timeout, .ndo_validate_addr = eth_validate_addr, @@ -2674,7 +2674,7 @@ static const struct net_device_ops emac_gige_netdev_ops = { .ndo_open = emac_open, .ndo_stop = emac_close, .ndo_get_stats = emac_stats, - .ndo_set_multicast_list = emac_set_multicast_list, + .ndo_set_rx_mode = emac_set_multicast_list, .ndo_do_ioctl = emac_ioctl, .ndo_tx_timeout = emac_tx_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index ba99af05bf62..bba1ffcd92d1 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1299,7 +1299,7 @@ static const struct net_device_ops ibmveth_netdev_ops = { .ndo_open = ibmveth_open, .ndo_stop = ibmveth_close, .ndo_start_xmit = ibmveth_start_xmit, - .ndo_set_multicast_list = ibmveth_set_multicast_list, + .ndo_set_rx_mode = ibmveth_set_multicast_list, .ndo_do_ioctl = ibmveth_ioctl, .ndo_change_mtu = ibmveth_change_mtu, .ndo_fix_features = ibmveth_fix_features, diff --git a/drivers/net/ethernet/ibm/iseries_veth.c b/drivers/net/ethernet/ibm/iseries_veth.c index 53dd39e9130e..4326681df382 100644 --- a/drivers/net/ethernet/ibm/iseries_veth.c +++ b/drivers/net/ethernet/ibm/iseries_veth.c @@ -1009,7 +1009,7 @@ static const struct net_device_ops veth_netdev_ops = { .ndo_stop = veth_close, .ndo_start_xmit = veth_start_xmit, .ndo_change_mtu = veth_change_mtu, - .ndo_set_multicast_list = veth_set_multicast_list, + .ndo_set_rx_mode = veth_set_multicast_list, .ndo_set_mac_address = NULL, .ndo_validate_addr = eth_validate_addr, }; diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c index b470281158e9..8fd80a00b898 100644 --- a/drivers/net/ethernet/icplus/ipg.c +++ b/drivers/net/ethernet/icplus/ipg.c @@ -2201,7 +2201,7 @@ static const struct net_device_ops ipg_netdev_ops = { .ndo_stop = ipg_nic_stop, .ndo_start_xmit = ipg_nic_hard_start_xmit, .ndo_get_stats = ipg_nic_get_stats, - .ndo_set_multicast_list = ipg_nic_set_multicast_list, + .ndo_set_rx_mode = ipg_nic_set_multicast_list, .ndo_do_ioctl = ipg_ioctl, .ndo_tx_timeout = ipg_tx_timeout, .ndo_change_mtu = ipg_nic_change_mtu, diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index c1352c60c299..fe87d3eea5ed 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -2738,7 +2738,7 @@ static const struct net_device_ops e100_netdev_ops = { .ndo_stop = e100_close, .ndo_start_xmit = e100_xmit_frame, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = e100_set_multicast_list, + .ndo_set_rx_mode = e100_set_multicast_list, .ndo_set_mac_address = e100_set_mac_address, .ndo_change_mtu = e100_change_mtu, .ndo_do_ioctl = e100_do_ioctl, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index ab4be80f7ab5..d0fdb512e849 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5761,7 +5761,7 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_stop = e1000_close, .ndo_start_xmit = e1000_xmit_frame, .ndo_get_stats64 = e1000e_get_stats64, - .ndo_set_multicast_list = e1000_set_multi, + .ndo_set_rx_mode = e1000_set_multi, .ndo_set_mac_address = e1000_set_mac, .ndo_change_mtu = e1000_change_mtu, .ndo_do_ioctl = e1000_ioctl, diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 592b5c1827bc..801608497409 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1790,7 +1790,6 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_start_xmit = igb_xmit_frame_adv, .ndo_get_stats64 = igb_get_stats64, .ndo_set_rx_mode = igb_set_rx_mode, - .ndo_set_multicast_list = igb_set_rx_mode, .ndo_set_mac_address = igb_set_mac, .ndo_change_mtu = igb_change_mtu, .ndo_do_ioctl = igb_ioctl, diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 40ed066e3ef4..a6bdb3c744f0 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2538,7 +2538,7 @@ static const struct net_device_ops igbvf_netdev_ops = { .ndo_stop = igbvf_close, .ndo_start_xmit = igbvf_xmit_frame, .ndo_get_stats = igbvf_get_stats, - .ndo_set_multicast_list = igbvf_set_multi, + .ndo_set_rx_mode = igbvf_set_multi, .ndo_set_mac_address = igbvf_set_mac, .ndo_change_mtu = igbvf_change_mtu, .ndo_do_ioctl = igbvf_ioctl, diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 6a130eb51cfa..b8ef2c0fc5d0 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -330,7 +330,7 @@ static const struct net_device_ops ixgb_netdev_ops = { .ndo_stop = ixgb_close, .ndo_start_xmit = ixgb_xmit_frame, .ndo_get_stats = ixgb_get_stats, - .ndo_set_multicast_list = ixgb_set_multi, + .ndo_set_rx_mode = ixgb_set_multi, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ixgb_set_mac, .ndo_change_mtu = ixgb_change_mtu, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 8c70273b01bc..faa83cea7331 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7205,7 +7205,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_start_xmit = ixgbe_xmit_frame, .ndo_select_queue = ixgbe_select_queue, .ndo_set_rx_mode = ixgbe_set_rx_mode, - .ndo_set_multicast_list = ixgbe_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ixgbe_set_mac, .ndo_change_mtu = ixgbe_change_mtu, diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 45b007827024..b1e1c2daf5f9 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -3221,7 +3221,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_stop = ixgbevf_close, .ndo_start_xmit = ixgbevf_xmit_frame, .ndo_set_rx_mode = ixgbevf_set_rx_mode, - .ndo_set_multicast_list = ixgbevf_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ixgbevf_set_mac, .ndo_change_mtu = ixgbevf_change_mtu, diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 3ac262f55633..a869ee47dde6 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -2839,7 +2839,7 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_do_ioctl = jme_ioctl, .ndo_start_xmit = jme_start_xmit, .ndo_set_mac_address = jme_set_macaddr, - .ndo_set_multicast_list = jme_set_multi, + .ndo_set_rx_mode = jme_set_multi, .ndo_change_mtu = jme_change_mtu, .ndo_tx_timeout = jme_tx_timeout, .ndo_fix_features = jme_fix_features, diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 763844c587fd..6767756d0dad 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1089,7 +1089,7 @@ static const struct net_device_ops korina_netdev_ops = { .ndo_open = korina_open, .ndo_stop = korina_close, .ndo_start_xmit = korina_send_packet, - .ndo_set_multicast_list = korina_multicast_list, + .ndo_set_rx_mode = korina_multicast_list, .ndo_tx_timeout = korina_tx_timeout, .ndo_do_ioctl = korina_ioctl, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 45f252b7da30..6bb2b9506cad 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -687,7 +687,7 @@ static const struct net_device_ops ltq_eth_netdev_ops = { .ndo_do_ioctl = ltq_etop_ioctl, .ndo_set_mac_address = ltq_etop_set_mac_address, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = ltq_etop_set_multicast_list, + .ndo_set_rx_mode = ltq_etop_set_multicast_list, .ndo_select_queue = ltq_etop_select_queue, .ndo_init = ltq_etop_init, .ndo_tx_timeout = ltq_etop_tx_timeout, diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 98ec614c5690..34622b038094 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -3762,7 +3762,7 @@ static const struct net_device_ops skge_netdev_ops = { .ndo_tx_timeout = skge_tx_timeout, .ndo_change_mtu = skge_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = skge_set_multicast, + .ndo_set_rx_mode = skge_set_multicast, .ndo_set_mac_address = skge_set_mac_address, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = skge_netpoll, diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 57339da76326..3ff0a1292933 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -4612,7 +4612,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_do_ioctl = sky2_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = sky2_set_mac_address, - .ndo_set_multicast_list = sky2_set_multicast, + .ndo_set_rx_mode = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, .ndo_fix_features = sky2_fix_features, .ndo_set_features = sky2_set_features, @@ -4629,7 +4629,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_do_ioctl = sky2_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = sky2_set_mac_address, - .ndo_set_multicast_list = sky2_set_multicast, + .ndo_set_rx_mode = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, .ndo_fix_features = sky2_fix_features, .ndo_set_features = sky2_set_features, diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4b0f32e568f8..27789be1e6ac 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1016,7 +1016,7 @@ static const struct net_device_ops mlx4_netdev_ops = { .ndo_start_xmit = mlx4_en_xmit, .ndo_select_queue = mlx4_en_select_queue, .ndo_get_stats = mlx4_en_get_stats, - .ndo_set_multicast_list = mlx4_en_set_multicast, + .ndo_set_rx_mode = mlx4_en_set_multicast, .ndo_set_mac_address = mlx4_en_set_mac, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = mlx4_en_change_mtu, diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index c827a6097d02..70788401d699 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -1333,7 +1333,7 @@ static const struct net_device_ops ks8695_netdev_ops = { .ndo_tx_timeout = ks8695_timeout, .ndo_set_mac_address = ks8695_set_mac, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = ks8695_set_multicast, + .ndo_set_rx_mode = ks8695_set_multicast, }; /** diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index 2837ce209cd7..50055e0282ed 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c @@ -1534,7 +1534,7 @@ static const struct net_device_ops enc28j60_netdev_ops = { .ndo_open = enc28j60_net_open, .ndo_stop = enc28j60_net_close, .ndo_start_xmit = enc28j60_send_packet, - .ndo_set_multicast_list = enc28j60_set_multicast_list, + .ndo_set_rx_mode = enc28j60_set_multicast_list, .ndo_set_mac_address = enc28j60_set_mac_address, .ndo_tx_timeout = enc28j60_tx_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/mipsnet.c b/drivers/net/ethernet/mipsnet.c index 004e64ab1f95..d05b0c9e1e9c 100644 --- a/drivers/net/ethernet/mipsnet.c +++ b/drivers/net/ethernet/mipsnet.c @@ -242,7 +242,7 @@ static const struct net_device_ops mipsnet_netdev_ops = { .ndo_open = mipsnet_open, .ndo_stop = mipsnet_close, .ndo_start_xmit = mipsnet_xmit, - .ndo_set_multicast_list = mipsnet_set_mclist, + .ndo_set_rx_mode = mipsnet_set_mclist, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 1d2247554a35..81c17002374b 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3892,7 +3892,7 @@ static const struct net_device_ops myri10ge_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = myri10ge_change_mtu, .ndo_fix_features = myri10ge_fix_features, - .ndo_set_multicast_list = myri10ge_set_multicast_list, + .ndo_set_rx_mode = myri10ge_set_multicast_list, .ndo_set_mac_address = myri10ge_set_mac_address, }; diff --git a/drivers/net/ethernet/natsemi/ibmlana.c b/drivers/net/ethernet/natsemi/ibmlana.c index a7d6cad32953..999407f7ebdf 100644 --- a/drivers/net/ethernet/natsemi/ibmlana.c +++ b/drivers/net/ethernet/natsemi/ibmlana.c @@ -910,7 +910,7 @@ static const struct net_device_ops ibmlana_netdev_ops = { .ndo_open = ibmlana_open, .ndo_stop = ibmlana_close, .ndo_start_xmit = ibmlana_tx, - .ndo_set_multicast_list = ibmlana_set_multicast_list, + .ndo_set_rx_mode = ibmlana_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c index 949c1f933644..fc7c6a932ad9 100644 --- a/drivers/net/ethernet/natsemi/jazzsonic.c +++ b/drivers/net/ethernet/natsemi/jazzsonic.c @@ -111,7 +111,7 @@ static const struct net_device_ops sonic_netdev_ops = { .ndo_stop = jazzsonic_close, .ndo_start_xmit = sonic_send_packet, .ndo_get_stats = sonic_get_stats, - .ndo_set_multicast_list = sonic_multicast_list, + .ndo_set_rx_mode = sonic_multicast_list, .ndo_tx_timeout = sonic_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index c93679ee6994..5c36948e54d7 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -190,7 +190,7 @@ static const struct net_device_ops macsonic_netdev_ops = { .ndo_open = macsonic_open, .ndo_stop = macsonic_close, .ndo_start_xmit = sonic_send_packet, - .ndo_set_multicast_list = sonic_multicast_list, + .ndo_set_rx_mode = sonic_multicast_list, .ndo_tx_timeout = sonic_tx_timeout, .ndo_get_stats = sonic_get_stats, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c index 2962cc695ce3..6ca047aab793 100644 --- a/drivers/net/ethernet/natsemi/natsemi.c +++ b/drivers/net/ethernet/natsemi/natsemi.c @@ -783,7 +783,7 @@ static const struct net_device_ops natsemi_netdev_ops = { .ndo_stop = netdev_close, .ndo_start_xmit = start_tx, .ndo_get_stats = get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = natsemi_change_mtu, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = ns_tx_timeout, diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c index e736aec588fc..1a1e20e97a23 100644 --- a/drivers/net/ethernet/natsemi/ns83820.c +++ b/drivers/net/ethernet/natsemi/ns83820.c @@ -1937,7 +1937,7 @@ static const struct net_device_ops netdev_ops = { .ndo_start_xmit = ns83820_hard_start_xmit, .ndo_get_stats = ns83820_get_stats, .ndo_change_mtu = ns83820_change_mtu, - .ndo_set_multicast_list = ns83820_set_multicast, + .ndo_set_rx_mode = ns83820_set_multicast, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = ns83820_tx_timeout, diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c index 9f12026d98e7..ccf61b9da8d1 100644 --- a/drivers/net/ethernet/natsemi/xtsonic.c +++ b/drivers/net/ethernet/natsemi/xtsonic.c @@ -122,7 +122,7 @@ static const struct net_device_ops xtsonic_netdev_ops = { .ndo_stop = xtsonic_close, .ndo_start_xmit = sonic_send_packet, .ndo_get_stats = sonic_get_stats, - .ndo_set_multicast_list = sonic_multicast_list, + .ndo_set_rx_mode = sonic_multicast_list, .ndo_tx_timeout = sonic_tx_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 277d48b0800a..840cbb25bdde 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -7682,7 +7682,7 @@ static const struct net_device_ops s2io_netdev_ops = { .ndo_get_stats = s2io_get_stats, .ndo_start_xmit = s2io_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = s2io_set_multicast, + .ndo_set_rx_mode = s2io_set_multicast, .ndo_do_ioctl = s2io_ioctl, .ndo_set_mac_address = s2io_set_mac_addr, .ndo_change_mtu = s2io_change_mtu, diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 178348a258d2..1a53a24fe3d4 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -3354,7 +3354,7 @@ static const struct net_device_ops vxge_netdev_ops = { .ndo_get_stats64 = vxge_get_stats64, .ndo_start_xmit = vxge_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = vxge_set_multicast, + .ndo_set_rx_mode = vxge_set_multicast, .ndo_do_ioctl = vxge_ioctl, .ndo_set_mac_address = vxge_set_mac_addr, .ndo_change_mtu = vxge_change_mtu, diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 2dfee892d200..8d288af16fc9 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -306,7 +306,7 @@ static const struct net_device_ops netx_eth_netdev_ops = { .ndo_stop = netx_eth_close, .ndo_start_xmit = netx_eth_hard_start_xmit, .ndo_tx_timeout = netx_eth_timeout, - .ndo_set_multicast_list = netx_eth_set_multicast_list, + .ndo_set_rx_mode = netx_eth_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c index bfea499a3513..f1bfb8f8fcf0 100644 --- a/drivers/net/ethernet/nuvoton/w90p910_ether.c +++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c @@ -919,7 +919,7 @@ static const struct net_device_ops w90p910_ether_netdev_ops = { .ndo_stop = w90p910_ether_close, .ndo_start_xmit = w90p910_ether_start_xmit, .ndo_get_stats = w90p910_ether_stats, - .ndo_set_multicast_list = w90p910_ether_set_multicast_list, + .ndo_set_rx_mode = w90p910_ether_set_multicast_list, .ndo_set_mac_address = w90p910_set_mac_address, .ndo_do_ioctl = w90p910_ether_ioctl, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index e55df308a3af..3784a727692e 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -5208,7 +5208,7 @@ static const struct net_device_ops nv_netdev_ops = { .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, - .ndo_set_multicast_list = nv_set_multicast, + .ndo_set_rx_mode = nv_set_multicast, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif @@ -5225,7 +5225,7 @@ static const struct net_device_ops nv_netdev_ops_optimized = { .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, - .ndo_set_multicast_list = nv_set_multicast, + .ndo_set_rx_mode = nv_set_multicast, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = nv_poll_controller, #endif diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c index d6f96e50e2f4..bc1d946b7971 100644 --- a/drivers/net/ethernet/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/octeon/octeon_mgmt.c @@ -1060,7 +1060,6 @@ static const struct net_device_ops octeon_mgmt_ops = { .ndo_stop = octeon_mgmt_stop, .ndo_start_xmit = octeon_mgmt_xmit, .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering, - .ndo_set_multicast_list = octeon_mgmt_set_rx_filtering, .ndo_set_mac_address = octeon_mgmt_set_mac_address, .ndo_do_ioctl = octeon_mgmt_ioctl, .ndo_change_mtu = octeon_mgmt_change_mtu, diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index eac3c5ca9731..72276fe78f8f 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -2158,7 +2158,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = { .ndo_change_mtu = pch_gbe_change_mtu, .ndo_set_features = pch_gbe_set_features, .ndo_do_ioctl = pch_gbe_ioctl, - .ndo_set_multicast_list = &pch_gbe_set_multi, + .ndo_set_rx_mode = pch_gbe_set_multi, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = pch_gbe_netpoll, #endif diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c index c274b3d77eb5..3458df3780b8 100644 --- a/drivers/net/ethernet/packetengines/hamachi.c +++ b/drivers/net/ethernet/packetengines/hamachi.c @@ -567,7 +567,7 @@ static const struct net_device_ops hamachi_netdev_ops = { .ndo_stop = hamachi_close, .ndo_start_xmit = hamachi_start_xmit, .ndo_get_stats = hamachi_get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c index 3e5ac60b89ac..db44e9af03c3 100644 --- a/drivers/net/ethernet/packetengines/yellowfin.c +++ b/drivers/net/ethernet/packetengines/yellowfin.c @@ -359,7 +359,7 @@ static const struct net_device_ops netdev_ops = { .ndo_open = yellowfin_open, .ndo_stop = yellowfin_close, .ndo_start_xmit = yellowfin_start_xmit, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 9ec112ca62e4..fad620da7c11 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1719,7 +1719,7 @@ static const struct net_device_ops pasemi_netdev_ops = { .ndo_open = pasemi_mac_open, .ndo_stop = pasemi_mac_close, .ndo_start_xmit = pasemi_mac_start_tx, - .ndo_set_multicast_list = pasemi_mac_set_rx_mode, + .ndo_set_rx_mode = pasemi_mac_set_rx_mode, .ndo_set_mac_address = pasemi_mac_set_mac_addr, .ndo_change_mtu = pasemi_mac_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 8c7fc32d781f..de18e4753b64 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -524,7 +524,7 @@ static const struct net_device_ops netxen_netdev_ops = { .ndo_start_xmit = netxen_nic_xmit_frame, .ndo_get_stats64 = netxen_nic_get_stats, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = netxen_set_multicast_list, + .ndo_set_rx_mode = netxen_set_multicast_list, .ndo_set_mac_address = netxen_nic_set_mac, .ndo_change_mtu = netxen_nic_change_mtu, .ndo_tx_timeout = netxen_tx_timeout, diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index ccde8061afa8..8cab61c08c8d 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -3762,7 +3762,6 @@ static const struct net_device_ops ql3xxx_netdev_ops = { .ndo_open = ql3xxx_open, .ndo_start_xmit = ql3xxx_send, .ndo_stop = ql3xxx_close, - .ndo_set_multicast_list = NULL, /* not allowed on NIC side */ .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ql3xxx_set_mac_address, diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ec8ef72d38d3..b447cc50693a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -325,7 +325,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { .ndo_start_xmit = qlcnic_xmit_frame, .ndo_get_stats = qlcnic_get_stats, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = qlcnic_set_multi, + .ndo_set_rx_mode = qlcnic_set_multi, .ndo_set_mac_address = qlcnic_set_mac, .ndo_change_mtu = qlcnic_change_mtu, .ndo_fix_features = qlcnic_fix_features, diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index f07e96ec8843..39360c485867 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4676,7 +4676,7 @@ static const struct net_device_ops qlge_netdev_ops = { .ndo_start_xmit = qlge_send, .ndo_change_mtu = qlge_change_mtu, .ndo_get_stats = qlge_get_stats, - .ndo_set_multicast_list = qlge_set_multicast_list, + .ndo_set_rx_mode = qlge_set_multicast_list, .ndo_set_mac_address = qlge_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = qlge_tx_timeout, diff --git a/drivers/net/ethernet/racal/ni5010.c b/drivers/net/ethernet/racal/ni5010.c index 4d3f2e2b28bd..072810da9a37 100644 --- a/drivers/net/ethernet/racal/ni5010.c +++ b/drivers/net/ethernet/racal/ni5010.c @@ -192,7 +192,7 @@ static const struct net_device_ops ni5010_netdev_ops = { .ndo_open = ni5010_open, .ndo_stop = ni5010_close, .ndo_start_xmit = ni5010_send_packet, - .ndo_set_multicast_list = ni5010_set_multicast_list, + .ndo_set_rx_mode = ni5010_set_multicast_list, .ndo_tx_timeout = ni5010_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index b64fcee483aa..2bbadc044784 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -982,7 +982,7 @@ static const struct net_device_ops r6040_netdev_ops = { .ndo_stop = r6040_close, .ndo_start_xmit = r6040_start_xmit, .ndo_get_stats = r6040_get_stats, - .ndo_set_multicast_list = r6040_multicast_list, + .ndo_set_rx_mode = r6040_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index cc4c210a91f8..5d2d1b8678f6 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -1785,7 +1785,7 @@ static const struct net_device_ops cp_netdev_ops = { .ndo_stop = cp_close, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = cp_set_mac_address, - .ndo_set_multicast_list = cp_set_rx_mode, + .ndo_set_rx_mode = cp_set_rx_mode, .ndo_get_stats = cp_get_stats, .ndo_do_ioctl = cp_ioctl, .ndo_start_xmit = cp_start_xmit, diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index c2672c692d6f..4d6b254fc6c1 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -916,7 +916,7 @@ static const struct net_device_ops rtl8139_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = rtl8139_set_mac_address, .ndo_start_xmit = rtl8139_start_xmit, - .ndo_set_multicast_list = rtl8139_set_rx_mode, + .ndo_set_rx_mode = rtl8139_set_rx_mode, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = rtl8139_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c index f3459798b0e9..e3f57fdbf0ea 100644 --- a/drivers/net/ethernet/realtek/atp.c +++ b/drivers/net/ethernet/realtek/atp.c @@ -245,7 +245,7 @@ static const struct net_device_ops atp_netdev_ops = { .ndo_open = net_open, .ndo_stop = net_close, .ndo_start_xmit = atp_send_packet, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_tx_timeout = tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 02339b3352e7..1cf8c3c1328d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3277,7 +3277,7 @@ static const struct net_device_ops rtl8169_netdev_ops = { .ndo_set_features = rtl8169_set_features, .ndo_set_mac_address = rtl_set_mac_address, .ndo_do_ioctl = rtl8169_ioctl, - .ndo_set_multicast_list = rtl_set_rx_mode, + .ndo_set_rx_mode = rtl_set_rx_mode, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = rtl8169_netpoll, #endif diff --git a/drivers/net/ethernet/realtek/sc92031.c b/drivers/net/ethernet/realtek/sc92031.c index 9da47337b7c3..128f8ebb81ec 100644 --- a/drivers/net/ethernet/realtek/sc92031.c +++ b/drivers/net/ethernet/realtek/sc92031.c @@ -1390,7 +1390,7 @@ static const struct net_device_ops sc92031_netdev_ops = { .ndo_start_xmit = sc92031_start_xmit, .ndo_open = sc92031_open, .ndo_stop = sc92031_stop, - .ndo_set_multicast_list = sc92031_set_multicast_list, + .ndo_set_rx_mode = sc92031_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index ad35c210b839..ef3a3521b835 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1758,7 +1758,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { .ndo_start_xmit = sh_eth_start_xmit, .ndo_get_stats = sh_eth_get_stats, #if defined(SH_ETH_HAS_TSU) - .ndo_set_multicast_list = sh_eth_set_multicast_list, + .ndo_set_rx_mode = sh_eth_set_multicast_list, #endif .ndo_tx_timeout = sh_eth_tx_timeout, .ndo_do_ioctl = sh_eth_do_ioctl, diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c index 44a8746f4014..893c880dadf0 100644 --- a/drivers/net/ethernet/seeq/ether3.c +++ b/drivers/net/ethernet/seeq/ether3.c @@ -761,7 +761,7 @@ static const struct net_device_ops ether3_netdev_ops = { .ndo_open = ether3_open, .ndo_stop = ether3_close, .ndo_start_xmit = ether3_sendpacket, - .ndo_set_multicast_list = ether3_setmulticastlist, + .ndo_set_rx_mode = ether3_setmulticastlist, .ndo_tx_timeout = ether3_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/seeq/seeq8005.c b/drivers/net/ethernet/seeq/seeq8005.c index d2fce98f557f..60561451789b 100644 --- a/drivers/net/ethernet/seeq/seeq8005.c +++ b/drivers/net/ethernet/seeq/seeq8005.c @@ -148,7 +148,7 @@ static const struct net_device_ops seeq8005_netdev_ops = { .ndo_stop = seeq8005_close, .ndo_start_xmit = seeq8005_send_packet, .ndo_tx_timeout = seeq8005_timeout, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index 52fb7ed9f365..c3673f151a41 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -715,7 +715,7 @@ static const struct net_device_ops sgiseeq_netdev_ops = { .ndo_stop = sgiseeq_close, .ndo_start_xmit = sgiseeq_start_xmit, .ndo_tx_timeout = timeout, - .ndo_set_multicast_list = sgiseeq_set_multicast, + .ndo_set_rx_mode = sgiseeq_set_multicast, .ndo_set_mac_address = sgiseeq_set_mac_address, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index faca764aa21b..b6b0e71f7fc8 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1903,7 +1903,7 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_do_ioctl = efx_ioctl, .ndo_change_mtu = efx_change_mtu, .ndo_set_mac_address = efx_set_mac_address, - .ndo_set_multicast_list = efx_set_multicast_list, + .ndo_set_rx_mode = efx_set_multicast_list, .ndo_set_features = efx_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index a234e4504522..ac149d99f78f 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c @@ -1220,7 +1220,7 @@ static const struct net_device_ops ioc3_netdev_ops = { .ndo_start_xmit = ioc3_start_xmit, .ndo_tx_timeout = ioc3_timeout, .ndo_get_stats = ioc3_get_stats, - .ndo_set_multicast_list = ioc3_set_multicast_list, + .ndo_set_rx_mode = ioc3_set_multicast_list, .ndo_do_ioctl = ioc3_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ioc3_set_mac_address, diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 3c0f1312b391..1b4658c99391 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c @@ -1841,7 +1841,7 @@ static const struct net_device_ops sis190_netdev_ops = { .ndo_do_ioctl = sis190_ioctl, .ndo_start_xmit = sis190_start_xmit, .ndo_tx_timeout = sis190_tx_timeout, - .ndo_set_multicast_list = sis190_set_rx_mode, + .ndo_set_rx_mode = sis190_set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = sis190_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index 658a1928fe79..a184abc5ef11 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -403,7 +403,7 @@ static const struct net_device_ops sis900_netdev_ops = { .ndo_stop = sis900_close, .ndo_start_xmit = sis900_start_xmit, .ndo_set_config = sis900_set_config, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 814c187d5f95..0a5dfb814157 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -314,7 +314,7 @@ static const struct net_device_ops epic_netdev_ops = { .ndo_start_xmit = epic_start_xmit, .ndo_tx_timeout = epic_tx_timeout, .ndo_get_stats = epic_get_stats, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = netdev_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index a91fe1723020..8f61fe9db1d0 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -1768,7 +1768,7 @@ static const struct net_device_ops smc911x_netdev_ops = { .ndo_stop = smc911x_close, .ndo_start_xmit = smc911x_hard_start_xmit, .ndo_tx_timeout = smc911x_timeout, - .ndo_set_multicast_list = smc911x_set_multicast_list, + .ndo_set_rx_mode = smc911x_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c index 5b65ac4b3cef..4e45094efb18 100644 --- a/drivers/net/ethernet/smsc/smc9194.c +++ b/drivers/net/ethernet/smsc/smc9194.c @@ -827,7 +827,7 @@ static const struct net_device_ops smc_netdev_ops = { .ndo_stop = smc_close, .ndo_start_xmit = smc_wait_to_send_packet, .ndo_tx_timeout = smc_timeout, - .ndo_set_multicast_list = smc_set_multicast_list, + .ndo_set_rx_mode = smc_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c index cffbc0373fa9..cbfa98187131 100644 --- a/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c @@ -294,7 +294,7 @@ static const struct net_device_ops smc_netdev_ops = { .ndo_start_xmit = smc_start_xmit, .ndo_tx_timeout = smc_tx_timeout, .ndo_set_config = s9k_config, - .ndo_set_multicast_list = set_rx_mode, + .ndo_set_rx_mode = set_rx_mode, .ndo_do_ioctl = smc_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 2b1d254d59af..f47f81e25322 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -1768,7 +1768,7 @@ static const struct net_device_ops smc_netdev_ops = { .ndo_stop = smc_close, .ndo_start_xmit = smc_hard_start_xmit, .ndo_tx_timeout = smc_timeout, - .ndo_set_multicast_list = smc_set_multicast_list, + .ndo_set_rx_mode = smc_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 75c08a55582c..788c4fdab9c2 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1906,7 +1906,7 @@ static const struct net_device_ops smsc911x_netdev_ops = { .ndo_stop = smsc911x_stop, .ndo_start_xmit = smsc911x_hard_start_xmit, .ndo_get_stats = smsc911x_get_stats, - .ndo_set_multicast_list = smsc911x_set_multicast_list, + .ndo_set_rx_mode = smsc911x_set_multicast_list, .ndo_do_ioctl = smsc911x_do_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index 459726f54754..4f15680849ff 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -1566,7 +1566,7 @@ static const struct net_device_ops smsc9420_netdev_ops = { .ndo_stop = smsc9420_stop, .ndo_start_xmit = smsc9420_hard_start_xmit, .ndo_get_stats = smsc9420_get_stats, - .ndo_set_multicast_list = smsc9420_set_multicast_list, + .ndo_set_rx_mode = smsc9420_set_multicast_list, .ndo_do_ioctl = smsc9420_do_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 646c86bcc545..1776a37b7aed 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -4910,7 +4910,7 @@ static const struct net_device_ops cas_netdev_ops = { .ndo_stop = cas_close, .ndo_start_xmit = cas_start_xmit, .ndo_get_stats = cas_get_stats, - .ndo_set_multicast_list = cas_set_multicast, + .ndo_set_rx_mode = cas_set_multicast, .ndo_do_ioctl = cas_ioctl, .ndo_tx_timeout = cas_tx_timeout, .ndo_change_mtu = cas_change_mtu, diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c index 297a4242106b..c94f5ef348d4 100644 --- a/drivers/net/ethernet/sun/sunbmac.c +++ b/drivers/net/ethernet/sun/sunbmac.c @@ -1070,7 +1070,7 @@ static const struct net_device_ops bigmac_ops = { .ndo_stop = bigmac_close, .ndo_start_xmit = bigmac_start_xmit, .ndo_get_stats = bigmac_get_stats, - .ndo_set_multicast_list = bigmac_set_multicast, + .ndo_set_rx_mode = bigmac_set_multicast, .ndo_tx_timeout = bigmac_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index fb9885dd36da..11fd299f5b99 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2820,7 +2820,7 @@ static const struct net_device_ops gem_netdev_ops = { .ndo_stop = gem_close, .ndo_start_xmit = gem_start_xmit, .ndo_get_stats = gem_get_stats, - .ndo_set_multicast_list = gem_set_multicast, + .ndo_set_rx_mode = gem_set_multicast, .ndo_do_ioctl = gem_ioctl, .ndo_tx_timeout = gem_tx_timeout, .ndo_change_mtu = gem_change_mtu, diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 856e05b9fba3..42f866ef81e1 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2619,7 +2619,7 @@ static const struct net_device_ops hme_netdev_ops = { .ndo_start_xmit = happy_meal_start_xmit, .ndo_tx_timeout = happy_meal_tx_timeout, .ndo_get_stats = happy_meal_get_stats, - .ndo_set_multicast_list = happy_meal_set_multicast, + .ndo_set_rx_mode = happy_meal_set_multicast, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 209c7f8df003..b28f74367ebe 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -824,7 +824,7 @@ static const struct net_device_ops qec_ops = { .ndo_open = qe_open, .ndo_stop = qe_close, .ndo_start_xmit = qe_start_xmit, - .ndo_set_multicast_list = qe_set_multicast, + .ndo_set_rx_mode = qe_set_multicast, .ndo_tx_timeout = qe_tx_timeout, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index bf3c762de620..8c6c059f3489 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -1012,7 +1012,7 @@ static DEFINE_MUTEX(vnet_list_mutex); static const struct net_device_ops vnet_ops = { .ndo_open = vnet_open, .ndo_stop = vnet_close, - .ndo_set_multicast_list = vnet_set_rx_mode, + .ndo_set_rx_mode = vnet_set_rx_mode, .ndo_set_mac_address = vnet_set_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = vnet_tx_timeout, diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 749bbf18dc6a..bc65aa8de4d0 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1860,7 +1860,7 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_start_xmit = bdx_tx_transmit, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = bdx_ioctl, - .ndo_set_multicast_list = bdx_setmulti, + .ndo_set_rx_mode = bdx_setmulti, .ndo_change_mtu = bdx_change_mtu, .ndo_set_mac_address = bdx_set_mac, .ndo_vlan_rx_add_vid = bdx_vlan_rx_add_vid, diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c index e0638cb4b07c..aaac0c7ad111 100644 --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c @@ -1100,7 +1100,7 @@ static const struct net_device_ops cpmac_netdev_ops = { .ndo_stop = cpmac_stop, .ndo_start_xmit = cpmac_start_xmit, .ndo_tx_timeout = cpmac_tx_timeout, - .ndo_set_multicast_list = cpmac_set_multicast_list, + .ndo_set_rx_mode = cpmac_set_multicast_list, .ndo_do_ioctl = cpmac_ioctl, .ndo_set_config = cpmac_config, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 3f451e4d8361..815c7970261b 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1741,7 +1741,7 @@ static const struct net_device_ops emac_netdev_ops = { .ndo_open = emac_dev_open, .ndo_stop = emac_dev_stop, .ndo_start_xmit = emac_dev_xmit, - .ndo_set_multicast_list = emac_dev_mcast_set, + .ndo_set_rx_mode = emac_dev_mcast_set, .ndo_set_mac_address = emac_dev_setmac_addr, .ndo_do_ioctl = emac_devioctl, .ndo_tx_timeout = emac_dev_tx_timeout, diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 145871b3130b..9c0dd6b8d6c9 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -774,7 +774,7 @@ static const struct net_device_ops tlan_netdev_ops = { .ndo_start_xmit = tlan_start_tx, .ndo_tx_timeout = tlan_tx_timeout, .ndo_get_stats = tlan_get_stats, - .ndo_set_multicast_list = tlan_set_multicast_list, + .ndo_set_rx_mode = tlan_set_multicast_list, .ndo_do_ioctl = tlan_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index d82a82d9870c..ddb33cfd3543 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -1452,7 +1452,7 @@ static const struct net_device_ops gelic_netdevice_ops = { .ndo_open = gelic_net_open, .ndo_stop = gelic_net_stop, .ndo_start_xmit = gelic_net_xmit, - .ndo_set_multicast_list = gelic_net_set_multi, + .ndo_set_rx_mode = gelic_net_set_multi, .ndo_change_mtu = gelic_net_change_mtu, .ndo_tx_timeout = gelic_net_tx_timeout, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 2e62938c0f82..fd4ed7f8cfa1 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -2568,7 +2568,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = { .ndo_open = gelic_wl_open, .ndo_stop = gelic_wl_stop, .ndo_start_xmit = gelic_net_xmit, - .ndo_set_multicast_list = gelic_net_set_multi, + .ndo_set_rx_mode = gelic_net_set_multi, .ndo_change_mtu = gelic_net_change_mtu, .ndo_tx_timeout = gelic_net_tx_timeout, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c index af345dbd1210..6199f6b387b6 100644 --- a/drivers/net/ethernet/toshiba/spider_net.c +++ b/drivers/net/ethernet/toshiba/spider_net.c @@ -2259,7 +2259,7 @@ static const struct net_device_ops spider_net_ops = { .ndo_open = spider_net_open, .ndo_stop = spider_net_stop, .ndo_start_xmit = spider_net_xmit, - .ndo_set_multicast_list = spider_net_set_multi, + .ndo_set_rx_mode = spider_net_set_multi, .ndo_set_mac_address = spider_net_set_mac, .ndo_change_mtu = spider_net_change_mtu, .ndo_do_ioctl = spider_net_do_ioctl, diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index 4a55a162dfe6..71b785cd7563 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -774,7 +774,7 @@ static const struct net_device_ops tc35815_netdev_ops = { .ndo_stop = tc35815_close, .ndo_start_xmit = tc35815_send_packet, .ndo_get_stats = tc35815_get_stats, - .ndo_set_multicast_list = tc35815_set_multicast_list, + .ndo_set_rx_mode = tc35815_set_multicast_list, .ndo_tx_timeout = tc35815_tx_timeout, .ndo_do_ioctl = tc35815_ioctl, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 64cb9ac19ed9..480a4ba53172 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1554,7 +1554,7 @@ static const struct net_device_ops tsi108_netdev_ops = { .ndo_open = tsi108_open, .ndo_stop = tsi108_close, .ndo_start_xmit = tsi108_send_packet, - .ndo_set_multicast_list = tsi108_set_rx_mode, + .ndo_set_rx_mode = tsi108_set_rx_mode, .ndo_get_stats = tsi108_get_stats, .ndo_do_ioctl = tsi108_do_ioctl, .ndo_set_mac_address = tsi108_set_mac, diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 7f23ab913fd9..f34dd99fe579 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -697,7 +697,7 @@ static const struct net_device_ops rhine_netdev_ops = { .ndo_stop = rhine_close, .ndo_start_xmit = rhine_start_tx, .ndo_get_stats = rhine_get_stats, - .ndo_set_multicast_list = rhine_set_rx_mode, + .ndo_set_rx_mode = rhine_set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 490ec5b2775a..095ab566d082 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2615,7 +2615,7 @@ static const struct net_device_ops velocity_netdev_ops = { .ndo_get_stats = velocity_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, - .ndo_set_multicast_list = velocity_set_multi, + .ndo_set_rx_mode = velocity_set_multi, .ndo_change_mtu = velocity_change_mtu, .ndo_do_ioctl = velocity_ioctl, .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid, diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 728fe414147a..570776edc01b 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -922,7 +922,6 @@ static const struct net_device_ops temac_netdev_ops = { .ndo_start_xmit = temac_start_xmit, .ndo_set_mac_address = netdev_set_mac_address, .ndo_validate_addr = eth_validate_addr, - //.ndo_set_multicast_list = temac_set_multicast_list, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = temac_poll_controller, #endif diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index e33b190d716f..bbe8b7dbf3f3 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -467,7 +467,7 @@ static const struct net_device_ops netdev_ops = { .ndo_tx_timeout = xirc_tx_timeout, .ndo_set_config = do_config, .ndo_do_ioctl = do_ioctl, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index de51e8453c13..ec96d910e9a3 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1339,7 +1339,7 @@ static const struct net_device_ops ixp4xx_netdev_ops = { .ndo_open = eth_open, .ndo_stop = eth_close, .ndo_start_xmit = eth_xmit, - .ndo_set_multicast_list = eth_set_mcast_list, + .ndo_set_rx_mode = eth_set_mcast_list, .ndo_do_ioctl = eth_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 05172c39a0ce..836e13fcb3ec 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -561,7 +561,7 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_change_mtu = macvlan_change_mtu, .ndo_change_rx_flags = macvlan_change_rx_flags, .ndo_set_mac_address = macvlan_set_mac_address, - .ndo_set_multicast_list = macvlan_set_multicast_list, + .ndo_set_rx_mode = macvlan_set_multicast_list, .ndo_get_stats64 = macvlan_dev_get_stats64, .ndo_validate_addr = eth_validate_addr, .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid, diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 16c62659cdd9..3d9a4596a423 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -167,7 +167,7 @@ static const struct net_device_ops skfp_netdev_ops = { .ndo_start_xmit = skfp_send_pkt, .ndo_get_stats = skfp_ctl_get_stats, .ndo_change_mtu = fddi_change_mtu, - .ndo_set_multicast_list = skfp_ctl_set_multicast_list, + .ndo_set_rx_mode = skfp_ctl_set_multicast_list, .ndo_set_mac_address = skfp_ctl_set_mac_address, .ndo_do_ioctl = skfp_ioctl, }; diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index b6162fe2348e..ef9fdf3652f6 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -282,7 +282,7 @@ static const struct net_device_ops xl_netdev_ops = { .ndo_stop = xl_close, .ndo_start_xmit = xl_xmit, .ndo_change_mtu = xl_change_mtu, - .ndo_set_multicast_list = xl_set_rx_mode, + .ndo_set_rx_mode = xl_set_rx_mode, .ndo_set_mac_address = xl_set_mac_address, }; diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index e257a00fe14b..b5c8c18f5046 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -823,7 +823,7 @@ static const struct net_device_ops trdev_netdev_ops = { .ndo_open = tok_open, .ndo_stop = tok_close, .ndo_start_xmit = tok_send_packet, - .ndo_set_multicast_list = tok_set_multicast_list, + .ndo_set_rx_mode = tok_set_multicast_list, .ndo_change_mtu = ibmtr_change_mtu, }; diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index 9354ca9da576..8d71e0d29062 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -231,7 +231,7 @@ static const struct net_device_ops streamer_netdev_ops = { #if STREAMER_IOCTL .ndo_do_ioctl = streamer_ioctl, #endif - .ndo_set_multicast_list = streamer_set_rx_mode, + .ndo_set_rx_mode = streamer_set_rx_mode, .ndo_set_mac_address = streamer_set_mac_address, }; diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index e3855aeb13d4..fd8dce90c957 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -201,7 +201,7 @@ static const struct net_device_ops olympic_netdev_ops = { .ndo_stop = olympic_close, .ndo_start_xmit = olympic_xmit, .ndo_change_mtu = olympic_change_mtu, - .ndo_set_multicast_list = olympic_set_rx_mode, + .ndo_set_rx_mode = olympic_set_rx_mode, .ndo_set_mac_address = olympic_set_mac_address, }; diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index d9044aba7afa..029846a98636 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -3623,7 +3623,7 @@ static const struct net_device_ops smctr_netdev_ops = { .ndo_start_xmit = smctr_send_packet, .ndo_tx_timeout = smctr_timeout, .ndo_get_stats = smctr_get_stats, - .ndo_set_multicast_list = smctr_set_multicast_list, + .ndo_set_rx_mode = smctr_set_multicast_list, }; static int __init smctr_probe1(struct net_device *dev, int ioaddr) diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 793020347e54..65e9cf3a71fe 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -2289,7 +2289,7 @@ const struct net_device_ops tms380tr_netdev_ops = { .ndo_start_xmit = tms380tr_send_packet, .ndo_tx_timeout = tms380tr_timeout, .ndo_get_stats = tms380tr_get_stats, - .ndo_set_multicast_list = tms380tr_set_multicast_list, + .ndo_set_rx_mode = tms380tr_set_multicast_list, .ndo_set_mac_address = tms380tr_set_mac_address, }; EXPORT_SYMBOL(tms380tr_netdev_ops); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 71f3d1a35b74..7bea9c65119e 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -496,7 +496,7 @@ static const struct net_device_ops tap_netdev_ops = { .ndo_start_xmit = tun_net_xmit, .ndo_change_mtu = tun_net_change_mtu, .ndo_fix_features = tun_net_fix_features, - .ndo_set_multicast_list = tun_net_mclist, + .ndo_set_rx_mode = tun_net_mclist, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index c5c4b4def7fb..b843eedd409d 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -872,7 +872,7 @@ static const struct net_device_ops ax88172_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = asix_ioctl, - .ndo_set_multicast_list = ax88172_set_multicast, + .ndo_set_rx_mode = ax88172_set_multicast, }; static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) @@ -975,7 +975,7 @@ static const struct net_device_ops ax88772_netdev_ops = { .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = asix_ioctl, - .ndo_set_multicast_list = asix_set_multicast, + .ndo_set_rx_mode = asix_set_multicast, }; static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) @@ -1270,7 +1270,7 @@ static const struct net_device_ops ax88178_netdev_ops = { .ndo_tx_timeout = usbnet_tx_timeout, .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = asix_set_multicast, + .ndo_set_rx_mode = asix_set_multicast, .ndo_do_ioctl = asix_ioctl, .ndo_change_mtu = ax88178_change_mtu, }; diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 8056f8a27c6a..a68272c93381 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -749,7 +749,7 @@ static const struct net_device_ops catc_netdev_ops = { .ndo_start_xmit = catc_start_xmit, .ndo_tx_timeout = catc_tx_timeout, - .ndo_set_multicast_list = catc_set_multicast_list, + .ndo_set_rx_mode = catc_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 1d93133e9b74..fbc0e4def767 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -428,7 +428,7 @@ static const struct net_device_ops dm9601_netdev_ops = { .ndo_change_mtu = usbnet_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = dm9601_ioctl, - .ndo_set_multicast_list = dm9601_set_multicast, + .ndo_set_rx_mode = dm9601_set_multicast, .ndo_set_mac_address = dm9601_set_mac_address, }; diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index be02a25da71a..131ac6c172f6 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c @@ -193,7 +193,7 @@ static const struct net_device_ops int51x1_netdev_ops = { .ndo_change_mtu = usbnet_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = int51x1_set_multicast, + .ndo_set_rx_mode = int51x1_set_multicast, }; static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf) diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index ad0298f9b5f9..582ca2dfa5f9 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -985,7 +985,7 @@ static const struct net_device_ops kaweth_netdev_ops = { .ndo_stop = kaweth_close, .ndo_start_xmit = kaweth_start_xmit, .ndo_tx_timeout = kaweth_tx_timeout, - .ndo_set_multicast_list = kaweth_set_rx_mode, + .ndo_set_rx_mode = kaweth_set_rx_mode, .ndo_get_stats = kaweth_netdev_stats, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 2b791392e788..db2cb74bf854 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -553,7 +553,7 @@ static const struct net_device_ops mcs7830_netdev_ops = { .ndo_change_mtu = usbnet_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = mcs7830_ioctl, - .ndo_set_multicast_list = mcs7830_set_multicast, + .ndo_set_rx_mode = mcs7830_set_multicast, .ndo_set_mac_address = mcs7830_set_mac_address, }; diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index ef3667690b12..769f5090bda1 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1476,7 +1476,7 @@ static const struct net_device_ops pegasus_netdev_ops = { .ndo_stop = pegasus_close, .ndo_do_ioctl = pegasus_ioctl, .ndo_start_xmit = pegasus_start_xmit, - .ndo_set_multicast_list = pegasus_set_multicast, + .ndo_set_rx_mode = pegasus_set_multicast, .ndo_get_stats = pegasus_netdev_stats, .ndo_tx_timeout = pegasus_tx_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index ef3b236b5145..b00d692587a2 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -899,7 +899,7 @@ static const struct net_device_ops rtl8150_netdev_ops = { .ndo_do_ioctl = rtl8150_ioctl, .ndo_start_xmit = rtl8150_start_xmit, .ndo_tx_timeout = rtl8150_tx_timeout, - .ndo_set_multicast_list = rtl8150_set_multicast, + .ndo_set_rx_mode = rtl8150_set_multicast, .ndo_set_mac_address = rtl8150_set_mac_address, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 15b3d6888ae9..22a7cf951e72 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1000,7 +1000,7 @@ static const struct net_device_ops smsc75xx_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = smsc75xx_ioctl, - .ndo_set_multicast_list = smsc75xx_set_multicast, + .ndo_set_rx_mode = smsc75xx_set_multicast, .ndo_set_features = smsc75xx_set_features, }; diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index f74f3ce71526..eff67678c5a6 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -972,7 +972,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = smsc95xx_ioctl, - .ndo_set_multicast_list = smsc95xx_set_multicast, + .ndo_set_rx_mode = smsc95xx_set_multicast, .ndo_set_features = smsc95xx_set_features, }; diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 1cbacb389652..f530c57151b2 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2870,7 +2870,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, .ndo_set_features = vmxnet3_set_features, .ndo_get_stats64 = vmxnet3_get_stats64, .ndo_tx_timeout = vmxnet3_tx_timeout, - .ndo_set_multicast_list = vmxnet3_set_mc, + .ndo_set_rx_mode = vmxnet3_set_mc, .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 86127bcc9f7a..783168cce077 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -212,7 +212,7 @@ static const struct net_device_ops sbni_netdev_ops = { .ndo_open = sbni_open, .ndo_stop = sbni_close, .ndo_start_xmit = sbni_start_xmit, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_do_ioctl = sbni_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index e1b3e3c134fd..ac1176a4f465 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2754,7 +2754,7 @@ static const struct net_device_ops airo_netdev_ops = { .ndo_stop = airo_close, .ndo_start_xmit = airo_start_xmit, .ndo_get_stats = airo_get_stats, - .ndo_set_multicast_list = airo_set_multicast_list, + .ndo_set_rx_mode = airo_set_multicast_list, .ndo_set_mac_address = airo_set_mac_address, .ndo_do_ioctl = airo_ioctl, .ndo_change_mtu = airo_change_mtu, @@ -2766,7 +2766,7 @@ static const struct net_device_ops mpi_netdev_ops = { .ndo_stop = airo_close, .ndo_start_xmit = mpi_start_xmit, .ndo_get_stats = airo_get_stats, - .ndo_set_multicast_list = airo_set_multicast_list, + .ndo_set_rx_mode = airo_set_multicast_list, .ndo_set_mac_address = airo_set_mac_address, .ndo_do_ioctl = airo_ioctl, .ndo_change_mtu = airo_change_mtu, diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 89a116fba1de..bfa0d54221e8 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -816,7 +816,7 @@ static const struct net_device_ops hostap_netdev_ops = { .ndo_stop = prism2_close, .ndo_do_ioctl = hostap_ioctl, .ndo_set_mac_address = prism2_set_mac_address, - .ndo_set_multicast_list = hostap_set_multicast_list, + .ndo_set_rx_mode = hostap_set_multicast_list, .ndo_change_mtu = prism2_change_mtu, .ndo_tx_timeout = prism2_tx_timeout, .ndo_validate_addr = eth_validate_addr, @@ -829,7 +829,7 @@ static const struct net_device_ops hostap_mgmt_netdev_ops = { .ndo_stop = prism2_close, .ndo_do_ioctl = hostap_ioctl, .ndo_set_mac_address = prism2_set_mac_address, - .ndo_set_multicast_list = hostap_set_multicast_list, + .ndo_set_rx_mode = hostap_set_multicast_list, .ndo_change_mtu = prism2_change_mtu, .ndo_tx_timeout = prism2_tx_timeout, .ndo_validate_addr = eth_validate_addr, @@ -842,7 +842,7 @@ static const struct net_device_ops hostap_master_ops = { .ndo_stop = prism2_close, .ndo_do_ioctl = hostap_ioctl, .ndo_set_mac_address = prism2_set_mac_address, - .ndo_set_multicast_list = hostap_set_multicast_list, + .ndo_set_rx_mode = hostap_set_multicast_list, .ndo_change_mtu = prism2_change_mtu, .ndo_tx_timeout = prism2_tx_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 87813c33bdc2..553f66b67c16 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11701,7 +11701,7 @@ static const struct net_device_ops ipw_netdev_ops = { .ndo_init = ipw_net_init, .ndo_open = ipw_net_open, .ndo_stop = ipw_net_stop, - .ndo_set_multicast_list = ipw_net_set_multicast_list, + .ndo_set_rx_mode = ipw_net_set_multicast_list, .ndo_set_mac_address = ipw_net_set_mac_address, .ndo_start_xmit = libipw_xmit, .ndo_change_mtu = libipw_change_mtu, diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 94652c5a25de..2fdeb81ce5b2 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -786,7 +786,7 @@ static const struct net_device_ops lbs_netdev_ops = { .ndo_stop = lbs_eth_stop, .ndo_start_xmit = lbs_hard_start_xmit, .ndo_set_mac_address = lbs_set_mac_address, - .ndo_set_multicast_list = lbs_set_multicast_list, + .ndo_set_rx_mode = lbs_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, }; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index be72c08ea2a7..8e3104d990fb 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -959,7 +959,7 @@ static const struct net_device_ops mesh_netdev_ops = { .ndo_stop = lbs_mesh_stop, .ndo_start_xmit = lbs_hard_start_xmit, .ndo_set_mac_address = lbs_set_mac_address, - .ndo_set_multicast_list = lbs_set_multicast_list, + .ndo_set_rx_mode = lbs_set_multicast_list, }; /** diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index e5fc53dc6887..0415e3d1c317 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -627,7 +627,7 @@ static const struct net_device_ops mwifiex_netdev_ops = { .ndo_set_mac_address = mwifiex_set_mac_address, .ndo_tx_timeout = mwifiex_tx_timeout, .ndo_get_stats = mwifiex_get_stats, - .ndo_set_multicast_list = mwifiex_set_multicast_list, + .ndo_set_rx_mode = mwifiex_set_multicast_list, }; /* diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index ef7efe839bb8..b52acc4b4086 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -2135,7 +2135,7 @@ static const struct net_device_ops orinoco_netdev_ops = { .ndo_open = orinoco_open, .ndo_stop = orinoco_stop, .ndo_start_xmit = orinoco_xmit, - .ndo_set_multicast_list = orinoco_set_multicast_list, + .ndo_set_rx_mode = orinoco_set_multicast_list, .ndo_change_mtu = orinoco_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index 811e87f8a349..0793e4265b43 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1562,7 +1562,7 @@ static const struct net_device_ops ezusb_netdev_ops = { .ndo_open = orinoco_open, .ndo_stop = orinoco_stop, .ndo_start_xmit = ezusb_xmit, - .ndo_set_multicast_list = orinoco_set_multicast_list, + .ndo_set_rx_mode = orinoco_set_multicast_list, .ndo_change_mtu = orinoco_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 2a06ebcd67c5..0021e4948512 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -273,7 +273,7 @@ static const struct net_device_ops ray_netdev_ops = { .ndo_start_xmit = ray_dev_start_xmit, .ndo_set_config = ray_dev_config, .ndo_get_stats = ray_get_stats, - .ndo_set_multicast_list = set_multicast_list, + .ndo_set_rx_mode = set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 29f938930667..6e0c61145b18 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -3392,7 +3392,7 @@ static const struct net_device_ops rndis_wlan_netdev_ops = { .ndo_tx_timeout = usbnet_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = rndis_wlan_set_multicast_list, + .ndo_set_rx_mode = rndis_wlan_set_multicast_list, }; static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 415eec401e2e..8efa2f2d9579 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -1722,7 +1722,7 @@ static const struct net_device_ops zd1201_netdev_ops = { .ndo_stop = zd1201_net_stop, .ndo_start_xmit = zd1201_hard_start_xmit, .ndo_tx_timeout = zd1201_tx_timeout, - .ndo_set_multicast_list = zd1201_set_multicast, + .ndo_set_rx_mode = zd1201_set_multicast, .ndo_set_mac_address = zd1201_set_mac_address, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index c3b8064a102d..fb246b944b16 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -2122,7 +2122,7 @@ static const struct net_device_ops lcs_mc_netdev_ops = { .ndo_stop = lcs_stop_device, .ndo_get_stats = lcs_getstats, .ndo_start_xmit = lcs_start_xmit, - .ndo_set_multicast_list = lcs_set_multicast_list, + .ndo_set_rx_mode = lcs_set_multicast_list, }; static int diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 3e68b66dc43e..a21ae3d549db 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -925,7 +925,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = { .ndo_get_stats = qeth_get_stats, .ndo_start_xmit = qeth_l2_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = qeth_l2_set_multicast_list, + .ndo_set_rx_mode = qeth_l2_set_multicast_list, .ndo_do_ioctl = qeth_l2_do_ioctl, .ndo_set_mac_address = qeth_l2_set_mac_address, .ndo_change_mtu = qeth_change_mtu, diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e2a927ae002a..ce735204d317 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3275,7 +3275,7 @@ static const struct net_device_ops qeth_l3_netdev_ops = { .ndo_get_stats = qeth_get_stats, .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = qeth_l3_set_multicast_list, + .ndo_set_rx_mode = qeth_l3_set_multicast_list, .ndo_do_ioctl = qeth_l3_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_l3_fix_features, @@ -3291,7 +3291,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_get_stats = qeth_get_stats, .ndo_start_xmit = qeth_l3_hard_start_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = qeth_l3_set_multicast_list, + .ndo_set_rx_mode = qeth_l3_set_multicast_list, .ndo_do_ioctl = qeth_l3_do_ioctl, .ndo_change_mtu = qeth_change_mtu, .ndo_fix_features = qeth_l3_fix_features, diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 32ee39ad00df..9b02895a152e 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -368,7 +368,7 @@ static struct net_device_ops ar6000_netdev_ops = { .ndo_stop = ar6000_close, .ndo_get_stats = ar6000_get_stats, .ndo_start_xmit = ar6000_data_tx, - .ndo_set_multicast_list = ar6000_set_multicast_list, + .ndo_set_rx_mode = ar6000_set_multicast_list, }; /* Debug log support */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 05dada98eb6b..b1294017dd7b 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1437,7 +1437,7 @@ static struct net_device_ops brcmf_netdev_ops_pri = { .ndo_do_ioctl = brcmf_netdev_ioctl_entry, .ndo_start_xmit = brcmf_netdev_start_xmit, .ndo_set_mac_address = brcmf_netdev_set_mac_address, - .ndo_set_multicast_list = brcmf_netdev_set_multicast_list + .ndo_set_rx_mode = brcmf_netdev_set_multicast_list, }; int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 5f25bbad36b6..4406630b0c6f 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -638,7 +638,7 @@ static const struct net_device_ops et131x_netdev_ops = { .ndo_open = et131x_open, .ndo_stop = et131x_close, .ndo_start_xmit = et131x_tx, - .ndo_set_multicast_list = et131x_multicast, + .ndo_set_rx_mode = et131x_multicast, .ndo_tx_timeout = et131x_tx_timeout, .ndo_change_mtu = et131x_change_mtu, .ndo_set_mac_address = et131x_set_mac_addr, diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 61989f0d9f0d..bfd4c81c410f 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -307,7 +307,7 @@ static const struct net_device_ops device_ops = { .ndo_open = netvsc_open, .ndo_stop = netvsc_close, .ndo_start_xmit = netvsc_start_xmit, - .ndo_set_multicast_list = netvsc_set_multicast_list, + .ndo_set_rx_mode = netvsc_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index a8f780e95e0a..076f86675ce6 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -512,7 +512,7 @@ static const struct net_device_ops cvm_oct_npi_netdev_ops = { .ndo_init = cvm_oct_common_init, .ndo_uninit = cvm_oct_common_uninit, .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, @@ -527,7 +527,7 @@ static const struct net_device_ops cvm_oct_xaui_netdev_ops = { .ndo_open = cvm_oct_xaui_open, .ndo_stop = cvm_oct_xaui_stop, .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, @@ -542,7 +542,7 @@ static const struct net_device_ops cvm_oct_sgmii_netdev_ops = { .ndo_open = cvm_oct_sgmii_open, .ndo_stop = cvm_oct_sgmii_stop, .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, @@ -555,7 +555,7 @@ static const struct net_device_ops cvm_oct_spi_netdev_ops = { .ndo_init = cvm_oct_spi_init, .ndo_uninit = cvm_oct_spi_uninit, .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, @@ -570,7 +570,7 @@ static const struct net_device_ops cvm_oct_rgmii_netdev_ops = { .ndo_open = cvm_oct_rgmii_open, .ndo_stop = cvm_oct_rgmii_stop, .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, @@ -582,7 +582,7 @@ static const struct net_device_ops cvm_oct_rgmii_netdev_ops = { static const struct net_device_ops cvm_oct_pow_netdev_ops = { .ndo_init = cvm_oct_common_init, .ndo_start_xmit = cvm_oct_xmit_pow, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, + .ndo_set_rx_mode = cvm_oct_common_set_multicast_list, .ndo_set_mac_address = cvm_oct_common_set_mac_address, .ndo_do_ioctl = cvm_oct_ioctl, .ndo_change_mtu = cvm_oct_common_change_mtu, diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 4c6651aac307..04c23919f4d6 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -3534,7 +3534,7 @@ static const struct net_device_ops rtl8180_netdev_ops = { .ndo_get_stats = rtl8180_stats, .ndo_tx_timeout = rtl8180_restart, .ndo_do_ioctl = rtl8180_ioctl, - .ndo_set_multicast_list = r8180_set_multicast, + .ndo_set_rx_mode = r8180_set_multicast, .ndo_set_mac_address = r8180_set_mac_adr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 94d9c8d5d090..b418fed703c6 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4519,7 +4519,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { .ndo_stop = rtl8192_close, .ndo_tx_timeout = tx_timeout, .ndo_do_ioctl = rtl8192_ioctl, - .ndo_set_multicast_list = r8192_set_multicast, + .ndo_set_rx_mode = r8192_set_multicast, .ndo_set_mac_address = r8192_set_mac_adr, .ndo_start_xmit = ieee80211_rtl_xmit, }; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index ee86fe8509ed..c09be0a66467 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -5739,7 +5739,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { .ndo_get_stats = rtl8192_stats, .ndo_tx_timeout = tx_timeout, .ndo_do_ioctl = rtl8192_ioctl, - .ndo_set_multicast_list = r8192_set_multicast, + .ndo_set_rx_mode = r8192_set_multicast, .ndo_set_mac_address = r8192_set_mac_adr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 18f11039bb5f..77a0751a31ad 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3724,7 +3724,7 @@ static const struct net_device_ops slic_netdev_ops = { .ndo_do_ioctl = slic_ioctl, .ndo_set_mac_address = slic_mac_set_address, .ndo_get_stats = slic_get_stats, - .ndo_set_multicast_list = slic_mcast_set_list, + .ndo_set_rx_mode = slic_mcast_set_list, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, }; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 3d2a9ba16b15..8cb9116c44f8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -911,7 +911,7 @@ static const struct net_device_ops device_netdev_ops = { .ndo_do_ioctl = device_ioctl, .ndo_get_stats = device_get_stats, .ndo_start_xmit = device_xmit, - .ndo_set_multicast_list = device_set_multi, + .ndo_set_rx_mode = device_set_multi, }; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index e18efd43e3e0..1ff394074cba 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -753,7 +753,7 @@ static const struct net_device_ops device_netdev_ops = { .ndo_do_ioctl = device_ioctl, .ndo_get_stats = device_get_stats, .ndo_start_xmit = device_xmit, - .ndo_set_multicast_list = device_set_multi, + .ndo_set_rx_mode = device_set_multi, }; static int __devinit diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index cf917e613f22..b21515ff678a 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1179,7 +1179,7 @@ static const struct net_device_ops wl_netdev_ops = .ndo_set_config = &wl_config, .ndo_get_stats = &wl_stats, - .ndo_set_multicast_list = &wl_multicast, + .ndo_set_rx_mode = &wl_multicast, .ndo_init = &wl_insert, .ndo_open = &wl_adapter_open, diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index b0af292bc7e3..14bfeb2e704c 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -715,7 +715,7 @@ static const struct net_device_ops p80211_netdev_ops = { .ndo_stop = p80211knetdev_stop, .ndo_get_stats = p80211knetdev_get_stats, .ndo_start_xmit = p80211knetdev_hard_start_xmit, - .ndo_set_multicast_list = p80211knetdev_set_multicast_list, + .ndo_set_rx_mode = p80211knetdev_set_multicast_list, .ndo_do_ioctl = p80211knetdev_do_ioctl, .ndo_set_mac_address = p80211knetdev_set_mac_address, .ndo_tx_timeout = p80211knetdev_tx_timeout, diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9d40a071d038..eba705b92d6f 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -674,7 +674,6 @@ static const struct net_device_ops vlan_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = vlan_dev_set_mac_address, .ndo_set_rx_mode = vlan_dev_set_rx_mode, - .ndo_set_multicast_list = vlan_dev_set_rx_mode, .ndo_change_rx_flags = vlan_dev_change_rx_flags, .ndo_do_ioctl = vlan_dev_ioctl, .ndo_neigh_setup = vlan_dev_neigh_setup, diff --git a/net/atm/lec.c b/net/atm/lec.c index 215c9fad7cdf..f1964caa0f83 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -643,7 +643,7 @@ static const struct net_device_ops lec_netdev_ops = { .ndo_start_xmit = lec_start_xmit, .ndo_change_mtu = lec_change_mtu, .ndo_tx_timeout = lec_tx_timeout, - .ndo_set_multicast_list = lec_set_multicast_list, + .ndo_set_rx_mode = lec_set_multicast_list, }; static const unsigned char lec_ctrl_magic[] = { diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index d4f5dff7c955..bc4086480d97 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -217,7 +217,7 @@ static const struct net_device_ops bnep_netdev_ops = { .ndo_stop = bnep_net_close, .ndo_start_xmit = bnep_net_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = bnep_net_set_mc_list, + .ndo_set_rx_mode = bnep_net_set_mc_list, .ndo_set_mac_address = bnep_net_set_mac_addr, .ndo_tx_timeout = bnep_net_timeout, .ndo_change_mtu = eth_change_mtu, diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 32b8f9f7f79e..ee68eee79e52 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -304,7 +304,7 @@ static const struct net_device_ops br_netdev_ops = { .ndo_start_xmit = br_dev_xmit, .ndo_get_stats64 = br_get_stats64, .ndo_set_mac_address = br_set_mac_address, - .ndo_set_multicast_list = br_dev_set_multicast_list, + .ndo_set_rx_mode = br_dev_set_multicast_list, .ndo_change_mtu = br_change_mtu, .ndo_do_ioctl = br_dev_ioctl, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 0a47b6c37038..56cf9b8e1c7c 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -301,7 +301,6 @@ static const struct net_device_ops dsa_netdev_ops = { .ndo_start_xmit = dsa_xmit, .ndo_change_rx_flags = dsa_slave_change_rx_flags, .ndo_set_rx_mode = dsa_slave_set_rx_mode, - .ndo_set_multicast_list = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, .ndo_do_ioctl = dsa_slave_ioctl, }; @@ -314,7 +313,6 @@ static const struct net_device_ops edsa_netdev_ops = { .ndo_start_xmit = edsa_xmit, .ndo_change_rx_flags = dsa_slave_change_rx_flags, .ndo_set_rx_mode = dsa_slave_set_rx_mode, - .ndo_set_multicast_list = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, .ndo_do_ioctl = dsa_slave_ioctl, }; @@ -327,7 +325,6 @@ static const struct net_device_ops trailer_netdev_ops = { .ndo_start_xmit = trailer_xmit, .ndo_change_rx_flags = dsa_slave_change_rx_flags, .ndo_set_rx_mode = dsa_slave_set_rx_mode, - .ndo_set_multicast_list = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, .ndo_do_ioctl = dsa_slave_ioctl, }; diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index e8d5f4405d68..d14152e866d9 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -50,7 +50,7 @@ static const struct net_device_ops irlan_eth_netdev_ops = { .ndo_open = irlan_eth_open, .ndo_stop = irlan_eth_close, .ndo_start_xmit = irlan_eth_xmit, - .ndo_set_multicast_list = irlan_eth_set_multicast_list, + .ndo_set_rx_mode = irlan_eth_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, }; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index c798b434eb64..d10dc4df60b6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -645,7 +645,7 @@ static const struct net_device_ops ieee80211_dataif_ops = { .ndo_stop = ieee80211_stop, .ndo_uninit = ieee80211_teardown_sdata, .ndo_start_xmit = ieee80211_subif_start_xmit, - .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_set_rx_mode = ieee80211_set_multicast_list, .ndo_change_mtu = ieee80211_change_mtu, .ndo_set_mac_address = ieee80211_change_mac, .ndo_select_queue = ieee80211_netdev_select_queue, @@ -689,7 +689,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { .ndo_stop = ieee80211_stop, .ndo_uninit = ieee80211_teardown_sdata, .ndo_start_xmit = ieee80211_monitor_start_xmit, - .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_set_rx_mode = ieee80211_set_multicast_list, .ndo_change_mtu = ieee80211_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_select_queue = ieee80211_monitor_select_queue, -- cgit v1.2.3 From 88f07484ccdf08e58dc462ed1ac7eb2e84d88a17 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Date: Tue, 23 Aug 2011 01:29:52 -0700 Subject: drivers/net/ethernet/*: Enabled vendor Kconfig options Based on finds for Stephen Rothwell, where current defconfig's enable a ethernet driver and it is not compiled due to the newly added NET_VENDOR_* component of Kconfig. This patch enables all the "new" Kconfig options so that current defconfig's will continue to compile the expected drivers. In addition, by enabling all the new Kconfig options does not add any un-expected options. CC: Stephen Rothwll <sfc@canb.auug.org.au> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> --- drivers/net/ethernet/3com/Kconfig | 1 + drivers/net/ethernet/8390/Kconfig | 1 + drivers/net/ethernet/adaptec/Kconfig | 1 + drivers/net/ethernet/alteon/Kconfig | 1 + drivers/net/ethernet/amd/Kconfig | 1 + drivers/net/ethernet/apple/Kconfig | 1 + drivers/net/ethernet/atheros/Kconfig | 1 + drivers/net/ethernet/broadcom/Kconfig | 1 + drivers/net/ethernet/brocade/Kconfig | 1 + drivers/net/ethernet/chelsio/Kconfig | 1 + drivers/net/ethernet/cirrus/Kconfig | 1 + drivers/net/ethernet/cisco/Kconfig | 1 + drivers/net/ethernet/dec/Kconfig | 1 + drivers/net/ethernet/dlink/Kconfig | 1 + drivers/net/ethernet/emulex/Kconfig | 1 + drivers/net/ethernet/faraday/Kconfig | 1 + drivers/net/ethernet/freescale/Kconfig | 1 + drivers/net/ethernet/fujitsu/Kconfig | 1 + drivers/net/ethernet/hp/Kconfig | 1 + drivers/net/ethernet/i825xx/Kconfig | 1 + drivers/net/ethernet/ibm/Kconfig | 1 + drivers/net/ethernet/intel/Kconfig | 1 + drivers/net/ethernet/marvell/Kconfig | 1 + drivers/net/ethernet/mellanox/Kconfig | 1 + drivers/net/ethernet/micrel/Kconfig | 1 + drivers/net/ethernet/microchip/Kconfig | 1 + drivers/net/ethernet/myricom/Kconfig | 1 + drivers/net/ethernet/natsemi/Kconfig | 1 + drivers/net/ethernet/neterion/Kconfig | 1 + drivers/net/ethernet/nuvoton/Kconfig | 1 + drivers/net/ethernet/nvidia/Kconfig | 1 + drivers/net/ethernet/oki-semi/Kconfig | 1 + drivers/net/ethernet/pasemi/Kconfig | 1 + drivers/net/ethernet/qlogic/Kconfig | 1 + drivers/net/ethernet/racal/Kconfig | 1 + drivers/net/ethernet/rdc/Kconfig | 1 + drivers/net/ethernet/realtek/Kconfig | 1 + drivers/net/ethernet/seeq/Kconfig | 1 + drivers/net/ethernet/sgi/Kconfig | 1 + drivers/net/ethernet/sis/Kconfig | 1 + drivers/net/ethernet/smsc/Kconfig | 1 + drivers/net/ethernet/stmicro/Kconfig | 1 + drivers/net/ethernet/sun/Kconfig | 1 + drivers/net/ethernet/tehuti/Kconfig | 1 + drivers/net/ethernet/ti/Kconfig | 1 + drivers/net/ethernet/toshiba/Kconfig | 1 + drivers/net/ethernet/tundra/Kconfig | 1 + drivers/net/ethernet/via/Kconfig | 1 + drivers/net/ethernet/xilinx/Kconfig | 1 + drivers/net/ethernet/xircom/Kconfig | 1 + drivers/net/ethernet/xscale/Kconfig | 1 + 51 files changed, 51 insertions(+) (limited to 'drivers/net/ethernet/micrel') diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig index 65cc129da114..a439cbdda3b9 100644 --- a/drivers/net/ethernet/3com/Kconfig +++ b/drivers/net/ethernet/3com/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_3COM bool "3Com devices" + default y depends on ISA || EISA || MCA || PCI || PCMCIA ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index 5d2169809b19..e04ade444247 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_8390 bool "National Semi-conductor 8390 devices" + default y depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \ ISA || MCA || EISA || MAC || M32R || MACH_TX49XX || \ MCA_LEGACY || H8300 || ARM || MIPS || ZORRO || PCMCIA || \ diff --git a/drivers/net/ethernet/adaptec/Kconfig b/drivers/net/ethernet/adaptec/Kconfig index 5e9dbe9817fd..5c804bbe3dab 100644 --- a/drivers/net/ethernet/adaptec/Kconfig +++ b/drivers/net/ethernet/adaptec/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_ADAPTEC bool "Adaptec devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/alteon/Kconfig b/drivers/net/ethernet/alteon/Kconfig index 68862e4d145c..799a85282070 100644 --- a/drivers/net/ethernet/alteon/Kconfig +++ b/drivers/net/ethernet/alteon/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_ALTEON bool "Alteon devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 05139403ea8d..8af1c934dbd5 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_AMD bool "AMD devices" + default y depends on DIO || MACH_DECSTATION || MVME147 || ATARI || SUN3 || \ SUN3X || SBUS || PCI || ZORRO || (ISA && ISA_DMA_API) || \ (ARM && ARCH_EBSA110) || ISA || EISA || MCA || PCMCIA diff --git a/drivers/net/ethernet/apple/Kconfig b/drivers/net/ethernet/apple/Kconfig index fc796bc353d0..59d5c2630acb 100644 --- a/drivers/net/ethernet/apple/Kconfig +++ b/drivers/net/ethernet/apple/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_APPLE bool "Apple devices" + default y depends on (PPC_PMAC && PPC32) || MAC || ISA || EISA || MACH_IXDP2351 \ || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440 ---help--- diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig index 966c6c7ea09c..26ab8cae28b5 100644 --- a/drivers/net/ethernet/atheros/Kconfig +++ b/drivers/net/ethernet/atheros/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_ATHEROS bool "Atheros devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 8986e57d7f9c..d82ad221ebd4 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_BROADCOM bool "Broadcom devices" + default y depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \ SIBYTE_SB1xxx_SOC ---help--- diff --git a/drivers/net/ethernet/brocade/Kconfig b/drivers/net/ethernet/brocade/Kconfig index 03f0b17b87c3..264155778857 100644 --- a/drivers/net/ethernet/brocade/Kconfig +++ b/drivers/net/ethernet/brocade/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_BROCADE bool "Brocade devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig index 7b54574107ce..2de50f95798f 100644 --- a/drivers/net/ethernet/chelsio/Kconfig +++ b/drivers/net/ethernet/chelsio/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_CHELSIO bool "Chelsio devices" + default y depends on PCI || INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig index 53ebe7899174..e0cacf662914 100644 --- a/drivers/net/ethernet/cirrus/Kconfig +++ b/drivers/net/ethernet/cirrus/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_CIRRUS bool "Cirrus devices" + default y depends on ARM && ARCH_EP93XX ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/cisco/Kconfig b/drivers/net/ethernet/cisco/Kconfig index bbd534880670..94606f7ee13a 100644 --- a/drivers/net/ethernet/cisco/Kconfig +++ b/drivers/net/ethernet/cisco/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_CISCO bool "Cisco devices" + default y depends on PCI && INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/dec/Kconfig b/drivers/net/ethernet/dec/Kconfig index 40e8df9fde8d..37940279ded8 100644 --- a/drivers/net/ethernet/dec/Kconfig +++ b/drivers/net/ethernet/dec/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_DEC bool "Digital Equipment devices" + default y depends on PCI || EISA || CARDBUS ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/dlink/Kconfig b/drivers/net/ethernet/dlink/Kconfig index 9fdb66b66f15..84a28a668162 100644 --- a/drivers/net/ethernet/dlink/Kconfig +++ b/drivers/net/ethernet/dlink/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_DLINK bool "D-Link devices" + default y depends on PCI || PARPORT ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/emulex/Kconfig b/drivers/net/ethernet/emulex/Kconfig index 018ac94fb824..7a28a6433944 100644 --- a/drivers/net/ethernet/emulex/Kconfig +++ b/drivers/net/ethernet/emulex/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_EMULEX bool "Emulex devices" + default y depends on PCI && INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig index b0d76f01d47b..5918c6891694 100644 --- a/drivers/net/ethernet/faraday/Kconfig +++ b/drivers/net/ethernet/faraday/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_FARADAY bool "Faraday devices" + default y depends on ARM ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index 2fd2c614c08b..4dbe41f1cbc6 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_FREESCALE bool "Freescale devices" + default y depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \ M523x || M527x || M5272 || M528x || M520x || M532x || \ IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC || \ diff --git a/drivers/net/ethernet/fujitsu/Kconfig b/drivers/net/ethernet/fujitsu/Kconfig index 2cd968edb733..dffee9d44fd5 100644 --- a/drivers/net/ethernet/fujitsu/Kconfig +++ b/drivers/net/ethernet/fujitsu/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_FUJITSU bool "Fujitsu devices" + default y depends on ISA || PCMCIA || ((ISA || MCA_LEGACY) && EXPERIMENTAL) ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/hp/Kconfig b/drivers/net/ethernet/hp/Kconfig index 07b42e963143..a0b8ece1e3bc 100644 --- a/drivers/net/ethernet/hp/Kconfig +++ b/drivers/net/ethernet/hp/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_HP bool "HP devices" + default y depends on ISA || EISA || PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig index 5c30a5b3cba9..2be46986cbe2 100644 --- a/drivers/net/ethernet/i825xx/Kconfig +++ b/drivers/net/ethernet/i825xx/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_I825XX bool "Intel (82586/82593/82596) devices" + default y depends on NET_VENDOR_INTEL && (ISA || ISA_DMA_API || ARM || \ ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \ GSC || BVME6000 || MVME16x || EXPERIMENTAL) diff --git a/drivers/net/ethernet/ibm/Kconfig b/drivers/net/ethernet/ibm/Kconfig index 4c7ef980f1c6..9e16f3fa97b2 100644 --- a/drivers/net/ethernet/ibm/Kconfig +++ b/drivers/net/ethernet/ibm/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_IBM bool "IBM devices" + default y depends on MCA || PPC_PSERIES || PPC_PSERIES || PPC_DCR || \ (IBMEBUS && INET && SPARSEMEM) ---help--- diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 5fe185ba07bc..4a98e83812b7 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_INTEL bool "Intel devices" + default y depends on PCI || PCI_MSI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index e525408367b6..0029934748bc 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_MARVELL bool "Marvell devices" + default y depends on PCI || CPU_PXA168 || MV64X60 || PPC32 || PLAT_ORION || INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/mellanox/Kconfig b/drivers/net/ethernet/mellanox/Kconfig index e06949127b1f..d8099a7903d3 100644 --- a/drivers/net/ethernet/mellanox/Kconfig +++ b/drivers/net/ethernet/mellanox/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_MELLANOX bool "Mellanox devices" + default y depends on PCI && INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig index 4227de6d11f2..bd090dbe3ad6 100644 --- a/drivers/net/ethernet/micrel/Kconfig +++ b/drivers/net/ethernet/micrel/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_MICREL bool "Micrel devices" + default y depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \ (ARM && ARCH_KS8695) ---help--- diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig index 53b0b04935a3..8163fd0f453f 100644 --- a/drivers/net/ethernet/microchip/Kconfig +++ b/drivers/net/ethernet/microchip/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_MICROCHIP bool "Microchip devices" + default y depends on SPI && EXPERIMENTAL ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/myricom/Kconfig b/drivers/net/ethernet/myricom/Kconfig index 1816ae12ce07..540f0c6fc160 100644 --- a/drivers/net/ethernet/myricom/Kconfig +++ b/drivers/net/ethernet/myricom/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_MYRI bool "Myricom devices" + default y depends on PCI && INET ---help--- If you have a network (Ethernet) card belonging to this class, say diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig index 1e5c1e1ec79a..4a6b9fd073b6 100644 --- a/drivers/net/ethernet/natsemi/Kconfig +++ b/drivers/net/ethernet/natsemi/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_NATSEMI bool "National Semi-conductor devices" + default y depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000 ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/neterion/Kconfig b/drivers/net/ethernet/neterion/Kconfig index 3d98e62c2412..ff26b54bd3fb 100644 --- a/drivers/net/ethernet/neterion/Kconfig +++ b/drivers/net/ethernet/neterion/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_EXAR bool "Exar devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say diff --git a/drivers/net/ethernet/nuvoton/Kconfig b/drivers/net/ethernet/nuvoton/Kconfig index 3b91c3be6270..01182b559473 100644 --- a/drivers/net/ethernet/nuvoton/Kconfig +++ b/drivers/net/ethernet/nuvoton/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_NUVOTON bool "Nuvoton devices" + default y depends on ARM && ARCH_W90X900 ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/nvidia/Kconfig b/drivers/net/ethernet/nvidia/Kconfig index 0a18e7314195..ace19e7f6d13 100644 --- a/drivers/net/ethernet/nvidia/Kconfig +++ b/drivers/net/ethernet/nvidia/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_NVIDIA bool "NVIDIA devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/oki-semi/Kconfig b/drivers/net/ethernet/oki-semi/Kconfig index 97f5e72f0ec7..ecd45f9ea9d9 100644 --- a/drivers/net/ethernet/oki-semi/Kconfig +++ b/drivers/net/ethernet/oki-semi/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_OKI bool "OKI Semiconductor devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/pasemi/Kconfig b/drivers/net/ethernet/pasemi/Kconfig index ccb79b8069ad..01e6c329d78c 100644 --- a/drivers/net/ethernet/pasemi/Kconfig +++ b/drivers/net/ethernet/pasemi/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_PASEMI bool "PA Semi devices" + default y depends on PPC_PASEMI && PCI && INET ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig index a7c4424011ec..a8669adecc97 100644 --- a/drivers/net/ethernet/qlogic/Kconfig +++ b/drivers/net/ethernet/qlogic/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_QLOGIC bool "QLogic devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/racal/Kconfig b/drivers/net/ethernet/racal/Kconfig index 45d493036cec..01969e0a9c68 100644 --- a/drivers/net/ethernet/racal/Kconfig +++ b/drivers/net/ethernet/racal/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_RACAL bool "Racal-Interlan (Micom) NI devices" + default y depends on ISA ---help--- If you have a network (Ethernet) card belonging to this class, such diff --git a/drivers/net/ethernet/rdc/Kconfig b/drivers/net/ethernet/rdc/Kconfig index b15ebac75f51..2055f7eb2ba9 100644 --- a/drivers/net/ethernet/rdc/Kconfig +++ b/drivers/net/ethernet/rdc/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_RDC bool "RDC devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig index a5f67a091c4d..d8df67ac51b9 100644 --- a/drivers/net/ethernet/realtek/Kconfig +++ b/drivers/net/ethernet/realtek/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_REALTEK bool "Realtek devices" + default y depends on PCI || (PARPORT && X86) ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/seeq/Kconfig b/drivers/net/ethernet/seeq/Kconfig index 02667915b34a..49b6d5b1dfd2 100644 --- a/drivers/net/ethernet/seeq/Kconfig +++ b/drivers/net/ethernet/seeq/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_SEEQ bool "SEEQ devices" + default y depends on (ARM && ARCH_ACORN) || SGI_HAS_SEEQ || EXPERIMENTAL ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/sgi/Kconfig b/drivers/net/ethernet/sgi/Kconfig index 3098594ab274..e832f46660c9 100644 --- a/drivers/net/ethernet/sgi/Kconfig +++ b/drivers/net/ethernet/sgi/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_SGI bool "SGI devices" + default y depends on (PCI && SGI_IP27) || SGI_IP32 ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/sis/Kconfig b/drivers/net/ethernet/sis/Kconfig index 01d43e870eeb..68d052b09af1 100644 --- a/drivers/net/ethernet/sis/Kconfig +++ b/drivers/net/ethernet/sis/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_SIS bool "Silicon Integrated Systems (SiS) devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index 702efe686c48..f9619285b5ef 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_SMSC bool "SMC (SMSC)/Western Digital devices" + default y depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \ BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA ---help--- diff --git a/drivers/net/ethernet/stmicro/Kconfig b/drivers/net/ethernet/stmicro/Kconfig index e40df6433860..f4a80da00650 100644 --- a/drivers/net/ethernet/stmicro/Kconfig +++ b/drivers/net/ethernet/stmicro/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_STMICRO bool "STMicroelectronics devices" + default y depends on HAS_IOMEM ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig index 5132fa69047a..57bfd8599679 100644 --- a/drivers/net/ethernet/sun/Kconfig +++ b/drivers/net/ethernet/sun/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_SUN bool "Sun devices" + default y depends on SUN3 || SBUS || PCI || SUN_LDOMS ---help--- If you have a network (Ethernet) card belonging to this class, say diff --git a/drivers/net/ethernet/tehuti/Kconfig b/drivers/net/ethernet/tehuti/Kconfig index 914ad4059eae..1fc027eda33e 100644 --- a/drivers/net/ethernet/tehuti/Kconfig +++ b/drivers/net/ethernet/tehuti/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_TEHUTI bool "Tehuti devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index 1284319ba7e0..de76c70ec8fb 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_TI bool "Texas Instruments (TI) devices" + default y depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3)) ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig index 6ef2ce2c0ea7..051764704559 100644 --- a/drivers/net/ethernet/toshiba/Kconfig +++ b/drivers/net/ethernet/toshiba/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_TOSHIBA bool "Toshiba devices" + default y depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3 ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/tundra/Kconfig b/drivers/net/ethernet/tundra/Kconfig index 03925d1aecb2..cf7d69b62c42 100644 --- a/drivers/net/ethernet/tundra/Kconfig +++ b/drivers/net/ethernet/tundra/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_TUNDRA bool "Tundra devices" + default y depends on TSI108_BRIDGE ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig index 7199194fa898..e5d82a53ea57 100644 --- a/drivers/net/ethernet/via/Kconfig +++ b/drivers/net/ethernet/via/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_VIA bool "VIA devices" + default y depends on PCI ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig index 4e3aad401cd8..d5a826063a82 100644 --- a/drivers/net/ethernet/xilinx/Kconfig +++ b/drivers/net/ethernet/xilinx/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_XILINX bool "Xilinx devices" + default y depends on PPC || PPC32 || MICROBLAZE ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/xircom/Kconfig b/drivers/net/ethernet/xircom/Kconfig index 3d64e58e3f8b..69f56a6de821 100644 --- a/drivers/net/ethernet/xircom/Kconfig +++ b/drivers/net/ethernet/xircom/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_XIRCOM bool "Xircom devices" + default y depends on PCMCIA ---help--- If you have a network (Ethernet) card belonging to this class, say Y diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig index 6bbcc54d6ce7..cf67352cea14 100644 --- a/drivers/net/ethernet/xscale/Kconfig +++ b/drivers/net/ethernet/xscale/Kconfig @@ -4,6 +4,7 @@ config NET_VENDOR_XSCALE bool "Intel XScale IXP devices" + default y depends on NET_VENDOR_INTEL && ((ARM && ARCH_IXP4XX && \ IXP4XX_NPE && IXP4XX_QMGR) || ARCH_ENP2611) ---help--- -- cgit v1.2.3 From 787343ad3d321fc987e36715433050df88353465 Mon Sep 17 00:00:00 2001 From: Ian Campbell <Ian.Campbell@citrix.com> Date: Wed, 31 Aug 2011 00:46:55 +0000 Subject: ksz884x: convert to SKB paged frag API. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/net/ethernet/micrel/ksz884x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net/ethernet/micrel') diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 27418d31a09f..710c4aead146 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4704,8 +4704,7 @@ static void send_packet(struct sk_buff *skb, struct net_device *dev) dma_buf->dma = pci_map_single( hw_priv->pdev, - page_address(this_frag->page) + - this_frag->page_offset, + skb_frag_address(this_frag), dma_buf->len, PCI_DMA_TODEVICE); set_tx_buf(desc, dma_buf->dma); -- cgit v1.2.3 From aaba215ca0b4232824c92b830853f465f16a6672 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Date: Wed, 14 Sep 2011 21:23:14 +0000 Subject: MII: fix Kconfig dependencies for MII MII Kconfig option is apart of the core networking drivers and by default NET_CORE is enabled so drivers selecting MII will have MII enabled as well. It was found using the randconfig option during testing, MII would be selected but NET_CORE could be disabled. This caused a dependency error. Resolved the dependency by selecting NET_CORE when MII is selected. Reported-by: Emil Tantilov <emil.s.tantilov@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- arch/cris/arch-v10/drivers/Kconfig | 1 + arch/cris/arch-v32/drivers/Kconfig | 1 + drivers/net/ethernet/3com/Kconfig | 1 + drivers/net/ethernet/Kconfig | 4 ++++ drivers/net/ethernet/adaptec/Kconfig | 1 + drivers/net/ethernet/adi/Kconfig | 1 + drivers/net/ethernet/amd/Kconfig | 2 ++ drivers/net/ethernet/atheros/Kconfig | 4 ++++ drivers/net/ethernet/broadcom/Kconfig | 2 ++ drivers/net/ethernet/cadence/Kconfig | 1 + drivers/net/ethernet/cirrus/Kconfig | 1 + drivers/net/ethernet/davicom/Kconfig | 1 + drivers/net/ethernet/dec/tulip/Kconfig | 1 + drivers/net/ethernet/dlink/Kconfig | 1 + drivers/net/ethernet/faraday/Kconfig | 1 + drivers/net/ethernet/freescale/fs_enet/Kconfig | 1 + drivers/net/ethernet/icplus/Kconfig | 1 + drivers/net/ethernet/intel/Kconfig | 1 + drivers/net/ethernet/micrel/Kconfig | 4 ++++ drivers/net/ethernet/nuvoton/Kconfig | 1 + drivers/net/ethernet/oki-semi/pch_gbe/Kconfig | 1 + drivers/net/ethernet/packetengines/Kconfig | 1 + drivers/net/ethernet/rdc/Kconfig | 1 + drivers/net/ethernet/realtek/Kconfig | 3 +++ drivers/net/ethernet/renesas/Kconfig | 1 + drivers/net/ethernet/sgi/Kconfig | 1 + drivers/net/ethernet/sis/Kconfig | 2 ++ drivers/net/ethernet/smsc/Kconfig | 5 +++++ drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + drivers/net/ethernet/via/Kconfig | 2 ++ drivers/net/usb/Kconfig | 3 +++ 31 files changed, 52 insertions(+) (limited to 'drivers/net/ethernet/micrel') diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 0d7221779923..32d90867a984 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -4,6 +4,7 @@ config ETRAX_ETHERNET bool "Ethernet support" depends on ETRAX_ARCH_V10 select NET_ETHERNET + select NET_CORE select MII help This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 41a2732e8b9c..e47e9c3401b0 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -4,6 +4,7 @@ config ETRAX_ETHERNET bool "Ethernet support" depends on ETRAX_ARCH_V32 select NET_ETHERNET + select NET_CORE select MII help This option enables the ETRAX FS built-in 10/100Mbit Ethernet diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig index a439cbdda3b9..a8bb30cf512d 100644 --- a/drivers/net/ethernet/3com/Kconfig +++ b/drivers/net/ethernet/3com/Kconfig @@ -81,6 +81,7 @@ config PCMCIA_3C589 config VORTEX tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support" depends on (PCI || EISA) + select NET_CORE select MII ---help--- This option enables driver support for a large number of 10Mbps and diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 1f647471e651..6dff5a0e733f 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -62,6 +62,7 @@ config JME tristate "JMicron(R) PCI-Express Gigabit Ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver supports the PCI-Express gigabit ethernet adapters @@ -102,6 +103,7 @@ config FEALNX tristate "Myson MTD-8xx PCI Ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- Say Y here to support the Myson MTD-800 family of PCI-based Ethernet @@ -112,6 +114,7 @@ source "drivers/net/ethernet/8390/Kconfig" config NET_NETX tristate "NetX Ethernet support" + select NET_CORE select MII depends on ARCH_NETX ---help--- @@ -128,6 +131,7 @@ source "drivers/net/ethernet/oki-semi/Kconfig" config ETHOC tristate "OpenCores 10/100 Mbps Ethernet MAC support" depends on HAS_IOMEM && HAS_DMA + select NET_CORE select MII select PHYLIB select CRC32 diff --git a/drivers/net/ethernet/adaptec/Kconfig b/drivers/net/ethernet/adaptec/Kconfig index 5c804bbe3dab..0bff571b1bb3 100644 --- a/drivers/net/ethernet/adaptec/Kconfig +++ b/drivers/net/ethernet/adaptec/Kconfig @@ -22,6 +22,7 @@ config ADAPTEC_STARFIRE tristate "Adaptec Starfire/DuraLAN support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig index 6de9851045cb..49a30d37ae4a 100644 --- a/drivers/net/ethernet/adi/Kconfig +++ b/drivers/net/ethernet/adi/Kconfig @@ -23,6 +23,7 @@ config BFIN_MAC tristate "Blackfin on-chip MAC support" depends on (BF516 || BF518 || BF526 || BF527 || BF536 || BF537) select CRC32 + select NET_CORE select MII select PHYLIB select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 8af1c934dbd5..238b537b68fe 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -34,6 +34,7 @@ config AMD8111_ETH tristate "AMD 8111 (new PCI LANCE) support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- If you have an AMD 8111-based PCI LANCE ethernet card, @@ -59,6 +60,7 @@ config PCNET32 tristate "AMD PCnet32 PCI support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- If you have a PCnet32 or PCnetPCI based network (Ethernet) card, diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig index 26ab8cae28b5..1ed886d421f8 100644 --- a/drivers/net/ethernet/atheros/Kconfig +++ b/drivers/net/ethernet/atheros/Kconfig @@ -22,6 +22,7 @@ config ATL2 tristate "Atheros L2 Fast Ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver supports the Atheros L2 fast ethernet adapter. @@ -33,6 +34,7 @@ config ATL1 tristate "Atheros/Attansic L1 Gigabit Ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver supports the Atheros/Attansic L1 gigabit ethernet @@ -45,6 +47,7 @@ config ATL1E tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL select CRC32 + select NET_CORE select MII ---help--- This driver supports the Atheros L1E gigabit ethernet adapter. @@ -56,6 +59,7 @@ config ATL1C tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL select CRC32 + select NET_CORE select MII ---help--- This driver supports the Atheros L1C gigabit ethernet adapter. diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index d82ad221ebd4..f15e72e81ac4 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -22,6 +22,7 @@ config B44 tristate "Broadcom 440x/47xx ethernet support" depends on SSB_POSSIBLE && HAS_DMA select SSB + select NET_CORE select MII ---help--- If you have a network (Ethernet) controller of this type, say Y @@ -53,6 +54,7 @@ config B44_PCI config BCM63XX_ENET tristate "Broadcom 63xx internal mac support" depends on BCM63XX + select NET_CORE select MII select PHYLIB help diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index c00e706ab58a..98849a1fc749 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -25,6 +25,7 @@ if NET_ATMEL config ARM_AT91_ETHER tristate "AT91RM9200 Ethernet support" depends on ARM && ARCH_AT91RM9200 + select NET_CORE select MII ---help--- If you wish to compile a kernel for the AT91RM9200 and enable diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig index e0cacf662914..e9386ef524aa 100644 --- a/drivers/net/ethernet/cirrus/Kconfig +++ b/drivers/net/ethernet/cirrus/Kconfig @@ -21,6 +21,7 @@ if NET_VENDOR_CIRRUS config EP93XX_ETH tristate "EP93xx Ethernet support" depends on ARM && ARCH_EP93XX + select NET_CORE select MII help This is a driver for the ethernet hardware included in EP93xx CPUs. diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig index 73c5d2080f24..972b62b31837 100644 --- a/drivers/net/ethernet/davicom/Kconfig +++ b/drivers/net/ethernet/davicom/Kconfig @@ -6,6 +6,7 @@ config DM9000 tristate "DM9000 support" depends on ARM || BLACKFIN || MIPS select CRC32 + select NET_CORE select MII ---help--- Support for DM9000 chipset. diff --git a/drivers/net/ethernet/dec/tulip/Kconfig b/drivers/net/ethernet/dec/tulip/Kconfig index f6af772b12c9..1203be0436e2 100644 --- a/drivers/net/ethernet/dec/tulip/Kconfig +++ b/drivers/net/ethernet/dec/tulip/Kconfig @@ -125,6 +125,7 @@ config WINBOND_840 tristate "Winbond W89c840 Ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver is for the Winbond W89c840 chip. It also works with diff --git a/drivers/net/ethernet/dlink/Kconfig b/drivers/net/ethernet/dlink/Kconfig index 84a28a668162..b5afe218c31b 100644 --- a/drivers/net/ethernet/dlink/Kconfig +++ b/drivers/net/ethernet/dlink/Kconfig @@ -66,6 +66,7 @@ config SUNDANCE tristate "Sundance Alta support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver is for the Sundance "Alta" chip. diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig index 5918c6891694..b8974b9e3b47 100644 --- a/drivers/net/ethernet/faraday/Kconfig +++ b/drivers/net/ethernet/faraday/Kconfig @@ -21,6 +21,7 @@ if NET_VENDOR_FARADAY config FTMAC100 tristate "Faraday FTMAC100 10/100 Ethernet support" depends on ARM + select NET_CORE select MII ---help--- This driver supports the FTMAC100 10/100 Ethernet controller diff --git a/drivers/net/ethernet/freescale/fs_enet/Kconfig b/drivers/net/ethernet/freescale/fs_enet/Kconfig index be92229f2c2a..268414d9f2cb 100644 --- a/drivers/net/ethernet/freescale/fs_enet/Kconfig +++ b/drivers/net/ethernet/freescale/fs_enet/Kconfig @@ -1,6 +1,7 @@ config FS_ENET tristate "Freescale Ethernet Driver" depends on NET_VENDOR_FREESCALE && (CPM1 || CPM2 || PPC_MPC512x) + select NET_CORE select MII select PHYLIB diff --git a/drivers/net/ethernet/icplus/Kconfig b/drivers/net/ethernet/icplus/Kconfig index e88822276269..3aff81d7989f 100644 --- a/drivers/net/ethernet/icplus/Kconfig +++ b/drivers/net/ethernet/icplus/Kconfig @@ -5,6 +5,7 @@ config IP1000 tristate "IP1000 Gigabit Ethernet support" depends on PCI && EXPERIMENTAL + select NET_CORE select MII ---help--- This driver supports IP1000 gigabit Ethernet cards. diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 4a98e83812b7..61029dc7fa6f 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -21,6 +21,7 @@ if NET_VENDOR_INTEL config E100 tristate "Intel(R) PRO/100+ support" depends on PCI + select NET_CORE select MII ---help--- This driver supports Intel(R) PRO/100 family of adapters. diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig index bd090dbe3ad6..d10c2e15f4ed 100644 --- a/drivers/net/ethernet/micrel/Kconfig +++ b/drivers/net/ethernet/micrel/Kconfig @@ -22,6 +22,7 @@ if NET_VENDOR_MICREL config ARM_KS8695_ETHER tristate "KS8695 Ethernet support" depends on ARM && ARCH_KS8695 + select NET_CORE select MII ---help--- If you wish to compile a kernel for the KS8695 and want to @@ -38,6 +39,7 @@ config KS8842 config KS8851 tristate "Micrel KS8851 SPI" depends on SPI + select NET_CORE select MII select CRC32 ---help--- @@ -46,6 +48,7 @@ config KS8851 config KS8851_MLL tristate "Micrel KS8851 MLL" depends on HAS_IOMEM + select NET_CORE select MII ---help--- This platform driver is for Micrel KS8851 Address/data bus @@ -54,6 +57,7 @@ config KS8851_MLL config KSZ884X_PCI tristate "Micrel KSZ8841/2 PCI" depends on PCI + select NET_CORE select MII select CRC32 ---help--- diff --git a/drivers/net/ethernet/nuvoton/Kconfig b/drivers/net/ethernet/nuvoton/Kconfig index 01182b559473..334c17183095 100644 --- a/drivers/net/ethernet/nuvoton/Kconfig +++ b/drivers/net/ethernet/nuvoton/Kconfig @@ -22,6 +22,7 @@ config W90P910_ETH tristate "Nuvoton w90p910 Ethernet support" depends on ARM && ARCH_W90X900 select PHYLIB + select NET_CORE select MII ---help--- Say Y here if you want to use built-in Ethernet ports diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig index c85709d6ff1b..7efa62427235 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig +++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig @@ -5,6 +5,7 @@ config PCH_GBE tristate "OKI SEMICONDUCTOR ML7223 IOH GbE (Intel EG20T PCH)" depends on PCI + select NET_CORE select MII ---help--- This is a gigabit ethernet driver for EG20T PCH. diff --git a/drivers/net/ethernet/packetengines/Kconfig b/drivers/net/ethernet/packetengines/Kconfig index 4add1db20f1e..b97132d9dff0 100644 --- a/drivers/net/ethernet/packetengines/Kconfig +++ b/drivers/net/ethernet/packetengines/Kconfig @@ -20,6 +20,7 @@ if NET_PACKET_ENGINE config HAMACHI tristate "Packet Engines Hamachi GNIC-II support" depends on PCI + select NET_CORE select MII ---help--- If you have a Gigabit Ethernet card of this type, say Y and read diff --git a/drivers/net/ethernet/rdc/Kconfig b/drivers/net/ethernet/rdc/Kconfig index 2055f7eb2ba9..c8ba4b3494c1 100644 --- a/drivers/net/ethernet/rdc/Kconfig +++ b/drivers/net/ethernet/rdc/Kconfig @@ -22,6 +22,7 @@ config R6040 tristate "RDC R6040 Fast Ethernet Adapter support" depends on PCI select CRC32 + select NET_CORE select MII select PHYLIB ---help--- diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig index d8df67ac51b9..84083ec6e612 100644 --- a/drivers/net/ethernet/realtek/Kconfig +++ b/drivers/net/ethernet/realtek/Kconfig @@ -37,6 +37,7 @@ config 8139CP tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL select CRC32 + select NET_CORE select MII ---help--- This is a driver for the Fast Ethernet PCI network cards based on @@ -51,6 +52,7 @@ config 8139TOO tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This is a driver for the Fast Ethernet PCI network cards based on @@ -105,6 +107,7 @@ config R8169 depends on PCI select FW_LOADER select CRC32 + select NET_CORE select MII ---help--- Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter. diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index f57ae230817b..9755b49bbefb 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig @@ -9,6 +9,7 @@ config SH_ETH CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757) select CRC32 + select NET_CORE select MII select MDIO_BITBANG select PHYLIB diff --git a/drivers/net/ethernet/sgi/Kconfig b/drivers/net/ethernet/sgi/Kconfig index e832f46660c9..c1c4bb868a3b 100644 --- a/drivers/net/ethernet/sgi/Kconfig +++ b/drivers/net/ethernet/sgi/Kconfig @@ -22,6 +22,7 @@ config SGI_IOC3_ETH bool "SGI IOC3 Ethernet" depends on PCI && SGI_IP27 select CRC32 + select NET_CORE select MII ---help--- If you have a network (Ethernet) card of this type, say Y and read diff --git a/drivers/net/ethernet/sis/Kconfig b/drivers/net/ethernet/sis/Kconfig index 68d052b09af1..f1135cc1bd48 100644 --- a/drivers/net/ethernet/sis/Kconfig +++ b/drivers/net/ethernet/sis/Kconfig @@ -22,6 +22,7 @@ config SIS900 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This is a driver for the Fast Ethernet PCI network cards based on @@ -38,6 +39,7 @@ config SIS190 tristate "SiS190/SiS191 gigabit ethernet support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index f9619285b5ef..1854c88dfb92 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig @@ -37,6 +37,7 @@ config SMC9194 config SMC91X tristate "SMC 91C9x/91C1xxx support" select CRC32 + select NET_CORE select MII depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ MN10300 || COLDFIRE) @@ -56,6 +57,7 @@ config PCMCIA_SMC91C92 tristate "SMC 91Cxx PCMCIA support" depends on PCMCIA select CRC32 + select NET_CORE select MII ---help--- Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA @@ -68,6 +70,7 @@ config EPIC100 tristate "SMC EtherPower II" depends on PCI select CRC32 + select NET_CORE select MII ---help--- This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC, @@ -78,6 +81,7 @@ config EPIC100 config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 + select NET_CORE select MII depends on (ARM || SUPERH || MN10300) ---help--- @@ -95,6 +99,7 @@ config SMSC911X tristate "SMSC LAN911x/LAN921x families embedded ethernet support" depends on (ARM || SUPERH || BLACKFIN || MIPS || MN10300) select CRC32 + select NET_CORE select MII select PHYLIB ---help--- diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 2e35be7ccfae..8cd9ddec05a0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -1,6 +1,7 @@ config STMMAC_ETH tristate "STMicroelectronics 10/100/1000 Ethernet driver" depends on HAS_IOMEM + select NET_CORE select MII select PHYLIB select CRC32 diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig index e5d82a53ea57..68a9ba66feba 100644 --- a/drivers/net/ethernet/via/Kconfig +++ b/drivers/net/ethernet/via/Kconfig @@ -22,6 +22,7 @@ config VIA_RHINE tristate "VIA Rhine support" depends on PCI select CRC32 + select NET_CORE select MII ---help--- If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A), @@ -47,6 +48,7 @@ config VIA_VELOCITY depends on PCI select CRC32 select CRC_CCITT + select NET_CORE select MII ---help--- If you have a VIA "Velocity" based network card say Y here. diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 84d4608153c9..233576127934 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -68,6 +68,7 @@ config USB_KAWETH config USB_PEGASUS tristate "USB Pegasus/Pegasus-II based ethernet device support" + select NET_CORE select MII ---help--- Say Y here if you know you have Pegasus or Pegasus-II based adapter. @@ -84,6 +85,7 @@ config USB_PEGASUS config USB_RTL8150 tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)" depends on EXPERIMENTAL + select NET_CORE select MII help Say Y here if you have RTL8150 based usb-ethernet adapter. @@ -95,6 +97,7 @@ config USB_RTL8150 config USB_USBNET tristate "Multi-purpose USB Networking Framework" + select NET_CORE select MII ---help--- This driver supports several kinds of network links over USB, -- cgit v1.2.3 From 9e903e085262ffbf1fc44a17ac06058aca03524a Mon Sep 17 00:00:00 2001 From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 18 Oct 2011 21:00:24 +0000 Subject: net: add skb frag size accessors To ease skb->truesize sanitization, its better to be able to localize all references to skb frags size. Define accessors : skb_frag_size() to fetch frag size, and skb_frag_size_{set|add|sub}() to manipulate it. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/atm/eni.c | 2 +- drivers/infiniband/hw/amso1100/c2.c | 4 +- drivers/infiniband/hw/nes/nes_nic.c | 10 +-- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 18 +++--- drivers/net/ethernet/3com/3c59x.c | 6 +- drivers/net/ethernet/3com/typhoon.c | 6 +- drivers/net/ethernet/adaptec/starfire.c | 8 +-- drivers/net/ethernet/aeroflex/greth.c | 8 +-- drivers/net/ethernet/alteon/acenic.c | 10 +-- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 6 +- drivers/net/ethernet/atheros/atlx/atl1.c | 12 ++-- drivers/net/ethernet/broadcom/bnx2.c | 12 ++-- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 14 ++--- drivers/net/ethernet/broadcom/tg3.c | 8 +-- drivers/net/ethernet/brocade/bna/bnad.c | 6 +- drivers/net/ethernet/chelsio/cxgb/sge.c | 10 +-- drivers/net/ethernet/chelsio/cxgb3/sge.c | 12 ++-- drivers/net/ethernet/chelsio/cxgb4/sge.c | 26 ++++---- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 26 ++++---- drivers/net/ethernet/cisco/enic/enic_main.c | 12 ++-- drivers/net/ethernet/emulex/benet/be_main.c | 18 +++--- drivers/net/ethernet/ibm/ehea/ehea_main.c | 4 +- drivers/net/ethernet/ibm/emac/core.c | 2 +- drivers/net/ethernet/ibm/ibmveth.c | 6 +- drivers/net/ethernet/intel/e1000/e1000_main.c | 6 +- drivers/net/ethernet/intel/e1000e/netdev.c | 6 +- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- drivers/net/ethernet/intel/igbvf/netdev.c | 4 +- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +- drivers/net/ethernet/jme.c | 4 +- drivers/net/ethernet/marvell/mv643xx_eth.c | 9 +-- drivers/net/ethernet/marvell/skge.c | 8 +-- drivers/net/ethernet/marvell/sky2.c | 16 ++--- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 14 ++--- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 12 ++-- drivers/net/ethernet/micrel/ksz884x.c | 2 +- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 14 ++--- drivers/net/ethernet/natsemi/ns83820.c | 4 +- drivers/net/ethernet/neterion/s2io.c | 12 ++-- drivers/net/ethernet/neterion/vxge/vxge-main.c | 12 ++-- drivers/net/ethernet/nvidia/forcedeth.c | 18 +++--- drivers/net/ethernet/pasemi/pasemi_mac.c | 8 +-- .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 6 +- drivers/net/ethernet/qlogic/qla3xxx.c | 6 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 6 +- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 6 +- drivers/net/ethernet/realtek/8139cp.c | 4 +- drivers/net/ethernet/realtek/r8169.c | 4 +- drivers/net/ethernet/sfc/rx.c | 2 +- drivers/net/ethernet/sfc/tx.c | 8 +-- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +- drivers/net/ethernet/sun/cassini.c | 8 +-- drivers/net/ethernet/sun/niu.c | 6 +- drivers/net/ethernet/sun/sungem.c | 4 +- drivers/net/ethernet/sun/sunhme.c | 4 +- drivers/net/ethernet/tehuti/tehuti.c | 6 +- drivers/net/ethernet/tile/tilepro.c | 2 +- drivers/net/ethernet/tundra/tsi108_eth.c | 6 +- drivers/net/ethernet/via/via-velocity.c | 6 +- drivers/net/ethernet/xilinx/ll_temac_main.c | 4 +- drivers/net/virtio_net.c | 8 +-- drivers/net/vmxnet3/vmxnet3_drv.c | 12 ++-- drivers/net/xen-netback/netback.c | 4 +- drivers/net/xen-netfront.c | 4 +- drivers/scsi/cxgbi/libcxgbi.c | 10 +-- drivers/scsi/fcoe/fcoe_transport.c | 2 +- drivers/staging/hv/netvsc_drv.c | 4 +- include/linux/skbuff.h | 28 +++++++-- net/appletalk/ddp.c | 5 +- net/core/datagram.c | 16 ++--- net/core/dev.c | 6 +- net/core/pktgen.c | 12 ++-- net/core/skbuff.c | 72 ++++++++++++---------- net/core/user_dma.c | 4 +- net/ipv4/inet_lro.c | 8 +-- net/ipv4/ip_fragment.c | 4 +- net/ipv4/ip_output.c | 6 +- net/ipv4/tcp.c | 9 ++- net/ipv4/tcp_output.c | 8 ++- net/ipv6/ip6_output.c | 5 +- net/ipv6/netfilter/nf_conntrack_reasm.c | 4 +- net/ipv6/reassembly.c | 4 +- net/xfrm/xfrm_ipcomp.c | 2 +- 87 files changed, 387 insertions(+), 357 deletions(-) (limited to 'drivers/net/ethernet/micrel') diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index f7ca4c13d61d..956e9accb051 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -1136,7 +1136,7 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */ put_dma(tx->index,eni_dev->dma,&j,(unsigned long) skb_frag_page(&skb_shinfo(skb)->frags[i]) + skb_shinfo(skb)->frags[i].page_offset, - skb_shinfo(skb)->frags[i].size); + skb_frag_size(&skb_shinfo(skb)->frags[i])); } if (skb->len & 3) put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3)); diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 6e85a75289e8..5ce7b9e8bff6 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c @@ -800,8 +800,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* Loop thru additional data fragments and queue them */ if (skb_shinfo(skb)->nr_frags) { for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - maplen = frag->size; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + maplen = skb_frag_size(frag); mapaddr = skb_frag_dma_map(&c2dev->pcidev->dev, frag, 0, maplen, DMA_TO_DEVICE); elem = elem->next; diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 7cb7f292dfd1..47b2ee4c01e2 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -444,10 +444,10 @@ static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev) skb_frag_t *frag = &skb_shinfo(skb)->frags[skb_fragment_index]; bus_address = skb_frag_dma_map(&nesdev->pcidev->dev, - frag, 0, frag->size, + frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); wqe_fragment_length[wqe_fragment_index] = - cpu_to_le16(skb_shinfo(skb)->frags[skb_fragment_index].size); + cpu_to_le16(skb_frag_size(&skb_shinfo(skb)->frags[skb_fragment_index])); set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index), bus_address); wqe_fragment_index++; @@ -565,7 +565,7 @@ tso_sq_no_longer_full: &skb_shinfo(skb)->frags[tso_frag_count]; tso_bus_address[tso_frag_count] = skb_frag_dma_map(&nesdev->pcidev->dev, - frag, 0, frag->size, + frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); } @@ -637,11 +637,11 @@ tso_sq_no_longer_full: } while (wqe_fragment_index < 5) { wqe_fragment_length[wqe_fragment_index] = - cpu_to_le16(skb_shinfo(skb)->frags[tso_frag_index].size); + cpu_to_le16(skb_frag_size(&skb_shinfo(skb)->frags[tso_frag_index])); set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index), (u64)tso_bus_address[tso_frag_index]); wqe_fragment_index++; - tso_wqe_length += skb_shinfo(skb)->frags[tso_frag_index++].size; + tso_wqe_length += skb_frag_size(&skb_shinfo(skb)->frags[tso_frag_index++]); if (wqe_fragment_index < 5) wqe_fragment_length[wqe_fragment_index] = 0; if (tso_frag_index == tso_frag_count) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 67a477be237e..c74548a586ea 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -543,7 +543,7 @@ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space, } else { size = min(length, (unsigned) PAGE_SIZE); - frag->size = size; + skb_frag_size_set(frag, size); skb->data_len += size; skb->truesize += size; skb->len += size; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 00435be4a44b..2b060f45bec3 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -117,7 +117,7 @@ static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv, size = length - IPOIB_UD_HEAD_SIZE; - frag->size = size; + skb_frag_size_set(frag, size); skb->data_len += size; skb->truesize += size; } else @@ -322,10 +322,10 @@ static int ipoib_dma_map_tx(struct ib_device *ca, off = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; mapping[i + off] = ib_dma_map_page(ca, skb_frag_page(frag), - frag->page_offset, frag->size, + frag->page_offset, skb_frag_size(frag), DMA_TO_DEVICE); if (unlikely(ib_dma_mapping_error(ca, mapping[i + off]))) goto partial_error; @@ -334,8 +334,9 @@ static int ipoib_dma_map_tx(struct ib_device *ca, partial_error: for (; i > 0; --i) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; - ib_dma_unmap_page(ca, mapping[i - !off], frag->size, DMA_TO_DEVICE); + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; + + ib_dma_unmap_page(ca, mapping[i - !off], skb_frag_size(frag), DMA_TO_DEVICE); } if (off) @@ -359,8 +360,9 @@ static void ipoib_dma_unmap_tx(struct ib_device *ca, off = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - ib_dma_unmap_page(ca, mapping[i + off], frag->size, + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + ib_dma_unmap_page(ca, mapping[i + off], skb_frag_size(frag), DMA_TO_DEVICE); } } @@ -510,7 +512,7 @@ static inline int post_send(struct ipoib_dev_priv *priv, for (i = 0; i < nr_frags; ++i) { priv->tx_sge[i + off].addr = mapping[i + off]; - priv->tx_sge[i + off].length = frags[i].size; + priv->tx_sge[i + off].length = skb_frag_size(&frags[i]); } priv->tx_wr.num_sge = nr_frags + off; priv->tx_wr.wr_id = wr_id; diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 9ca45dcba755..b42c06baba89 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -2182,12 +2182,12 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) cpu_to_le32(pci_map_single( VORTEX_PCI(vp), (void *)skb_frag_address(frag), - frag->size, PCI_DMA_TODEVICE)); + skb_frag_size(frag), PCI_DMA_TODEVICE)); if (i == skb_shinfo(skb)->nr_frags-1) - vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size|LAST_FRAG); + vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG); else - vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size); + vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)); } } #else diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index 11f8858c786d..20ea07508ac7 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -810,15 +810,15 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) txd->frag.addrHi = 0; first_txd->numDesc++; - for(i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; void *frag_addr; txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); typhoon_inc_tx_index(&txRing->lastWrite, 1); - len = frag->size; + len = skb_frag_size(frag); frag_addr = skb_frag_address(frag); skb_dma = pci_map_single(tp->tx_pdev, frag_addr, len, PCI_DMA_TODEVICE); diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index d6b015598569..6d9f6911000f 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c @@ -1256,12 +1256,12 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) np->tx_info[entry].mapping = pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); } else { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1]; - status |= this_frag->size; + const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1]; + status |= skb_frag_size(this_frag); np->tx_info[entry].mapping = pci_map_single(np->pci_dev, skb_frag_address(this_frag), - this_frag->size, + skb_frag_size(this_frag), PCI_DMA_TODEVICE); } @@ -1378,7 +1378,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { pci_unmap_single(np->pci_dev, np->tx_info[entry].mapping, - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_TODEVICE); np->dirty_tx++; entry++; diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 6715bf54f04e..442fefa4f2ca 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -198,7 +198,7 @@ static void greth_clean_rings(struct greth_private *greth) dma_unmap_page(greth->dev, greth_read_bd(&tx_bdp->addr), - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); greth->tx_last = NEXT_TX(greth->tx_last); @@ -517,7 +517,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) status = GRETH_BD_EN; if (skb->ip_summed == CHECKSUM_PARTIAL) status |= GRETH_TXBD_CSALL; - status |= frag->size & GRETH_BD_LEN; + status |= skb_frag_size(frag) & GRETH_BD_LEN; /* Wrap around descriptor ring */ if (curr_tx == GRETH_TXBD_NUM_MASK) @@ -531,7 +531,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) greth_write_bd(&bdp->stat, status); - dma_addr = skb_frag_dma_map(greth->dev, frag, 0, frag->size, + dma_addr = skb_frag_dma_map(greth->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(greth->dev, dma_addr))) @@ -713,7 +713,7 @@ static void greth_clean_tx_gbit(struct net_device *dev) dma_unmap_page(greth->dev, greth_read_bd(&bdp->addr), - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); greth->tx_last = NEXT_TX(greth->tx_last); diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index b1a4e8204437..f872748ab4e6 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -2478,18 +2478,18 @@ restart: idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct tx_ring_info *info; - len += frag->size; + len += skb_frag_size(frag); info = ap->skb->tx_skbuff + idx; desc = ap->tx_ring + idx; mapping = skb_frag_dma_map(&ap->pdev->dev, frag, 0, - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); - flagsize = (frag->size << 16); + flagsize = skb_frag_size(frag) << 16; if (skb->ip_summed == CHECKSUM_PARTIAL) flagsize |= BD_FLG_TCP_UDP_SUM; idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap); @@ -2508,7 +2508,7 @@ restart: info->skb = NULL; } dma_unmap_addr_set(info, mapping, mapping); - dma_unmap_len_set(info, maplen, frag->size); + dma_unmap_len_set(info, maplen, skb_frag_size(frag)); ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag); } } diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 12a0b30319db..02c7ed8d9eca 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2179,7 +2179,7 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter, memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); - buffer_info->length = frag->size; + buffer_info->length = skb_frag_size(frag); buffer_info->dma = skb_frag_dma_map(&adapter->pdev->dev, frag, 0, buffer_info->length, diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 97c45a4b855a..95483bcac1d0 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1593,7 +1593,7 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb) u16 proto_hdr_len = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - fg_size = skb_shinfo(skb)->frags[i].size; + fg_size = skb_frag_size(&skb_shinfo(skb)->frags[i]); tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT); } @@ -1744,12 +1744,12 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; u16 i; u16 seg_num; frag = &skb_shinfo(skb)->frags[f]; - buf_len = frag->size; + buf_len = skb_frag_size(frag); seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; for (i = 0; i < seg_num; i++) { diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 7381a49fefb4..0405261efb5c 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2267,11 +2267,11 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; u16 i, nseg; frag = &skb_shinfo(skb)->frags[f]; - buf_len = frag->size; + buf_len = skb_frag_size(frag); nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) / ATL1_MAX_TX_BUF_LEN; @@ -2356,7 +2356,6 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, int count = 1; int ret_val; struct tx_packet_desc *ptpd; - u16 frag_size; u16 vlan_tag; unsigned int nr_frags = 0; unsigned int mss = 0; @@ -2372,10 +2371,9 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) { - frag_size = skb_shinfo(skb)->frags[f].size; - if (frag_size) - count += (frag_size + ATL1_MAX_TX_BUF_LEN - 1) / - ATL1_MAX_TX_BUF_LEN; + unsigned int f_size = skb_frag_size(&skb_shinfo(skb)->frags[f]); + count += (f_size + ATL1_MAX_TX_BUF_LEN - 1) / + ATL1_MAX_TX_BUF_LEN; } mss = skb_shinfo(skb)->gso_size; diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 6ff7636e73a2..965c7235804d 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -2871,7 +2871,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) dma_unmap_addr( &txr->tx_buf_ring[TX_RING_IDX(sw_cons)], mapping), - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_TODEVICE); } @@ -3049,7 +3049,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb, } else { skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; - frag->size -= tail; + skb_frag_size_sub(frag, tail); skb->data_len -= tail; } return 0; @@ -5395,7 +5395,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping), - skb_shinfo(skb)->frags[k].size, + skb_frag_size(&skb_shinfo(skb)->frags[k]), PCI_DMA_TODEVICE); } dev_kfree_skb(skb); @@ -6530,13 +6530,13 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_buf->is_gso = skb_is_gso(skb); for (i = 0; i < last_frag; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; prod = NEXT_TX_BD(prod); ring_prod = TX_RING_IDX(prod); txbd = &txr->tx_desc_ring[ring_prod]; - len = frag->size; + len = skb_frag_size(frag); mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0, len, DMA_TO_DEVICE); if (dma_mapping_error(&bp->pdev->dev, mapping)) @@ -6594,7 +6594,7 @@ dma_error: ring_prod = TX_RING_IDX(prod); tx_buf = &txr->tx_buf_ring[ring_prod]; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping), - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_TODEVICE); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e575e89c7d46..dd8ee56396b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2363,7 +2363,7 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, /* Calculate the first sum - it's special */ for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++) wnd_sum += - skb_shinfo(skb)->frags[frag_idx].size; + skb_frag_size(&skb_shinfo(skb)->frags[frag_idx]); /* If there was data on linear skb data - check it */ if (first_bd_sz > 0) { @@ -2379,14 +2379,14 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, check all windows */ for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) { wnd_sum += - skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1].size; + skb_frag_size(&skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1]); if (unlikely(wnd_sum < lso_mss)) { to_copy = 1; break; } wnd_sum -= - skb_shinfo(skb)->frags[wnd_idx].size; + skb_frag_size(&skb_shinfo(skb)->frags[wnd_idx]); } } else { /* in non-LSO too fragmented packet should always @@ -2796,8 +2796,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0, frag->size, - DMA_TO_DEVICE); + mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0, + skb_frag_size(frag), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { DP(NETIF_MSG_TX_QUEUED, "Unable to map page - " @@ -2821,8 +2821,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - tx_data_bd->nbytes = cpu_to_le16(frag->size); - le16_add_cpu(&pkt_size, frag->size); + tx_data_bd->nbytes = cpu_to_le16(skb_frag_size(frag)); + le16_add_cpu(&pkt_size, skb_frag_size(frag)); nbd++; DP(NETIF_MSG_TX_QUEUED, diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index fe712f955110..b89027c61937 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -5356,7 +5356,7 @@ static void tg3_tx(struct tg3_napi *tnapi) pci_unmap_page(tp->pdev, dma_unmap_addr(ri, mapping), - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_TODEVICE); while (ri->fragmented) { @@ -6510,14 +6510,14 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) } for (i = 0; i < last; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; entry = NEXT_TX(entry); txb = &tnapi->tx_buffers[entry]; pci_unmap_page(tnapi->tp->pdev, dma_unmap_addr(txb, mapping), - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); while (txb->fragmented) { txb->fragmented = false; @@ -6777,7 +6777,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i <= last; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - len = frag->size; + len = skb_frag_size(frag); mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0, len, DMA_TO_DEVICE); diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 2f4ced66612a..5d7872ecff52 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -116,7 +116,7 @@ bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array, for (j = 0; j < frag; j++) { dma_unmap_page(pdev, dma_unmap_addr(&array[index], dma_addr), - skb_shinfo(skb)->frags[j].size, DMA_TO_DEVICE); + skb_frag_size(&skb_shinfo(skb)->frags[j]), DMA_TO_DEVICE); dma_unmap_addr_set(&array[index], dma_addr, 0); BNA_QE_INDX_ADD(index, 1, depth); } @@ -2741,8 +2741,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) wis_used = 1; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - u16 size = frag->size; + const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + u16 size = skb_frag_size(frag); if (unlikely(size == 0)) { unmap_prod = unmap_q->producer_index; diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c index 0a511c4a0472..f9b602300040 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c @@ -1135,8 +1135,8 @@ static inline unsigned int compute_large_page_tx_descs(struct sk_buff *skb) len -= SGE_TX_DESC_MAX_PLEN; } for (i = 0; nfrags--; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - len = frag->size; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + len = skb_frag_size(frag); while (len > SGE_TX_DESC_MAX_PLEN) { count++; len -= SGE_TX_DESC_MAX_PLEN; @@ -1278,9 +1278,9 @@ static inline void write_tx_descs(struct adapter *adapter, struct sk_buff *skb, } mapping = skb_frag_dma_map(&adapter->pdev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); desc_mapping = mapping; - desc_len = frag->size; + desc_len = skb_frag_size(frag); pidx = write_large_page_tx_descs(pidx, &e1, &ce, &gen, &desc_mapping, &desc_len, @@ -1290,7 +1290,7 @@ static inline void write_tx_descs(struct adapter *adapter, struct sk_buff *skb, nfrags == 0); ce->skb = NULL; dma_unmap_addr_set(ce, dma_addr, mapping); - dma_unmap_len_set(ce, dma_len, frag->size); + dma_unmap_len_set(ce, dma_len, skb_frag_size(frag)); } ce->skb = skb; wmb(); diff --git a/drivers/net/ethernet/chelsio/cxgb3/sge.c b/drivers/net/ethernet/chelsio/cxgb3/sge.c index 2f46b37e5d16..cfb60e1f51da 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c @@ -254,7 +254,7 @@ static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q, while (frag_idx < nfrags && curflit < WR_FLITS) { pci_unmap_page(pdev, be64_to_cpu(sgp->addr[j]), - skb_shinfo(skb)->frags[frag_idx].size, + skb_frag_size(&skb_shinfo(skb)->frags[frag_idx]), PCI_DMA_TODEVICE); j ^= 1; if (j == 0) { @@ -977,11 +977,11 @@ static inline unsigned int make_sgl(const struct sk_buff *skb, nfrags = skb_shinfo(skb)->nr_frags; for (i = 0; i < nfrags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - mapping = skb_frag_dma_map(&pdev->dev, frag, 0, frag->size, + mapping = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); - sgp->len[j] = cpu_to_be32(frag->size); + sgp->len[j] = cpu_to_be32(skb_frag_size(frag)); sgp->addr[j] = cpu_to_be64(mapping); j ^= 1; if (j == 0) @@ -1544,7 +1544,7 @@ static void deferred_unmap_destructor(struct sk_buff *skb) si = skb_shinfo(skb); for (i = 0; i < si->nr_frags; i++) - pci_unmap_page(dui->pdev, *p++, si->frags[i].size, + pci_unmap_page(dui->pdev, *p++, skb_frag_size(&si->frags[i]), PCI_DMA_TODEVICE); } @@ -2118,7 +2118,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, rx_frag += nr_frags; __skb_frag_set_page(rx_frag, sd->pg_chunk.page); rx_frag->page_offset = sd->pg_chunk.offset + offset; - rx_frag->size = len; + skb_frag_size_set(rx_frag, len); skb->len += len; skb->data_len += len; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 56adf448b9fe..14f31d3a18d7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -215,8 +215,8 @@ static int map_skb(struct device *dev, const struct sk_buff *skb, end = &si->frags[si->nr_frags]; for (fp = si->frags; fp < end; fp++) { - *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size, - DMA_TO_DEVICE); + *++addr = dma_map_page(dev, fp->page, fp->page_offset, + skb_frag_size(fp), DMA_TO_DEVICE); if (dma_mapping_error(dev, *addr)) goto unwind; } @@ -224,7 +224,7 @@ static int map_skb(struct device *dev, const struct sk_buff *skb, unwind: while (fp-- > si->frags) - dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE); + dma_unmap_page(dev, *--addr, skb_frag_size(fp), DMA_TO_DEVICE); dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE); out_err: @@ -243,7 +243,7 @@ static void unmap_skb(struct device *dev, const struct sk_buff *skb, si = skb_shinfo(skb); end = &si->frags[si->nr_frags]; for (fp = si->frags; fp < end; fp++) - dma_unmap_page(dev, *addr++, fp->size, DMA_TO_DEVICE); + dma_unmap_page(dev, *addr++, skb_frag_size(fp), DMA_TO_DEVICE); } /** @@ -717,7 +717,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, sgl->addr0 = cpu_to_be64(addr[0] + start); nfrags++; } else { - sgl->len0 = htonl(si->frags[0].size); + sgl->len0 = htonl(skb_frag_size(&si->frags[0])); sgl->addr0 = cpu_to_be64(addr[1]); } @@ -732,13 +732,13 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge; for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) { - to->len[0] = cpu_to_be32(si->frags[i].size); - to->len[1] = cpu_to_be32(si->frags[++i].size); + to->len[0] = cpu_to_be32(skb_frag_size(&si->frags[i])); + to->len[1] = cpu_to_be32(skb_frag_size(&si->frags[++i])); to->addr[0] = cpu_to_be64(addr[i]); to->addr[1] = cpu_to_be64(addr[++i]); } if (nfrags) { - to->len[0] = cpu_to_be32(si->frags[i].size); + to->len[0] = cpu_to_be32(skb_frag_size(&si->frags[i])); to->len[1] = cpu_to_be32(0); to->addr[0] = cpu_to_be64(addr[i + 1]); } @@ -1417,7 +1417,7 @@ static inline void copy_frags(struct skb_shared_info *ssi, /* usually there's just one frag */ ssi->frags[0].page = gl->frags[0].page; ssi->frags[0].page_offset = gl->frags[0].page_offset + offset; - ssi->frags[0].size = gl->frags[0].size - offset; + skb_frag_size_set(&ssi->frags[0], skb_frag_size(&gl->frags[0]) - offset); ssi->nr_frags = gl->nfrags; n = gl->nfrags - 1; if (n) @@ -1718,8 +1718,8 @@ static int process_responses(struct sge_rspq *q, int budget) bufsz = get_buf_size(rsd); fp->page = rsd->page; fp->page_offset = q->offset; - fp->size = min(bufsz, len); - len -= fp->size; + skb_frag_size_set(fp, min(bufsz, len)); + len -= skb_frag_size(fp); if (!len) break; unmap_rx_buf(q->adap, &rxq->fl); @@ -1731,7 +1731,7 @@ static int process_responses(struct sge_rspq *q, int budget) */ dma_sync_single_for_cpu(q->adap->pdev_dev, get_buf_addr(rsd), - fp->size, DMA_FROM_DEVICE); + skb_frag_size(fp), DMA_FROM_DEVICE); si.va = page_address(si.frags[0].page) + si.frags[0].page_offset; @@ -1740,7 +1740,7 @@ static int process_responses(struct sge_rspq *q, int budget) si.nfrags = frags + 1; ret = q->handler(q, q->cur_desc, &si); if (likely(ret == 0)) - q->offset += ALIGN(fp->size, FL_ALIGN); + q->offset += ALIGN(skb_frag_size(fp), FL_ALIGN); else restore_rx_bufs(&si, &rxq->fl, frags); } else if (likely(rsp_type == RSP_TYPE_CPL)) { diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index cffb328c46c3..c2d456d90c00 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -296,8 +296,8 @@ static int map_skb(struct device *dev, const struct sk_buff *skb, si = skb_shinfo(skb); end = &si->frags[si->nr_frags]; for (fp = si->frags; fp < end; fp++) { - *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size, - DMA_TO_DEVICE); + *++addr = dma_map_page(dev, fp->page, fp->page_offset, + skb_frag_size(fp), DMA_TO_DEVICE); if (dma_mapping_error(dev, *addr)) goto unwind; } @@ -305,7 +305,7 @@ static int map_skb(struct device *dev, const struct sk_buff *skb, unwind: while (fp-- > si->frags) - dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE); + dma_unmap_page(dev, *--addr, skb_frag_size(fp), DMA_TO_DEVICE); dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE); out_err: @@ -899,7 +899,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq, sgl->addr0 = cpu_to_be64(addr[0] + start); nfrags++; } else { - sgl->len0 = htonl(si->frags[0].size); + sgl->len0 = htonl(skb_frag_size(&si->frags[0])); sgl->addr0 = cpu_to_be64(addr[1]); } @@ -915,13 +915,13 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq, to = (u8 *)end > (u8 *)tq->stat ? buf : sgl->sge; for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) { - to->len[0] = cpu_to_be32(si->frags[i].size); - to->len[1] = cpu_to_be32(si->frags[++i].size); + to->len[0] = cpu_to_be32(skb_frag_size(&si->frags[i])); + to->len[1] = cpu_to_be32(skb_frag_size(&si->frags[++i])); to->addr[0] = cpu_to_be64(addr[i]); to->addr[1] = cpu_to_be64(addr[++i]); } if (nfrags) { - to->len[0] = cpu_to_be32(si->frags[i].size); + to->len[0] = cpu_to_be32(skb_frag_size(&si->frags[i])); to->len[1] = cpu_to_be32(0); to->addr[0] = cpu_to_be64(addr[i + 1]); } @@ -1399,7 +1399,7 @@ struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl, ssi = skb_shinfo(skb); ssi->frags[0].page = gl->frags[0].page; ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len; - ssi->frags[0].size = gl->frags[0].size - pull_len; + skb_frag_size_set(&ssi->frags[0], skb_frag_size(&gl->frags[0]) - pull_len); if (gl->nfrags > 1) memcpy(&ssi->frags[1], &gl->frags[1], (gl->nfrags-1) * sizeof(skb_frag_t)); @@ -1451,7 +1451,7 @@ static inline void copy_frags(struct skb_shared_info *si, /* usually there's just one frag */ si->frags[0].page = gl->frags[0].page; si->frags[0].page_offset = gl->frags[0].page_offset + offset; - si->frags[0].size = gl->frags[0].size - offset; + skb_frag_size_set(&si->frags[0], skb_frag_size(&gl->frags[0]) - offset); si->nr_frags = gl->nfrags; n = gl->nfrags - 1; @@ -1702,8 +1702,8 @@ int process_responses(struct sge_rspq *rspq, int budget) bufsz = get_buf_size(sdesc); fp->page = sdesc->page; fp->page_offset = rspq->offset; - fp->size = min(bufsz, len); - len -= fp->size; + skb_frag_size_set(fp, min(bufsz, len)); + len -= skb_frag_size(fp); if (!len) break; unmap_rx_buf(rspq->adapter, &rxq->fl); @@ -1717,7 +1717,7 @@ int process_responses(struct sge_rspq *rspq, int budget) */ dma_sync_single_for_cpu(rspq->adapter->pdev_dev, get_buf_addr(sdesc), - fp->size, DMA_FROM_DEVICE); + skb_frag_size(fp), DMA_FROM_DEVICE); gl.va = (page_address(gl.frags[0].page) + gl.frags[0].page_offset); prefetch(gl.va); @@ -1728,7 +1728,7 @@ int process_responses(struct sge_rspq *rspq, int budget) */ ret = rspq->handler(rspq, rspq->cur_desc, &gl); if (likely(ret == 0)) - rspq->offset += ALIGN(fp->size, FL_ALIGN); + rspq->offset += ALIGN(skb_frag_size(fp), FL_ALIGN); else restore_rx_bufs(&gl, &rxq->fl, frag); } else if (likely(rsp_type == RSP_TYPE_CPL)) { diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 1bc908f595de..c3786fda11db 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -599,16 +599,16 @@ static inline void enic_queue_wq_skb_cont(struct enic *enic, struct vnic_wq *wq, struct sk_buff *skb, unsigned int len_left, int loopback) { - skb_frag_t *frag; + const skb_frag_t *frag; /* Queue additional data fragments */ for (frag = skb_shinfo(skb)->frags; len_left; frag++) { - len_left -= frag->size; + len_left -= skb_frag_size(frag); enic_queue_wq_desc_cont(wq, skb, skb_frag_dma_map(&enic->pdev->dev, - frag, 0, frag->size, + frag, 0, skb_frag_size(frag), DMA_TO_DEVICE), - frag->size, + skb_frag_size(frag), (len_left == 0), /* EOP? */ loopback); } @@ -717,8 +717,8 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic, * for additional data fragments */ for (frag = skb_shinfo(skb)->frags; len_left; frag++) { - len_left -= frag->size; - frag_len_left = frag->size; + len_left -= skb_frag_size(frag); + frag_len_left = skb_frag_size(frag); offset = 0; while (frag_len_left) { diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 679b8041e43a..706fc5989939 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -636,17 +636,17 @@ static int make_tx_wrbs(struct be_adapter *adapter, struct be_queue_info *txq, } for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = + const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; busaddr = skb_frag_dma_map(dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); if (dma_mapping_error(dev, busaddr)) goto dma_err; wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, frag->size); + wrb_fill(wrb, busaddr, skb_frag_size(frag)); be_dws_cpu_to_le(wrb, sizeof(*wrb)); queue_head_inc(txq); - copied += frag->size; + copied += skb_frag_size(frag); } if (dummy_wrb) { @@ -1069,7 +1069,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, skb_frag_set_page(skb, 0, page_info->page); skb_shinfo(skb)->frags[0].page_offset = page_info->page_offset + hdr_len; - skb_shinfo(skb)->frags[0].size = curr_frag_len - hdr_len; + skb_frag_size_set(&skb_shinfo(skb)->frags[0], curr_frag_len - hdr_len); skb->data_len = curr_frag_len - hdr_len; skb->truesize += rx_frag_size; skb->tail += hdr_len; @@ -1095,13 +1095,13 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, skb_frag_set_page(skb, j, page_info->page); skb_shinfo(skb)->frags[j].page_offset = page_info->page_offset; - skb_shinfo(skb)->frags[j].size = 0; + skb_frag_size_set(&skb_shinfo(skb)->frags[j], 0); skb_shinfo(skb)->nr_frags++; } else { put_page(page_info->page); } - skb_shinfo(skb)->frags[j].size += curr_frag_len; + skb_frag_size_add(&skb_shinfo(skb)->frags[j], curr_frag_len); skb->len += curr_frag_len; skb->data_len += curr_frag_len; skb->truesize += rx_frag_size; @@ -1176,11 +1176,11 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, skb_frag_set_page(skb, j, page_info->page); skb_shinfo(skb)->frags[j].page_offset = page_info->page_offset; - skb_shinfo(skb)->frags[j].size = 0; + skb_frag_size_set(&skb_shinfo(skb)->frags[j], 0); } else { put_page(page_info->page); } - skb_shinfo(skb)->frags[j].size += curr_frag_len; + skb_frag_size_add(&skb_shinfo(skb)->frags[j], curr_frag_len); skb->truesize += rx_frag_size; remaining -= curr_frag_len; index_inc(&rxcp->rxq_idx, rxq->len); diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index adb462d0b8d3..0d4d4f68d4ed 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -1676,7 +1676,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, /* copy sg1entry data */ sg1entry->l_key = lkey; - sg1entry->len = frag->size; + sg1entry->len = skb_frag_size(frag); sg1entry->vaddr = ehea_map_vaddr(skb_frag_address(frag)); swqe->descriptors++; @@ -1689,7 +1689,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, sgentry = &sg_list[i - sg1entry_contains_frag_data]; sgentry->l_key = lkey; - sgentry->len = frag->size; + sgentry->len = frag_size(frag); sgentry->vaddr = ehea_map_vaddr(skb_frag_address(frag)); swqe->descriptors++; } diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 6b3a033d9de5..ed79b2d3ad3e 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -1453,7 +1453,7 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev) /* skb fragments */ for (i = 0; i < nr_frags; ++i) { struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - len = frag->size; + len = skb_frag_size(frag); if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF)) goto undo_frame; diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 4da972eaabb4..b1cd41b9c61c 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1014,15 +1014,15 @@ retry_bounce: /* Map the frags */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; dma_addr = skb_frag_dma_map(&adapter->vdev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) goto map_failed_frags; - descs[i+1].fields.flags_len = desc_flags | frag->size; + descs[i+1].fields.flags_len = desc_flags | skb_frag_size(frag); descs[i+1].fields.address = dma_addr; } diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 7b54d7246150..cf480b554622 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -2894,10 +2894,10 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { @@ -3183,7 +3183,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), max_txd_pwr); if (adapter->pcix_82544) count += nr_frags; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 035ce73c388e..680312710a78 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4673,10 +4673,10 @@ static int e1000_tx_map(struct e1000_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { @@ -4943,7 +4943,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), max_txd_pwr); if (adapter->hw.mac.tx_pkt_filtering) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 837adbbce772..f9b818267de8 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -4268,7 +4268,7 @@ static void igb_tx_map(struct igb_ring *tx_ring, i = 0; } - size = frag->size; + size = skb_frag_size(frag); data_len -= size; dma = skb_frag_dma_map(tx_ring->dev, frag, 0, diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 23cc40f22d6f..1bd9abddcc59 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2045,7 +2045,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; count++; i++; @@ -2053,7 +2053,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, i = 0; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); buffer_info = &tx_ring->buffer_info[i]; BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD); diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 88558b1aac07..e21148f8b160 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -1383,10 +1383,10 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = frag->size; + len = skb_frag_size(frag); offset = 0; while (len) { diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 8075d11b4cde..09b8e88b2999 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6545,9 +6545,9 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, frag = &skb_shinfo(skb)->frags[f]; #ifdef IXGBE_FCOE - size = min_t(unsigned int, data_len, frag->size); + size = min_t(unsigned int, data_len, skb_frag_size(frag)); #else - size = frag->size; + size = skb_frag_size(frag); #endif data_len -= size; f++; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 4930c4605493..5e92cc2079bd 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2912,10 +2912,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter, } for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; - len = min((unsigned int)frag->size, total); + len = min((unsigned int)skb_frag_size(frag), total); offset = 0; while (len) { @@ -3096,7 +3096,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) count += TXD_USE_COUNT(skb_headlen(skb)); for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f])); if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count)) { adapter->tx_busy++; diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 48a0a23f342f..7a0c746f2749 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -1920,7 +1920,7 @@ jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx) u8 hidma = jme->dev->features & NETIF_F_HIGHDMA; int i, nr_frags = skb_shinfo(skb)->nr_frags; int mask = jme->tx_ring_mask; - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; u32 len; for (i = 0 ; i < nr_frags ; ++i) { @@ -1930,7 +1930,7 @@ jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx) jme_fill_tx_map(jme->pdev, ctxdesc, ctxbi, skb_frag_page(frag), - frag->page_offset, frag->size, hidma); + frag->page_offset, skb_frag_size(frag), hidma); } len = skb_is_nonlinear(skb) ? skb_headlen(skb) : skb->len; diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index f6821aa5ffbf..194a03113802 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -713,8 +713,9 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) int frag; for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag]; - if (fragp->size <= 8 && fragp->page_offset & 7) + const skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag]; + + if (skb_frag_size(fragp) <= 8 && fragp->page_offset & 7) return 1; } @@ -751,10 +752,10 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) } desc->l4i_chk = 0; - desc->byte_cnt = this_frag->size; + desc->byte_cnt = skb_frag_size(this_frag); desc->buf_ptr = skb_frag_dma_map(mp->dev->dev.parent, this_frag, 0, - this_frag->size, + skb_frag_size(this_frag), DMA_TO_DEVICE); } } diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 297730359b79..c7b60839ac99 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -2770,10 +2770,10 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, control |= BMU_STFWD; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; map = skb_frag_dma_map(&hw->pdev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); e = e->next; e->skb = skb; @@ -2783,9 +2783,9 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, tf->dma_lo = map; tf->dma_hi = (u64) map >> 32; dma_unmap_addr_set(e, mapaddr, map); - dma_unmap_len_set(e, maplen, frag->size); + dma_unmap_len_set(e, maplen, skb_frag_size(frag)); - tf->control = BMU_OWN | BMU_SW | control | frag->size; + tf->control = BMU_OWN | BMU_SW | control | skb_frag_size(frag); } tf->control |= BMU_EOF | BMU_IRQ_EOF; } diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 92634907bf8d..7b083c438a14 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1225,10 +1225,10 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, dma_unmap_len_set(re, data_size, size); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; re->frag_addr[i] = skb_frag_dma_map(&pdev->dev, frag, 0, - frag->size, + skb_frag_size(frag), DMA_FROM_DEVICE); if (dma_mapping_error(&pdev->dev, re->frag_addr[i])) @@ -1239,7 +1239,7 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, map_page_error: while (--i >= 0) { pci_unmap_page(pdev, re->frag_addr[i], - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_FROMDEVICE); } @@ -1263,7 +1263,7 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) pci_unmap_page(pdev, re->frag_addr[i], - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_FROMDEVICE); } @@ -1936,7 +1936,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; mapping = skb_frag_dma_map(&hw->pdev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); if (dma_mapping_error(&hw->pdev->dev, mapping)) goto mapping_unwind; @@ -1952,11 +1952,11 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, re = sky2->tx_ring + slot; re->flags = TX_MAP_PAGE; dma_unmap_addr_set(re, mapaddr, mapping); - dma_unmap_len_set(re, maplen, frag->size); + dma_unmap_len_set(re, maplen, skb_frag_size(frag)); le = get_tx_le(sky2, &slot); le->addr = cpu_to_le32(lower_32_bits(mapping)); - le->length = cpu_to_le16(frag->size); + le->length = cpu_to_le16(skb_frag_size(frag)); le->ctrl = ctrl; le->opcode = OP_BUFFER | HW_OWNER; } @@ -2484,7 +2484,7 @@ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space, } else { size = min(length, (unsigned) PAGE_SIZE); - frag->size = size; + skb_frag_size_set(frag, size); skb->data_len += size; skb->truesize += PAGE_SIZE; skb->len += size; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 37cc9e5c56be..46a0df9afc3c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -135,7 +135,7 @@ static void mlx4_en_init_rx_desc(struct mlx4_en_priv *priv, /* Set size and memtype fields */ for (i = 0; i < priv->num_frags; i++) { - skb_frags[i].size = priv->frag_info[i].frag_size; + skb_frag_size_set(&skb_frags[i], priv->frag_info[i].frag_size); rx_desc->data[i].byte_count = cpu_to_be32(priv->frag_info[i].frag_size); rx_desc->data[i].lkey = cpu_to_be32(priv->mdev->mr.key); @@ -194,7 +194,7 @@ static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv, dma = be64_to_cpu(rx_desc->data[nr].addr); en_dbg(DRV, priv, "Unmapping buffer at dma:0x%llx\n", (u64) dma); - pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, + pci_unmap_single(mdev->pdev, dma, skb_frag_size(&skb_frags[nr]), PCI_DMA_FROMDEVICE); put_page(skb_frags[nr].page); } @@ -421,7 +421,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv, /* Save page reference in skb */ skb_frags_rx[nr].page = skb_frags[nr].page; - skb_frags_rx[nr].size = skb_frags[nr].size; + skb_frag_size_set(&skb_frags_rx[nr], skb_frag_size(&skb_frags[nr])); skb_frags_rx[nr].page_offset = skb_frags[nr].page_offset; dma = be64_to_cpu(rx_desc->data[nr].addr); @@ -430,13 +430,13 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv, goto fail; /* Unmap buffer */ - pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size, + pci_unmap_single(mdev->pdev, dma, skb_frag_size(&skb_frags_rx[nr]), PCI_DMA_FROMDEVICE); } /* Adjust size of last fragment to match actual length */ if (nr > 0) - skb_frags_rx[nr - 1].size = length - - priv->frag_info[nr - 1].frag_prefix_size; + skb_frag_size_set(&skb_frags_rx[nr - 1], + length - priv->frag_info[nr - 1].frag_prefix_size); return nr; fail: @@ -506,7 +506,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, skb_shinfo(skb)->frags[0].page_offset += HEADER_COPY_SIZE; /* Adjust size of first fragment */ - skb_shinfo(skb)->frags[0].size -= HEADER_COPY_SIZE; + skb_frag_size_sub(&skb_shinfo(skb)->frags[0], HEADER_COPY_SIZE); skb->data_len = length - HEADER_COPY_SIZE; } return skb; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 6e03de034ac7..2a192c2f207d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -226,7 +226,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, frag = &skb_shinfo(skb)->frags[i]; pci_unmap_page(mdev->pdev, (dma_addr_t) be64_to_cpu(data[i].addr), - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); } } /* Stamp the freed descriptor */ @@ -256,7 +256,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, frag = &skb_shinfo(skb)->frags[i]; pci_unmap_page(mdev->pdev, (dma_addr_t) be64_to_cpu(data->addr), - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); ++data; } } @@ -550,7 +550,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb)); if (skb_shinfo(skb)->nr_frags) memcpy(((void *)(inl + 1)) + skb_headlen(skb), fragptr, - skb_shinfo(skb)->frags[0].size); + skb_frag_size(&skb_shinfo(skb)->frags[0])); } else { inl->byte_count = cpu_to_be32(1 << 31 | spc); @@ -570,7 +570,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk skb_headlen(skb) - spc); if (skb_shinfo(skb)->nr_frags) memcpy(((void *)(inl + 1)) + skb_headlen(skb) - spc, - fragptr, skb_shinfo(skb)->frags[0].size); + fragptr, skb_frag_size(&skb_shinfo(skb)->frags[0])); } wmb(); @@ -757,11 +757,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) for (i = skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) { frag = &skb_shinfo(skb)->frags[i]; dma = pci_map_page(mdev->dev->pdev, frag->page, frag->page_offset, - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); data->addr = cpu_to_be64(dma); data->lkey = cpu_to_be32(mdev->mr.key); wmb(); - data->byte_count = cpu_to_be32(frag->size); + data->byte_count = cpu_to_be32(skb_frag_size(frag)); --data; } diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 710c4aead146..7ece990381c8 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4700,7 +4700,7 @@ static void send_packet(struct sk_buff *skb, struct net_device *dev) ++hw->tx_int_cnt; dma_buf = DMA_BUFFER(desc); - dma_buf->len = this_frag->size; + dma_buf->len = skb_frag_size(this_frag); dma_buf->dma = pci_map_single( hw_priv->pdev, diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 26637279cd67..c970a48436dc 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -1216,7 +1216,7 @@ myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va, skb_frags = skb_shinfo(skb)->frags; while (len > 0) { memcpy(skb_frags, rx_frags, sizeof(*skb_frags)); - len -= rx_frags->size; + len -= skb_frag_size(rx_frags); skb_frags++; rx_frags++; skb_shinfo(skb)->nr_frags++; @@ -1228,7 +1228,7 @@ myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va, * manually */ skb_copy_to_linear_data(skb, va, hlen); skb_shinfo(skb)->frags[0].page_offset += hlen; - skb_shinfo(skb)->frags[0].size -= hlen; + skb_frag_size_sub(&skb_shinfo(skb)->frags[0], hlen); skb->data_len -= hlen; skb->tail += hlen; skb_pull(skb, MXGEFW_PAD); @@ -1345,9 +1345,9 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, __skb_frag_set_page(&rx_frags[i], rx->info[idx].page); rx_frags[i].page_offset = rx->info[idx].page_offset; if (remainder < MYRI10GE_ALLOC_SIZE) - rx_frags[i].size = remainder; + skb_frag_size_set(&rx_frags[i], remainder); else - rx_frags[i].size = MYRI10GE_ALLOC_SIZE; + skb_frag_size_set(&rx_frags[i], MYRI10GE_ALLOC_SIZE); rx->cnt++; idx = rx->cnt & rx->mask; remainder -= MYRI10GE_ALLOC_SIZE; @@ -1355,7 +1355,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, if (lro_enabled) { rx_frags[0].page_offset += MXGEFW_PAD; - rx_frags[0].size -= MXGEFW_PAD; + skb_frag_size_sub(&rx_frags[0], MXGEFW_PAD); len -= MXGEFW_PAD; lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags, /* opaque, will come back in get_frag_header */ @@ -1382,7 +1382,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, /* Attach the pages to the skb, and trim off any padding */ myri10ge_rx_skb_build(skb, va, rx_frags, len, hlen); - if (skb_shinfo(skb)->frags[0].size <= 0) { + if (skb_frag_size(&skb_shinfo(skb)->frags[0]) <= 0) { skb_frag_unref(skb, 0); skb_shinfo(skb)->nr_frags = 0; } @@ -2926,7 +2926,7 @@ again: idx = (count + tx->req) & tx->mask; frag = &skb_shinfo(skb)->frags[frag_idx]; frag_idx++; - len = frag->size; + len = skb_frag_size(frag); bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len, DMA_TO_DEVICE); dma_unmap_addr_set(&tx->info[idx], bus, bus); diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c index 73616b911327..2b8f64ddfb55 100644 --- a/drivers/net/ethernet/natsemi/ns83820.c +++ b/drivers/net/ethernet/natsemi/ns83820.c @@ -1161,11 +1161,11 @@ again: break; buf = skb_frag_dma_map(&dev->pci_dev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); dprintk("frag: buf=%08Lx page=%08lx offset=%08lx\n", (long long)buf, (long) page_to_pfn(frag->page), frag->page_offset); - len = frag->size; + len = skb_frag_size(frag); frag++; nr_frags--; } diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index bdd3e6a330cd..c27fb3dda9f4 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -2350,12 +2350,12 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, if (frg_cnt) { txds++; for (j = 0; j < frg_cnt; j++, txds++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[j]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[j]; if (!txds->Buffer_Pointer) break; pci_unmap_page(nic->pdev, (dma_addr_t)txds->Buffer_Pointer, - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); } } memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds)); @@ -4185,16 +4185,16 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) frg_cnt = skb_shinfo(skb)->nr_frags; /* For fragmented SKB. */ for (i = 0; i < frg_cnt; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; /* A '0' length fragment will be ignored */ - if (!frag->size) + if (!skb_frag_size(frag)) continue; txdp++; txdp->Buffer_Pointer = (u64)skb_frag_dma_map(&sp->pdev->dev, frag, 0, - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); - txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); + txdp->Control_1 = TXD_BUFFER0_SIZE(skb_frag_size(frag)); if (offload_type == SKB_GSO_UDP) txdp->Control_1 |= TXD_UFO_EN; } diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index a66f8fc0401e..671e166b5af1 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -585,7 +585,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, for (j = 0; j < frg_cnt; j++) { pci_unmap_page(fifo->pdev, txd_priv->dma_buffers[i++], - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); frag += 1; } @@ -920,11 +920,11 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) frag = &skb_shinfo(skb)->frags[0]; for (i = 0; i < frg_cnt; i++) { /* ignore 0 length fragment */ - if (!frag->size) + if (!skb_frag_size(frag)) continue; dma_pointer = (u64)skb_frag_dma_map(&fifo->pdev->dev, frag, - 0, frag->size, + 0, skb_frag_size(frag), DMA_TO_DEVICE); if (unlikely(dma_mapping_error(&fifo->pdev->dev, dma_pointer))) @@ -936,7 +936,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) txdl_priv->dma_buffers[j] = dma_pointer; vxge_hw_fifo_txdl_buffer_set(fifo_hw, dtr, j++, dma_pointer, - frag->size); + skb_frag_size(frag)); frag += 1; } @@ -979,7 +979,7 @@ _exit1: for (; j < i; j++) { pci_unmap_page(fifo->pdev, txdl_priv->dma_buffers[j], - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); frag += 1; } @@ -1050,7 +1050,7 @@ vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata) for (j = 0; j < frg_cnt; j++) { pci_unmap_page(fifo->pdev, txd_priv->dma_buffers[i++], - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); frag += 1; } diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index d7763ab841d8..1e37eb98c4e2 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -2099,8 +2099,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* add fragments to entries count */ for (i = 0; i < fragments; i++) { - entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) + - ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); + u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + + entries += (size >> NV_TX2_TSO_MAX_SHIFT) + + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } spin_lock_irqsave(&np->lock, flags); @@ -2138,8 +2140,8 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* setup the fragments */ for (i = 0; i < fragments; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = frag->size; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + u32 size = skb_frag_size(frag); offset = 0; do { @@ -2211,8 +2213,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, /* add fragments to entries count */ for (i = 0; i < fragments; i++) { - entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) + - ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); + u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + + entries += (size >> NV_TX2_TSO_MAX_SHIFT) + + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } spin_lock_irqsave(&np->lock, flags); @@ -2253,7 +2257,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, /* setup the fragments */ for (i = 0; i < fragments; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = frag->size; + u32 size = skb_frag_size(frag); offset = 0; do { diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index c6f005684677..49b549ff2c78 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -300,9 +300,9 @@ static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac, pci_unmap_single(pdev, dmas[0], skb_headlen(skb), PCI_DMA_TODEVICE); for (f = 0; f < nfrags; f++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; - pci_unmap_page(pdev, dmas[f+1], frag->size, PCI_DMA_TODEVICE); + pci_unmap_page(pdev, dmas[f+1], skb_frag_size(frag), PCI_DMA_TODEVICE); } dev_kfree_skb_irq(skb); @@ -1506,8 +1506,8 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; map[i + 1] = skb_frag_dma_map(&mac->dma_pdev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); - map_size[i+1] = frag->size; + skb_frag_size(frag), DMA_TO_DEVICE); + map_size[i+1] = skb_frag_size(frag); if (dma_mapping_error(&mac->dma_pdev->dev, map[i + 1])) { nfrags = i; goto out_err_nolock; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index e2ba78be1c2a..8cf3173ba488 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1905,13 +1905,13 @@ netxen_map_tx_skb(struct pci_dev *pdev, frag = &skb_shinfo(skb)->frags[i]; nf = &pbuf->frag_array[i+1]; - map = skb_frag_dma_map(&pdev->dev, frag, 0, frag->size, + map = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, map)) goto unwind; nf->dma = map; - nf->length = frag->size; + nf->length = skb_frag_size(frag); } return 0; @@ -1962,7 +1962,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) { frag = &skb_shinfo(skb)->frags[i]; - delta += frag->size; + delta += skb_frag_size(frag); } if (!__pskb_pull_tail(skb, delta)) diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 46f9b6499f9b..a4bdff438a5e 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -2388,7 +2388,7 @@ static int ql_send_map(struct ql3_adapter *qdev, seg++; } - map = skb_frag_dma_map(&qdev->pdev->dev, frag, 0, frag->size, + map = skb_frag_dma_map(&qdev->pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); err = dma_mapping_error(&qdev->pdev->dev, map); @@ -2401,9 +2401,9 @@ static int ql_send_map(struct ql3_adapter *qdev, oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = cpu_to_le32(frag->size); + oal_entry->len = cpu_to_le32(skb_frag_size(frag)); dma_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); - dma_unmap_len_set(&tx_cb->map[seg], maplen, frag->size); + dma_unmap_len_set(&tx_cb->map[seg], maplen, skb_frag_size(frag)); } /* Terminate the last segment. */ oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index eac19e7d2761..106503f118f6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2135,13 +2135,13 @@ qlcnic_map_tx_skb(struct pci_dev *pdev, frag = &skb_shinfo(skb)->frags[i]; nf = &pbuf->frag_array[i+1]; - map = skb_frag_dma_map(&pdev->dev, frag, 0, frag->size, + map = skb_frag_dma_map(&pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); if (dma_mapping_error(&pdev->dev, map)) goto unwind; nf->dma = map; - nf->length = frag->size; + nf->length = skb_frag_size(frag); } return 0; @@ -2221,7 +2221,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (!skb_is_gso(skb) && frag_count > QLCNIC_MAX_FRAGS_PER_TX) { for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++) - delta += skb_shinfo(skb)->frags[i].size; + delta += skb_frag_size(&skb_shinfo(skb)->frags[i]); if (!__pskb_pull_tail(skb, delta)) goto drop_packet; diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index f2d9bb78ec7f..c92afcd912e2 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1431,7 +1431,7 @@ static int ql_map_send(struct ql_adapter *qdev, map_idx++; } - map = skb_frag_dma_map(&qdev->pdev->dev, frag, 0, frag->size, + map = skb_frag_dma_map(&qdev->pdev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); err = dma_mapping_error(&qdev->pdev->dev, map); @@ -1443,10 +1443,10 @@ static int ql_map_send(struct ql_adapter *qdev, } tbd->addr = cpu_to_le64(map); - tbd->len = cpu_to_le32(frag->size); + tbd->len = cpu_to_le32(skb_frag_size(frag)); dma_unmap_addr_set(&tx_ring_desc->map[map_idx], mapaddr, map); dma_unmap_len_set(&tx_ring_desc->map[map_idx], maplen, - frag->size); + skb_frag_size(frag)); } /* Save the number of segments we've mapped. */ diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 5dcd5be03f31..ee5da9293ce0 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -777,12 +777,12 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, entry = NEXT_TX(entry); for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; u32 len; u32 ctrl; dma_addr_t mapping; - len = this_frag->size; + len = skb_frag_size(this_frag); mapping = dma_map_single(&cp->pdev->dev, skb_frag_address(this_frag), len, PCI_DMA_TODEVICE); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 2ce60709a455..aa39e771175c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5413,7 +5413,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, entry = tp->cur_tx; for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { - skb_frag_t *frag = info->frags + cur_frag; + const skb_frag_t *frag = info->frags + cur_frag; dma_addr_t mapping; u32 status, len; void *addr; @@ -5421,7 +5421,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, entry = (entry + 1) % NUM_TX_DESC; txd = tp->TxDescArray + entry; - len = frag->size; + len = skb_frag_size(frag); addr = skb_frag_address(frag); mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(d, mapping))) { diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 91a6b7123539..adbda182f159 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -481,7 +481,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, skb_frag_set_page(skb, 0, page); skb_shinfo(skb)->frags[0].page_offset = efx_rx_buf_offset(efx, rx_buf); - skb_shinfo(skb)->frags[0].size = rx_buf->len; + skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx_buf->len); skb_shinfo(skb)->nr_frags = 1; skb->len = rx_buf->len; diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 3964a62dde8b..df88c5430f95 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -238,7 +238,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) if (i >= skb_shinfo(skb)->nr_frags) break; fragment = &skb_shinfo(skb)->frags[i]; - len = fragment->size; + len = skb_frag_size(fragment); i++; /* Map for DMA */ unmap_single = false; @@ -926,11 +926,11 @@ static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, skb_frag_t *frag) { st->unmap_addr = skb_frag_dma_map(&efx->pci_dev->dev, frag, 0, - frag->size, DMA_TO_DEVICE); + skb_frag_size(frag), DMA_TO_DEVICE); if (likely(!dma_mapping_error(&efx->pci_dev->dev, st->unmap_addr))) { st->unmap_single = false; - st->unmap_len = frag->size; - st->in_len = frag->size; + st->unmap_len = skb_frag_size(frag); + st->in_len = skb_frag_size(frag); st->dma_addr = st->unmap_addr; return 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c0ee6b6b0198..87a6b2e59e04 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1106,8 +1106,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) } for (i = 0; i < nfrags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - int len = frag->size; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + int len = skb_frag_size(frag); entry = (++priv->cur_tx) % txsize; desc = priv->dma_tx + entry; diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index d9460d81a137..fd40988c19a6 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -2051,7 +2051,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, __skb_frag_set_page(frag, page->buffer); __skb_frag_ref(frag); frag->page_offset = off; - frag->size = hlen - swivel; + skb_frag_size_set(frag, hlen - swivel); /* any more data? */ if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) { @@ -2075,7 +2075,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, __skb_frag_set_page(frag, page->buffer); __skb_frag_ref(frag); frag->page_offset = 0; - frag->size = hlen; + skb_frag_size_set(frag, hlen); RX_USED_ADD(page, hlen + cp->crc_size); } @@ -2826,9 +2826,9 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring, entry = TX_DESC_NEXT(ring, entry); for (frag = 0; frag < nr_frags; frag++) { - skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag]; + const skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag]; - len = fragp->size; + len = skb_frag_size(fragp); mapping = skb_frag_dma_map(&cp->pdev->dev, fragp, 0, len, DMA_TO_DEVICE); diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 23740e848ac9..73c708107a37 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -3594,7 +3594,7 @@ static int release_tx_packet(struct niu *np, struct tx_ring_info *rp, int idx) tb = &rp->tx_buffs[idx]; BUG_ON(tb->skb != NULL); np->ops->unmap_page(np->device, tb->mapping, - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), DMA_TO_DEVICE); idx = NEXT_TX(rp, idx); } @@ -6727,9 +6727,9 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb, } for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - len = frag->size; + len = skb_frag_size(frag); mapping = np->ops->map_page(np->device, skb_frag_page(frag), frag->page_offset, len, DMA_TO_DEVICE); diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 6b62a73227c2..ceab215bb4a3 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -1065,12 +1065,12 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, entry = NEXT_TX(entry); for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; u32 len; dma_addr_t mapping; u64 this_ctrl; - len = this_frag->size; + len = skb_frag_size(this_frag); mapping = skb_frag_dma_map(&gp->pdev->dev, this_frag, 0, len, DMA_TO_DEVICE); this_ctrl = ctrl; diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 869d47be54b4..c517dac02ae1 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2305,10 +2305,10 @@ static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb, entry = NEXT_TX(entry); for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; u32 len, mapping, this_txflags; - len = this_frag->size; + len = skb_frag_size(this_frag); mapping = skb_frag_dma_map(hp->dma_dev, this_frag, 0, len, DMA_TO_DEVICE); this_txflags = tx_flags; diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index c77e3bf4750a..3a90af6d111c 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1493,12 +1493,12 @@ bdx_tx_map_skb(struct bdx_priv *priv, struct sk_buff *skb, bdx_tx_db_inc_wptr(db); for (i = 0; i < nr_frags; i++) { - struct skb_frag_struct *frag; + const struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[i]; - db->wptr->len = frag->size; + db->wptr->len = skb_frag_size(frag); db->wptr->addr.dma = skb_frag_dma_map(&priv->pdev->dev, frag, - 0, frag->size, + 0, skb_frag_size(frag), DMA_TO_DEVICE); pbl++; diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 1e2af96fc29c..78e3fb226cce 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c @@ -1713,7 +1713,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset; frags[n].cpa_lo = cpa; frags[n].cpa_hi = cpa >> 32; - frags[n].length = f->size; + frags[n].length = skb_frag_size(f); frags[n].hash_for_home = hash_for_home; n++; } diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index a03996cf88ed..a8df7eca0956 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -709,13 +709,13 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev) data->txring[tx].len = skb_headlen(skb); misc |= TSI108_TX_SOF; } else { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag, 0, - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); - data->txring[tx].len = frag->size; + data->txring[tx].len = skb_frag_size(frag); } if (i == frags - 1) diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index b47bce1a2e2a..4535d7cc848e 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2554,16 +2554,16 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, /* Handle fragments */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; tdinfo->skb_dma[i + 1] = skb_frag_dma_map(&vptr->pdev->dev, frag, 0, - frag->size, + skb_frag_size(frag), DMA_TO_DEVICE); td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]); td_ptr->td_buf[i + 1].pa_high = 0; - td_ptr->td_buf[i + 1].size = cpu_to_le16(frag->size); + td_ptr->td_buf[i + 1].size = cpu_to_le16(skb_frag_size(frag)); } tdinfo->nskb_dma = i + 1; diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 66e3c36c3733..85ba4d9ac170 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -716,8 +716,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; cur_p->phys = dma_map_single(ndev->dev.parent, skb_frag_address(frag), - frag->size, DMA_TO_DEVICE); - cur_p->len = frag->size; + frag_size(frag), DMA_TO_DEVICE); + cur_p->len = frag_size(frag); cur_p->app0 = 0; frag++; } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b8225f3b31d1..0d4841bed0f9 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -147,14 +147,14 @@ static void set_skb_frag(struct sk_buff *skb, struct page *page, skb_frag_t *f; f = &skb_shinfo(skb)->frags[i]; - f->size = min((unsigned)PAGE_SIZE - offset, *len); + skb_frag_size_set(f, min((unsigned)PAGE_SIZE - offset, *len)); f->page_offset = offset; __skb_frag_set_page(f, page); - skb->data_len += f->size; - skb->len += f->size; + skb->data_len += skb_frag_size(f); + skb->len += skb_frag_size(f); skb_shinfo(skb)->nr_frags++; - *len -= f->size; + *len -= skb_frag_size(f); } static struct sk_buff *page_to_skb(struct virtnet_info *vi, diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 902f284fd054..b771ebac0f01 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -656,8 +656,8 @@ vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd, __skb_frag_set_page(frag, rbi->page); frag->page_offset = 0; - frag->size = rcd->len; - skb->data_len += frag->size; + skb_frag_size_set(frag, rcd->len); + skb->data_len += rcd->len; skb->truesize += PAGE_SIZE; skb_shinfo(skb)->nr_frags++; } @@ -745,21 +745,21 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, } for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; tbi = tq->buf_info + tq->tx_ring.next2fill; tbi->map_type = VMXNET3_MAP_PAGE; tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, - 0, frag->size, + 0, skb_frag_size(frag), DMA_TO_DEVICE); - tbi->len = frag->size; + tbi->len = skb_frag_size(frag); gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); - gdesc->dword[2] = cpu_to_le32(dw2 | frag->size); + gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); gdesc->dword[3] = 0; dev_dbg(&adapter->netdev->dev, diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 8d70b44fcd8a..d5508957200e 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -334,7 +334,7 @@ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) count++; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - unsigned long size = skb_shinfo(skb)->frags[i].size; + unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]); unsigned long bytes; while (size > 0) { BUG_ON(copy_off > MAX_BUFFER_OFFSET); @@ -526,7 +526,7 @@ static int netbk_gop_skb(struct sk_buff *skb, for (i = 0; i < nr_frags; i++) { netbk_gop_frag_copy(vif, skb, npo, skb_frag_page(&skb_shinfo(skb)->frags[i]), - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), skb_shinfo(skb)->frags[i].page_offset, &head); } diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 6e5d4c09e5d7..226faab23603 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -467,7 +467,7 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, tx->gref = np->grant_tx_ref[id] = ref; tx->offset = frag->page_offset; - tx->size = frag->size; + tx->size = skb_frag_size(frag); tx->flags = 0; } @@ -965,7 +965,7 @@ err: if (rx->status > len) { skb_shinfo(skb)->frags[0].page_offset = rx->offset + len; - skb_shinfo(skb)->frags[0].size = rx->status - len; + skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); skb->data_len = rx->status - len; } else { __skb_fill_page_desc(skb, 0, NULL, 0, 0); diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 77ac217ad5ce..be69da38ccaa 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -1814,8 +1814,8 @@ static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, copy = min(datalen, sglen); if (i && page == frags[i - 1].page && sgoffset + sg->offset == - frags[i - 1].page_offset + frags[i - 1].size) { - frags[i - 1].size += copy; + frags[i - 1].page_offset + skb_frag_size(&frags[i - 1])) { + skb_frag_size_add(&frags[i - 1], copy); } else { if (i >= frag_max) { pr_warn("too many pages %u, dlen %u.\n", @@ -1825,7 +1825,7 @@ static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, frags[i].page = page; frags[i].page_offset = sg->offset + sgoffset; - frags[i].size = copy; + skb_frag_size_set(&frags[i], copy); i++; } datalen -= copy; @@ -1951,8 +1951,8 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset, char *src = kmap_atomic(frag->page, KM_SOFTIRQ0); - memcpy(dst, src+frag->page_offset, frag->size); - dst += frag->size; + memcpy(dst, src+frag->page_offset, skb_frag_size(frag)); + dst += skb_frag_size(frag); kunmap_atomic(src, KM_SOFTIRQ0); } if (padlen) { diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index f6613f9f1bdb..dac8e39a5188 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -105,7 +105,7 @@ u32 fcoe_fc_crc(struct fc_frame *fp) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { frag = &skb_shinfo(skb)->frags[i]; off = frag->page_offset; - len = frag->size; + len = skb_frag_size(frag); while (len > 0) { clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK)); data = kmap_atomic( diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 58792aefc8d3..4c7739f929ef 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -169,11 +169,11 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) /* Additional fragments are after SKB data */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *f = &skb_shinfo(skb)->frags[i]; packet->page_buf[i+2].pfn = page_to_pfn(skb_frag_page(f)); packet->page_buf[i+2].offset = f->page_offset; - packet->page_buf[i+2].len = f->size; + packet->page_buf[i+2].len = skb_frag_size(f); } /* Set the completion routine */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 64f86951ef74..6fcbbbd12ceb 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -150,6 +150,26 @@ struct skb_frag_struct { #endif }; +static inline unsigned int skb_frag_size(const skb_frag_t *frag) +{ + return frag->size; +} + +static inline void skb_frag_size_set(skb_frag_t *frag, unsigned int size) +{ + frag->size = size; +} + +static inline void skb_frag_size_add(skb_frag_t *frag, int delta) +{ + frag->size += delta; +} + +static inline void skb_frag_size_sub(skb_frag_t *frag, int delta) +{ + frag->size -= delta; +} + #define HAVE_HW_TIME_STAMP /** @@ -1132,7 +1152,7 @@ static inline int skb_pagelen(const struct sk_buff *skb) int i, len = 0; for (i = (int)skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) - len += skb_shinfo(skb)->frags[i].size; + len += skb_frag_size(&skb_shinfo(skb)->frags[i]); return len + skb_headlen(skb); } @@ -1156,7 +1176,7 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i, frag->page = page; frag->page_offset = off; - frag->size = size; + skb_frag_size_set(frag, size); } /** @@ -1907,10 +1927,10 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i, const struct page *page, int off) { if (i) { - struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; + const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; return page == skb_frag_page(frag) && - off == frag->page_offset + frag->size; + off == frag->page_offset + skb_frag_size(frag); } return 0; } diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index b1fe7c35e8d1..bfa9ab93eda5 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -951,13 +951,12 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, /* checksum stuff in frags */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; if (copy > len) copy = len; diff --git a/net/core/datagram.c b/net/core/datagram.c index 6449bed457d4..68bbf9f65cb0 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -324,14 +324,14 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, /* Copy paged appendix. Hmm... why does this look so complicated? */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { int err; u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct page *page = skb_frag_page(frag); if (copy > len) @@ -410,14 +410,14 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, /* Copy paged appendix. Hmm... why does this look so complicated? */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { int err; u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct page *page = skb_frag_page(frag); if (copy > len) @@ -500,14 +500,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, /* Copy paged appendix. Hmm... why does this look so complicated? */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { int err; u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct page *page = skb_frag_page(frag); if (copy > len) @@ -585,15 +585,15 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { __wsum csum2; int err = 0; u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct page *page = skb_frag_page(frag); if (copy > len) diff --git a/net/core/dev.c b/net/core/dev.c index 8b6118a16b87..cbb5918e4fc5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3489,9 +3489,9 @@ pull: skb->data_len -= grow; skb_shinfo(skb)->frags[0].page_offset += grow; - skb_shinfo(skb)->frags[0].size -= grow; + skb_frag_size_sub(&skb_shinfo(skb)->frags[0], grow); - if (unlikely(!skb_shinfo(skb)->frags[0].size)) { + if (unlikely(!skb_frag_size(&skb_shinfo(skb)->frags[0]))) { skb_frag_unref(skb, 0); memmove(skb_shinfo(skb)->frags, skb_shinfo(skb)->frags + 1, @@ -3559,7 +3559,7 @@ void skb_gro_reset_offset(struct sk_buff *skb) !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) { NAPI_GRO_CB(skb)->frag0 = skb_frag_address(&skb_shinfo(skb)->frags[0]); - NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size; + NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(&skb_shinfo(skb)->frags[0]); } } EXPORT_SYMBOL(skb_gro_reset_offset); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 796044ac0bf3..38d657737498 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2606,13 +2606,13 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb, skb_shinfo(skb)->frags[i].page_offset = 0; /*last fragment, fill rest of data*/ if (i == (frags - 1)) - skb_shinfo(skb)->frags[i].size = - (datalen < PAGE_SIZE ? datalen : PAGE_SIZE); + skb_frag_size_set(&skb_shinfo(skb)->frags[i], + (datalen < PAGE_SIZE ? datalen : PAGE_SIZE)); else - skb_shinfo(skb)->frags[i].size = frag_len; - datalen -= skb_shinfo(skb)->frags[i].size; - skb->len += skb_shinfo(skb)->frags[i].size; - skb->data_len += skb_shinfo(skb)->frags[i].size; + skb_frag_size_set(&skb_shinfo(skb)->frags[i], frag_len); + datalen -= skb_frag_size(&skb_shinfo(skb)->frags[i]); + skb->len += skb_frag_size(&skb_shinfo(skb)->frags[i]); + skb->data_len += skb_frag_size(&skb_shinfo(skb)->frags[i]); i++; skb_shinfo(skb)->nr_frags = i; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index a7f855dca922..ce357d986251 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -659,7 +659,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) } vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); memcpy(page_address(page), - vaddr + f->page_offset, f->size); + vaddr + f->page_offset, skb_frag_size(f)); kunmap_skb_frag(vaddr); page->private = (unsigned long)head; head = page; @@ -1190,14 +1190,14 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) goto drop_pages; for (; i < nfrags; i++) { - int end = offset + skb_shinfo(skb)->frags[i].size; + int end = offset + skb_frag_size(&skb_shinfo(skb)->frags[i]); if (end < len) { offset = end; continue; } - skb_shinfo(skb)->frags[i++].size = len - offset; + skb_frag_size_set(&skb_shinfo(skb)->frags[i++], len - offset); drop_pages: skb_shinfo(skb)->nr_frags = i; @@ -1306,9 +1306,11 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) /* Estimate size of pulled pages. */ eat = delta; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size >= eat) + int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + + if (size >= eat) goto pull_pages; - eat -= skb_shinfo(skb)->frags[i].size; + eat -= size; } /* If we need update frag list, we are in troubles. @@ -1371,14 +1373,16 @@ pull_pages: eat = delta; k = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { + int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + + if (size <= eat) { skb_frag_unref(skb, i); - eat -= skb_shinfo(skb)->frags[i].size; + eat -= size; } else { skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; if (eat) { skb_shinfo(skb)->frags[k].page_offset += eat; - skb_shinfo(skb)->frags[k].size -= eat; + skb_frag_size_sub(&skb_shinfo(skb)->frags[k], eat); eat = 0; } k++; @@ -1433,7 +1437,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy = end - offset) > 0) { u8 *vaddr; @@ -1632,7 +1636,7 @@ static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; if (__splice_segment(skb_frag_page(f), - f->page_offset, f->size, + f->page_offset, skb_frag_size(f), offset, len, skb, spd, 0, sk, pipe)) return 1; } @@ -1742,7 +1746,7 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) WARN_ON(start > offset + len); - end = start + frag->size; + end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { u8 *vaddr; @@ -1815,7 +1819,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy = end - offset) > 0) { __wsum csum2; u8 *vaddr; @@ -1890,7 +1894,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy = end - offset) > 0) { __wsum csum2; u8 *vaddr; @@ -2163,7 +2167,7 @@ static inline void skb_split_no_header(struct sk_buff *skb, skb->data_len = len - pos; for (i = 0; i < nfrags; i++) { - int size = skb_shinfo(skb)->frags[i].size; + int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); if (pos + size > len) { skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i]; @@ -2179,8 +2183,8 @@ static inline void skb_split_no_header(struct sk_buff *skb, */ skb_frag_ref(skb, i); skb_shinfo(skb1)->frags[0].page_offset += len - pos; - skb_shinfo(skb1)->frags[0].size -= len - pos; - skb_shinfo(skb)->frags[i].size = len - pos; + skb_frag_size_sub(&skb_shinfo(skb1)->frags[0], len - pos); + skb_frag_size_set(&skb_shinfo(skb)->frags[i], len - pos); skb_shinfo(skb)->nr_frags++; } k++; @@ -2258,7 +2262,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) } else { merge = to - 1; - todo -= fragfrom->size; + todo -= skb_frag_size(fragfrom); if (todo < 0) { if (skb_prepare_for_shift(skb) || skb_prepare_for_shift(tgt)) @@ -2268,8 +2272,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) fragfrom = &skb_shinfo(skb)->frags[from]; fragto = &skb_shinfo(tgt)->frags[merge]; - fragto->size += shiftlen; - fragfrom->size -= shiftlen; + skb_frag_size_add(fragto, shiftlen); + skb_frag_size_sub(fragfrom, shiftlen); fragfrom->page_offset += shiftlen; goto onlymerged; @@ -2293,9 +2297,9 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) fragfrom = &skb_shinfo(skb)->frags[from]; fragto = &skb_shinfo(tgt)->frags[to]; - if (todo >= fragfrom->size) { + if (todo >= skb_frag_size(fragfrom)) { *fragto = *fragfrom; - todo -= fragfrom->size; + todo -= skb_frag_size(fragfrom); from++; to++; @@ -2303,10 +2307,10 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) __skb_frag_ref(fragfrom); fragto->page = fragfrom->page; fragto->page_offset = fragfrom->page_offset; - fragto->size = todo; + skb_frag_size_set(fragto, todo); fragfrom->page_offset += todo; - fragfrom->size -= todo; + skb_frag_size_sub(fragfrom, todo); todo = 0; to++; @@ -2321,7 +2325,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) fragfrom = &skb_shinfo(skb)->frags[0]; fragto = &skb_shinfo(tgt)->frags[merge]; - fragto->size += fragfrom->size; + skb_frag_size_add(fragto, skb_frag_size(fragfrom)); __skb_frag_unref(fragfrom); } @@ -2419,7 +2423,7 @@ next_skb: while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) { frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx]; - block_limit = frag->size + st->stepped_offset; + block_limit = skb_frag_size(frag) + st->stepped_offset; if (abs_offset < block_limit) { if (!st->frag_data) @@ -2437,7 +2441,7 @@ next_skb: } st->frag_idx++; - st->stepped_offset += frag->size; + st->stepped_offset += skb_frag_size(frag); } if (st->frag_data) { @@ -2567,13 +2571,13 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, left = PAGE_SIZE - frag->page_offset; copy = (length > left)? left : length; - ret = getfrag(from, skb_frag_address(frag) + frag->size, + ret = getfrag(from, skb_frag_address(frag) + skb_frag_size(frag), offset, copy, 0, skb); if (ret < 0) return -EFAULT; /* copy was successful so update the size parameters */ - frag->size += copy; + skb_frag_size_add(frag, copy); skb->len += copy; skb->data_len += copy; offset += copy; @@ -2720,11 +2724,11 @@ struct sk_buff *skb_segment(struct sk_buff *skb, u32 features) while (pos < offset + len && i < nfrags) { *frag = skb_shinfo(skb)->frags[i]; __skb_frag_ref(frag); - size = frag->size; + size = skb_frag_size(frag); if (pos < offset) { frag->page_offset += offset - pos; - frag->size -= offset - pos; + skb_frag_size_sub(frag, offset - pos); } skb_shinfo(nskb)->nr_frags++; @@ -2733,7 +2737,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, u32 features) i++; pos += size; } else { - frag->size -= pos + size - (offset + len); + skb_frag_size_sub(frag, pos + size - (offset + len)); goto skip_fraglist; } @@ -2813,7 +2817,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) } while (--i); frag->page_offset += offset; - frag->size -= offset; + skb_frag_size_sub(frag, offset); skb->truesize -= skb->data_len; skb->len -= skb->data_len; @@ -2865,7 +2869,7 @@ merge: unsigned int eat = offset - headlen; skbinfo->frags[0].page_offset += eat; - skbinfo->frags[0].size -= eat; + skb_frag_size_sub(&skbinfo->frags[0], eat); skb->data_len -= eat; skb->len -= eat; offset = headlen; @@ -2936,7 +2940,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy = end - offset) > 0) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; diff --git a/net/core/user_dma.c b/net/core/user_dma.c index 34e9664cae3b..2d7cf3d52b4c 100644 --- a/net/core/user_dma.c +++ b/net/core/user_dma.c @@ -71,13 +71,13 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, /* Copy paged appendix. Hmm... why does this look so complicated? */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; WARN_ON(start > offset + len); - end = start + skb_shinfo(skb)->frags[i].size; + end = start + skb_frag_size(frag); copy = end - offset; if (copy > 0) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; struct page *page = skb_frag_page(frag); if (copy > len) diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 8e6be5aad115..cc280a3f4f96 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c @@ -244,11 +244,11 @@ static void lro_add_frags(struct net_lro_desc *lro_desc, skb->truesize += truesize; skb_frags[0].page_offset += hlen; - skb_frags[0].size -= hlen; + skb_frag_size_sub(&skb_frags[0], hlen); while (tcp_data_len > 0) { *(lro_desc->next_frag) = *skb_frags; - tcp_data_len -= skb_frags->size; + tcp_data_len -= skb_frag_size(skb_frags); lro_desc->next_frag++; skb_frags++; skb_shinfo(skb)->nr_frags++; @@ -400,14 +400,14 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr, skb_frags = skb_shinfo(skb)->frags; while (data_len > 0) { *skb_frags = *frags; - data_len -= frags->size; + data_len -= skb_frag_size(frags); skb_frags++; frags++; skb_shinfo(skb)->nr_frags++; } skb_shinfo(skb)->frags[0].page_offset += hdr_len; - skb_shinfo(skb)->frags[0].size -= hdr_len; + skb_frag_size_sub(&skb_shinfo(skb)->frags[0], hdr_len); skb->ip_summed = ip_summed; skb->csum = sum; diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 763589ad673d..fdaabf2f2b68 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -599,8 +599,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; skb_frag_list_init(head); - for (i=0; i<skb_shinfo(head)->nr_frags; i++) - plen += skb_shinfo(head)->frags[i].size; + for (i = 0; i < skb_shinfo(head)->nr_frags; i++) + plen += skb_frag_size(&skb_shinfo(head)->frags[i]); clone->len = clone->data_len = head->data_len - plen; head->data_len -= clone->len; head->len -= clone->len; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ae3bb147affd..e1374ab034bb 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1015,13 +1015,13 @@ alloc_new_skb: err = -EMSGSIZE; goto error; } - if (getfrag(from, skb_frag_address(frag)+frag->size, + if (getfrag(from, skb_frag_address(frag)+skb_frag_size(frag), offset, copy, skb->len, skb) < 0) { err = -EFAULT; goto error; } cork->off += copy; - frag->size += copy; + skb_frag_size_add(frag, copy); skb->len += copy; skb->data_len += copy; skb->truesize += copy; @@ -1230,7 +1230,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, if (len > size) len = size; if (skb_can_coalesce(skb, i, page, offset)) { - skb_shinfo(skb)->frags[i-1].size += len; + skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], len); } else if (i < MAX_SKB_FRAGS) { get_page(page); skb_fill_page_desc(skb, i, page, offset, len); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4c0da24fb649..132be081cd00 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -813,7 +813,7 @@ new_segment: goto wait_for_memory; if (can_coalesce) { - skb_shinfo(skb)->frags[i - 1].size += copy; + skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); } else { get_page(page); skb_fill_page_desc(skb, i, page, offset, copy); @@ -1058,8 +1058,7 @@ new_segment: /* Update the skb. */ if (merge) { - skb_shinfo(skb)->frags[i - 1].size += - copy; + skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); } else { skb_fill_page_desc(skb, i, page, off, copy); if (TCP_PAGE(sk)) { @@ -3031,8 +3030,8 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, for (i = 0; i < shi->nr_frags; ++i) { const struct skb_frag_struct *f = &shi->frags[i]; struct page *page = skb_frag_page(f); - sg_set_page(&sg, page, f->size, f->page_offset); - if (crypto_hash_update(desc, &sg, f->size)) + sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); + if (crypto_hash_update(desc, &sg, skb_frag_size(f))) return 1; } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index dde6b5768316..ed96c543f1cf 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1094,14 +1094,16 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) eat = len; k = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { + int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); + + if (size <= eat) { skb_frag_unref(skb, i); - eat -= skb_shinfo(skb)->frags[i].size; + eat -= size; } else { skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; if (eat) { skb_shinfo(skb)->frags[k].page_offset += eat; - skb_shinfo(skb)->frags[k].size -= eat; + skb_frag_size_sub(&skb_shinfo(skb)->frags[k], eat); eat = 0; } k++; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 1e20b64e646c..1c9bf8b5c30a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1512,13 +1512,14 @@ alloc_new_skb: err = -EMSGSIZE; goto error; } - if (getfrag(from, skb_frag_address(frag)+frag->size, + if (getfrag(from, + skb_frag_address(frag) + skb_frag_size(frag), offset, copy, skb->len, skb) < 0) { err = -EFAULT; goto error; } sk->sk_sndmsg_off += copy; - frag->size += copy; + skb_frag_size_add(frag, copy); skb->len += copy; skb->data_len += copy; skb->truesize += copy; diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 085727263812..e8762c73b170 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -378,8 +378,8 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; skb_frag_list_init(head); - for (i=0; i<skb_shinfo(head)->nr_frags; i++) - plen += skb_shinfo(head)->frags[i].size; + for (i = 0; i < skb_shinfo(head)->nr_frags; i++) + plen += skb_frag_size(&skb_shinfo(head)->frags[i]); clone->len = clone->data_len = head->data_len - plen; head->data_len -= clone->len; head->len -= clone->len; diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 7b954e2539d0..cc22099ac8b6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -464,8 +464,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; skb_frag_list_init(head); - for (i=0; i<skb_shinfo(head)->nr_frags; i++) - plen += skb_shinfo(head)->frags[i].size; + for (i = 0; i < skb_shinfo(head)->nr_frags; i++) + plen += skb_frag_size(&skb_shinfo(head)->frags[i]); clone->len = clone->data_len = head->data_len - plen; head->data_len -= clone->len; head->len -= clone->len; diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index f781b9ab8a54..e5246fbe36c4 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c @@ -90,7 +90,7 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) len = dlen; frag->page_offset = 0; - frag->size = len; + skb_frag_size_set(frag, len); memcpy(skb_frag_address(frag), scratch, len); skb->truesize += len; -- cgit v1.2.3