/* Agere Systems Inc. * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs * * Copyright © 2005 Agere Systems Inc. * All rights reserved. * http://www.agere.com * * Copyright (c) 2011 Mark Einon <[email protected]> * *------------------------------------------------------------------------------ * * SOFTWARE LICENSE * * This software is provided subject to the following terms and conditions, * which you should read carefully before using the software. Using this * software indicates your acceptance of these terms and conditions. If you do * not agree with these terms and conditions, do not use the software. * * Copyright © 2005 Agere Systems Inc. * All rights reserved. * * Redistribution and use in source or binary forms, with or without * modifications, are permitted provided that the following conditions are met: * * . Redistributions of source code must retain the above copyright notice, this * list of conditions and the following Disclaimer as comments in the code as * well as in the documentation and/or other materials provided with the * distribution. * * . Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following Disclaimer in the documentation * and/or other materials provided with the distribution. * * . Neither the name of Agere Systems Inc. nor the names of the contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * Disclaimer * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ #define pr_fmt(fmt) … #include <linux/pci.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/slab.h> #include <linux/ctype.h> #include <linux/string.h> #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/in.h> #include <linux/delay.h> #include <linux/bitops.h> #include <linux/io.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/if_arp.h> #include <linux/ioport.h> #include <linux/crc32.h> #include <linux/random.h> #include <linux/phy.h> #include "et131x.h" MODULE_AUTHOR(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …; /* EEPROM defines */ #define MAX_NUM_REGISTER_POLLS … #define MAX_NUM_WRITE_RETRIES … /* MAC defines */ #define COUNTER_WRAP_16_BIT … #define COUNTER_WRAP_12_BIT … /* PCI defines */ #define INTERNAL_MEM_SIZE … #define INTERNAL_MEM_RX_OFFSET … /* ISR defines */ /* For interrupts, normal running is: * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, * watchdog_interrupt & txdma_xfer_done * * In both cases, when flow control is enabled for either Tx or bi-direction, * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the * buffer rings are running low. */ #define INT_MASK_DISABLE … /* NOTE: Masking out MAC_STAT Interrupt for now... * #define INT_MASK_ENABLE 0xfff6bf17 * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 */ #define INT_MASK_ENABLE … #define INT_MASK_ENABLE_NO_FLOW … /* General defines */ /* Packet and header sizes */ #define NIC_MIN_PACKET_SIZE … /* Multicast list size */ #define NIC_MAX_MCAST_LIST … /* Supported Filters */ #define ET131X_PACKET_TYPE_DIRECTED … #define ET131X_PACKET_TYPE_MULTICAST … #define ET131X_PACKET_TYPE_BROADCAST … #define ET131X_PACKET_TYPE_PROMISCUOUS … #define ET131X_PACKET_TYPE_ALL_MULTICAST … /* Tx Timeout */ #define ET131X_TX_TIMEOUT … #define NIC_SEND_HANG_THRESHOLD … /* MP_ADAPTER flags */ #define FMP_ADAPTER_INTERRUPT_IN_USE … /* MP_SHARED flags */ #define FMP_ADAPTER_LOWER_POWER … #define FMP_ADAPTER_NON_RECOVER_ERROR … #define FMP_ADAPTER_HARDWARE_ERROR … #define FMP_ADAPTER_FAIL_SEND_MASK … /* Some offsets in PCI config space that are actually used. */ #define ET1310_PCI_MAC_ADDRESS … #define ET1310_PCI_EEPROM_STATUS … #define ET1310_PCI_ACK_NACK … #define ET1310_PCI_REPLAY … #define ET1310_PCI_L0L1LATENCY … /* PCI Product IDs */ #define ET131X_PCI_DEVICE_ID_GIG … #define ET131X_PCI_DEVICE_ID_FAST … /* Define order of magnitude converter */ #define NANO_IN_A_MICRO … #define PARM_RX_NUM_BUFS_DEF … #define PARM_RX_TIME_INT_DEF … #define PARM_RX_MEM_END_DEF … #define PARM_TX_TIME_INT_DEF … #define PARM_TX_NUM_BUFS_DEF … #define PARM_DMA_CACHE_DEF … /* RX defines */ #define FBR_CHUNKS … #define MAX_DESC_PER_RING_RX … /* number of RFDs - default and min */ #define RFD_LOW_WATER_MARK … #define NIC_DEFAULT_NUM_RFD … #define NUM_FBRS … #define MAX_PACKETS_HANDLED … #define ET131X_MIN_MTU … #define ET131X_MAX_MTU … #define ALCATEL_MULTICAST_PKT … #define ALCATEL_BROADCAST_PKT … /* typedefs for Free Buffer Descriptors */ struct fbr_desc { … }; /* Packet Status Ring Descriptors * * Word 0: * * top 16 bits are from the Alcatel Status Word as enumerated in * PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) * * 0: hp hash pass * 1: ipa IP checksum assist * 2: ipp IP checksum pass * 3: tcpa TCP checksum assist * 4: tcpp TCP checksum pass * 5: wol WOL Event * 6: rxmac_error RXMAC Error Indicator * 7: drop Drop packet * 8: ft Frame Truncated * 9: jp Jumbo Packet * 10: vp VLAN Packet * 11-15: unused * 16: asw_prev_pkt_dropped e.g. IFG too small on previous * 17: asw_RX_DV_event short receive event detected * 18: asw_false_carrier_event bad carrier since last good packet * 19: asw_code_err one or more nibbles signalled as errors * 20: asw_CRC_err CRC error * 21: asw_len_chk_err frame length field incorrect * 22: asw_too_long frame length > 1518 bytes * 23: asw_OK valid CRC + no code error * 24: asw_multicast has a multicast address * 25: asw_broadcast has a broadcast address * 26: asw_dribble_nibble spurious bits after EOP * 27: asw_control_frame is a control frame * 28: asw_pause_frame is a pause frame * 29: asw_unsupported_op unsupported OP code * 30: asw_VLAN_tag VLAN tag detected * 31: asw_long_evt Rx long event * * Word 1: * 0-15: length length in bytes * 16-25: bi Buffer Index * 26-27: ri Ring Index * 28-31: reserved */ struct pkt_stat_desc { … }; /* Typedefs for the RX DMA status word */ /* rx status word 0 holds part of the status bits of the Rx DMA engine * that get copied out to memory by the ET-1310. Word 0 is a 32 bit word * which contains the Free Buffer ring 0 and 1 available offset. * * bit 0-9 FBR1 offset * bit 10 Wrap flag for FBR1 * bit 16-25 FBR0 offset * bit 26 Wrap flag for FBR0 */ /* RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word * which contains the Packet Status Ring available offset. * * bit 0-15 reserved * bit 16-27 PSRoffset * bit 28 PSRwrap * bit 29-31 unused */ /* struct rx_status_block is a structure representing the status of the Rx * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020 */ struct rx_status_block { … }; /* Structure for look-up table holding free buffer ring pointers, addresses * and state. */ struct fbr_lookup { … }; /* struct rx_ring is the structure representing the adaptor's local * reference(s) to the rings */ struct rx_ring { … }; /* TX defines */ /* word 2 of the control bits in the Tx Descriptor ring for the ET-1310 * * 0-15: length of packet * 16-27: VLAN tag * 28: VLAN CFI * 29-31: VLAN priority * * word 3 of the control bits in the Tx Descriptor ring for the ET-1310 * * 0: last packet in the sequence * 1: first packet in the sequence * 2: interrupt the processor when this pkt sent * 3: Control word - no packet data * 4: Issue half-duplex backpressure : XON/XOFF * 5: send pause frame * 6: Tx frame has error * 7: append CRC * 8: MAC override * 9: pad packet * 10: Packet is a Huge packet * 11: append VLAN tag * 12: IP checksum assist * 13: TCP checksum assist * 14: UDP checksum assist */ #define TXDESC_FLAG_LASTPKT … #define TXDESC_FLAG_FIRSTPKT … #define TXDESC_FLAG_INTPROC … /* struct tx_desc represents each descriptor on the ring */ struct tx_desc { … }; /* The status of the Tx DMA engine it sits in free memory, and is pointed to * by 0x101c / 0x1020. This is a DMA10 type */ /* TCB (Transmit Control Block: Host Side) */ struct tcb { … }; /* Structure representing our local reference(s) to the ring */ struct tx_ring { … }; /* Do not change these values: if changed, then change also in respective * TXdma and Rxdma engines */ #define NUM_DESC_PER_RING_TX … #define NUM_TCB … /* These values are all superseded by registry entries to facilitate tuning. * Once the desired performance has been achieved, the optimal registry values * should be re-populated to these #defines: */ #define TX_ERROR_PERIOD … #define LO_MARK_PERCENT_FOR_PSR … #define LO_MARK_PERCENT_FOR_RX … /* RFD (Receive Frame Descriptor) */ struct rfd { … }; /* Flow Control */ #define FLOW_BOTH … #define FLOW_TXONLY … #define FLOW_RXONLY … #define FLOW_NONE … /* Struct to define some device statistics */ struct ce_stats { … }; /* The private adapter structure */ struct et131x_adapter { … }; static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status) { … } static int eeprom_write(struct et131x_adapter *adapter, u32 addr, u8 data) { … } static int eeprom_read(struct et131x_adapter *adapter, u32 addr, u8 *pdata) { … } static int et131x_init_eeprom(struct et131x_adapter *adapter) { … } static void et131x_rx_dma_enable(struct et131x_adapter *adapter) { … } static void et131x_rx_dma_disable(struct et131x_adapter *adapter) { … } static void et131x_tx_dma_enable(struct et131x_adapter *adapter) { … } static inline void add_10bit(u32 *v, int n) { … } static inline void add_12bit(u32 *v, int n) { … } static void et1310_config_mac_regs1(struct et131x_adapter *adapter) { … } static void et1310_config_mac_regs2(struct et131x_adapter *adapter) { … } static int et1310_in_phy_coma(struct et131x_adapter *adapter) { … } static void et1310_setup_device_for_multicast(struct et131x_adapter *adapter) { … } static void et1310_setup_device_for_unicast(struct et131x_adapter *adapter) { … } static void et1310_config_rxmac_regs(struct et131x_adapter *adapter) { … } static void et1310_config_txmac_regs(struct et131x_adapter *adapter) { … } static void et1310_config_macstat_regs(struct et131x_adapter *adapter) { … } static int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 addr, u8 reg, u16 *value) { … } static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value) { … } static int et131x_mii_write(struct et131x_adapter *adapter, u8 addr, u8 reg, u16 value) { … } static void et1310_phy_read_mii_bit(struct et131x_adapter *adapter, u16 regnum, u16 bitnum, u8 *value) { … } static void et1310_config_flow_control(struct et131x_adapter *adapter) { … } /* et1310_update_macstat_host_counters - Update local copy of the statistics */ static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) { … } /* et1310_handle_macstat_interrupt * * One of the MACSTAT counters has wrapped. Update the local copy of * the statistics held in the adapter structure, checking the "wrap" * bit for each counter. */ static void et1310_handle_macstat_interrupt(struct et131x_adapter *adapter) { … } static int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg) { … } static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value) { … } /* et1310_phy_power_switch - PHY power control * @adapter: device to control * @down: true for off/false for back on * * one hundred, ten, one thousand megs * How would you like to have your LAN accessed * Can't you see that this code processed * Phy power, phy power.. */ static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) { … } /* et131x_xcvr_init - Init the phy if we are setting it into force mode */ static void et131x_xcvr_init(struct et131x_adapter *adapter) { … } /* et131x_configure_global_regs - configure JAGCore global regs */ static void et131x_configure_global_regs(struct et131x_adapter *adapter) { … } /* et131x_config_rx_dma_regs - Start of Rx_DMA init sequence */ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) { … } /* et131x_config_tx_dma_regs - Set up the tx dma section of the JAGCore. * * Configure the transmit engine with the ring buffers we have created * and prepare it for use. */ static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter) { … } /* et131x_adapter_setup - Set the adapter up as per cassini+ documentation */ static void et131x_adapter_setup(struct et131x_adapter *adapter) { … } /* et131x_soft_reset - Issue soft reset to the hardware, complete for ET1310 */ static void et131x_soft_reset(struct et131x_adapter *adapter) { … } static void et131x_enable_interrupts(struct et131x_adapter *adapter) { … } static void et131x_disable_interrupts(struct et131x_adapter *adapter) { … } static void et131x_tx_dma_disable(struct et131x_adapter *adapter) { … } static void et131x_enable_txrx(struct net_device *netdev) { … } static void et131x_disable_txrx(struct net_device *netdev) { … } static void et131x_init_send(struct et131x_adapter *adapter) { … } /* et1310_enable_phy_coma * * driver receive an phy status change interrupt while in D0 and check that * phy_status is down. * * -- gate off JAGCore; * -- set gigE PHY in Coma mode * -- wake on phy_interrupt; Perform software reset JAGCore, * re-initialize jagcore and gigE PHY */ static void et1310_enable_phy_coma(struct et131x_adapter *adapter) { … } static void et1310_disable_phy_coma(struct et131x_adapter *adapter) { … } static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) { … } /* et131x_rx_dma_memory_alloc * * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required, * and the Packet Status Ring. */ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) { … } static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { … } /* et131x_init_recv - Initialize receive data structures */ static int et131x_init_recv(struct et131x_adapter *adapter) { … } /* et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate */ static void et131x_set_rx_dma_timer(struct et131x_adapter *adapter) { … } /* nic_return_rfd - Recycle a RFD and put it back onto the receive list */ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) { … } /* nic_rx_pkts - Checks the hardware for available packets * * Checks the hardware for available packets, using completion ring * If packets are available, it gets an RFD from the recv_list, attaches * the packet to it, puts the RFD in the RecvPendList, and also returns * the pointer to the RFD. */ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) { … } static int et131x_handle_recv_pkts(struct et131x_adapter *adapter, int budget) { … } /* et131x_tx_dma_memory_alloc * * Allocates memory that will be visible both to the device and to the CPU. * The OS will pass us packets, pointers to which we will insert in the Tx * Descriptor queue. The device will read this queue to find the packets in * memory. The device will update the "status" in memory each time it xmits a * packet. */ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) { … } static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) { … } #define MAX_TX_DESC_PER_PKT … /* nic_send_packet - NIC specific send handler for version B silicon. */ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { … } static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) { … } /* free_send_packet - Recycle a struct tcb */ static inline void free_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { … } /* et131x_free_busy_send_packets - Free and complete the stopped active sends */ static void et131x_free_busy_send_packets(struct et131x_adapter *adapter) { … } /* et131x_handle_send_pkts * * Re-claim the send resources, complete sends and get more to send from * the send wait queue. */ static void et131x_handle_send_pkts(struct et131x_adapter *adapter) { … } static int et131x_get_regs_len(struct net_device *netdev) { … } static void et131x_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *regs_data) { … } static void et131x_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) { … } static const struct ethtool_ops et131x_ethtool_ops = …; /* et131x_hwaddr_init - set up the MAC Address */ static void et131x_hwaddr_init(struct et131x_adapter *adapter) { … } static int et131x_pci_init(struct et131x_adapter *adapter, struct pci_dev *pdev) { … } /* et131x_error_timer_handler * @data: timer-specific variable; here a pointer to our adapter structure * * The routine called when the error timer expires, to track the number of * recurring errors. */ static void et131x_error_timer_handler(struct timer_list *t) { … } static void et131x_adapter_memory_free(struct et131x_adapter *adapter) { … } static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) { … } static void et131x_adjust_link(struct net_device *netdev) { … } static int et131x_mii_probe(struct net_device *netdev) { … } static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, struct pci_dev *pdev) { … } static void et131x_pci_remove(struct pci_dev *pdev) { … } static void et131x_up(struct net_device *netdev) { … } static void et131x_down(struct net_device *netdev) { … } #ifdef CONFIG_PM_SLEEP static int et131x_suspend(struct device *dev) { … } static int et131x_resume(struct device *dev) { … } #endif static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); static irqreturn_t et131x_isr(int irq, void *dev_id) { … } static int et131x_poll(struct napi_struct *napi, int budget) { … } /* et131x_stats - Return the current device statistics */ static struct net_device_stats *et131x_stats(struct net_device *netdev) { … } static int et131x_open(struct net_device *netdev) { … } static int et131x_close(struct net_device *netdev) { … } /* et131x_set_packet_filter - Configures the Rx Packet filtering */ static int et131x_set_packet_filter(struct et131x_adapter *adapter) { … } static void et131x_multicast(struct net_device *netdev) { … } static netdev_tx_t et131x_tx(struct sk_buff *skb, struct net_device *netdev) { … } /* et131x_tx_timeout - Timeout handler * * The handler called when a Tx request times out. The timeout period is * specified by the 'tx_timeo" element in the net_device structure (see * et131x_alloc_device() to see how this value is set). */ static void et131x_tx_timeout(struct net_device *netdev, unsigned int txqueue) { … } static int et131x_change_mtu(struct net_device *netdev, int new_mtu) { … } static const struct net_device_ops et131x_netdev_ops = …; static int et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { … } static const struct pci_device_id et131x_pci_table[] = …; MODULE_DEVICE_TABLE(pci, et131x_pci_table); static struct pci_driver et131x_driver = …; module_pci_driver(…) …;