/******************************************************************************* * * Linux ThunderLAN Driver * * tlan.c * by James Banks * * (C) 1997-1998 Caldera, Inc. * (C) 1998 James Banks * (C) 1999-2001 Torben Mathiasen * (C) 2002 Samuel Chessman * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * ** Useful (if not required) reading: * * Texas Instruments, ThunderLAN Programmer's Guide, * TI Literature Number SPWU013A * available in PDF format from www.ti.com * Level One, LXT901 and LXT970 Data Sheets * available in PDF format from www.level1.com * National Semiconductor, DP83840A Data Sheet * available in PDF format from www.national.com * Microchip Technology, 24C01A/02A/04A Data Sheet * available in PDF format from www.microchip.com * ******************************************************************************/ #define pr_fmt(fmt) … #include <linux/hardirq.h> #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/eisa.h> #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/delay.h> #include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/mii.h> #include "tlan.h" /* For removing EISA devices */ static struct net_device *tlan_eisa_devices; static int tlan_devices_installed; /* Set speed, duplex and aui settings */ static int aui[MAX_TLAN_BOARDS]; static int duplex[MAX_TLAN_BOARDS]; static int speed[MAX_TLAN_BOARDS]; static int boards_found; module_param_array(…); module_param_array(…); module_param_array(…); MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …; MODULE_PARM_DESC(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; /* Turn on debugging. * See Documentation/networking/device_drivers/ethernet/ti/tlan.rst for details */ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(…) …; static const char tlan_signature[] = …; static const char tlan_banner[] = …; static int tlan_have_pci; static int tlan_have_eisa; static const char * const media[] = …; static struct board { … } board_info[] = …; static const struct pci_device_id tlan_pci_tbl[] = …; MODULE_DEVICE_TABLE(pci, tlan_pci_tbl); static void tlan_eisa_probe(void); static void tlan_eisa_cleanup(void); static int tlan_init(struct net_device *); static int tlan_open(struct net_device *dev); static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *); static irqreturn_t tlan_handle_interrupt(int, void *); static int tlan_close(struct net_device *); static struct net_device_stats *tlan_get_stats(struct net_device *); static void tlan_set_multicast_list(struct net_device *); static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent); static void tlan_tx_timeout(struct net_device *dev, unsigned int txqueue); static void tlan_tx_timeout_work(struct work_struct *work); static int tlan_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static u32 tlan_handle_tx_eof(struct net_device *, u16); static u32 tlan_handle_stat_overflow(struct net_device *, u16); static u32 tlan_handle_rx_eof(struct net_device *, u16); static u32 tlan_handle_dummy(struct net_device *, u16); static u32 tlan_handle_tx_eoc(struct net_device *, u16); static u32 tlan_handle_status_check(struct net_device *, u16); static u32 tlan_handle_rx_eoc(struct net_device *, u16); static void tlan_timer(struct timer_list *t); static void tlan_phy_monitor(struct timer_list *t); static void tlan_reset_lists(struct net_device *); static void tlan_free_lists(struct net_device *); static void tlan_print_dio(u16); static void tlan_print_list(struct tlan_list *, char *, int); static void tlan_read_and_clear_stats(struct net_device *, int); static void tlan_reset_adapter(struct net_device *); static void tlan_finish_reset(struct net_device *); static void tlan_set_mac(struct net_device *, int areg, const char *mac); static void __tlan_phy_print(struct net_device *); static void tlan_phy_print(struct net_device *); static void tlan_phy_detect(struct net_device *); static void tlan_phy_power_down(struct net_device *); static void tlan_phy_power_up(struct net_device *); static void tlan_phy_reset(struct net_device *); static void tlan_phy_start_link(struct net_device *); static void tlan_phy_finish_auto_neg(struct net_device *); /* static int tlan_phy_nop(struct net_device *); static int tlan_phy_internal_check(struct net_device *); static int tlan_phy_internal_service(struct net_device *); static int tlan_phy_dp83840a_check(struct net_device *); */ static bool __tlan_mii_read_reg(struct net_device *, u16, u16, u16 *); static void tlan_mii_read_reg(struct net_device *, u16, u16, u16 *); static void tlan_mii_send_data(u16, u32, unsigned); static void tlan_mii_sync(u16); static void __tlan_mii_write_reg(struct net_device *, u16, u16, u16); static void tlan_mii_write_reg(struct net_device *, u16, u16, u16); static void tlan_ee_send_start(u16); static int tlan_ee_send_byte(u16, u8, int); static void tlan_ee_receive_byte(u16, u8 *, int); static int tlan_ee_read_byte(struct net_device *, u8, u8 *); static inline void tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb) { … } static inline struct sk_buff * tlan_get_skb(const struct tlan_list *tag) { … } static u32 (*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = …; static void tlan_set_timer(struct net_device *dev, u32 ticks, u32 type) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver primary functions these functions are more or less common to all linux network drivers. ****************************************************************************** *****************************************************************************/ /*************************************************************** * tlan_remove_one * * Returns: * Nothing * Parms: * None * * Goes through the TLanDevices list and frees the device * structs and memory associated with each device (lists * and buffers). It also ureserves the IO port regions * associated with this device. * **************************************************************/ static void tlan_remove_one(struct pci_dev *pdev) { … } static void tlan_start(struct net_device *dev) { … } static void tlan_stop(struct net_device *dev) { … } static int __maybe_unused tlan_suspend(struct device *dev_d) { … } static int __maybe_unused tlan_resume(struct device *dev_d) { … } static SIMPLE_DEV_PM_OPS(tlan_pm_ops, tlan_suspend, tlan_resume); static struct pci_driver tlan_driver = …; static int __init tlan_probe(void) { … } static int tlan_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { … } /* *************************************************************** * tlan_probe1 * * Returns: * 0 on success, error code on error * Parms: * none * * The name is lower case to fit in with all the rest of * the netcard_probe names. This function looks for * another TLan based adapter, setting it up with the * allocated device struct if one is found. * tlan_probe has been ported to the new net API and * now allocates its own device structure. This function * is also used by modules. * **************************************************************/ static int tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent) { … } static void tlan_eisa_cleanup(void) { … } static void __exit tlan_exit(void) { … } /* Module loading/unloading */ module_init(…) …; module_exit(tlan_exit); /************************************************************** * tlan_eisa_probe * * Returns: 0 on success, 1 otherwise * * Parms: None * * * This functions probes for EISA devices and calls * TLan_probe1 when one is found. * *************************************************************/ static void __init tlan_eisa_probe(void) { … } #ifdef CONFIG_NET_POLL_CONTROLLER static void tlan_poll(struct net_device *dev) { … } #endif static const struct net_device_ops tlan_netdev_ops = …; static void tlan_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { … } static int tlan_get_eeprom_len(struct net_device *dev) { … } static int tlan_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { … } static const struct ethtool_ops tlan_ethtool_ops = …; /*************************************************************** * tlan_init * * Returns: * 0 on success, error code otherwise. * Parms: * dev The structure of the device to be * init'ed. * * This function completes the initialization of the * device structure and driver. It reserves the IO * addresses, allocates memory for the lists and bounce * buffers, retrieves the MAC address from the eeprom * and assignes the device's methods. * **************************************************************/ static int tlan_init(struct net_device *dev) { … } /*************************************************************** * tlan_open * * Returns: * 0 on success, error code otherwise. * Parms: * dev Structure of device to be opened. * * This routine puts the driver and TLAN adapter in a * state where it is ready to send and receive packets. * It allocates the IRQ, resets and brings the adapter * out of reset, and allows interrupts. It also delays * the startup for autonegotiation or sends a Rx GO * command to the adapter, as appropriate. * **************************************************************/ static int tlan_open(struct net_device *dev) { … } /************************************************************** * tlan_ioctl * * Returns: * 0 on success, error code otherwise * Params: * dev structure of device to receive ioctl. * * rq ifreq structure to hold userspace data. * * cmd ioctl command. * * *************************************************************/ static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { … } /*************************************************************** * tlan_tx_timeout * * Returns: nothing * * Params: * dev structure of device which timed out * during transmit. * **************************************************************/ static void tlan_tx_timeout(struct net_device *dev, unsigned int txqueue) { … } /*************************************************************** * tlan_tx_timeout_work * * Returns: nothing * * Params: * work work item of device which timed out * **************************************************************/ static void tlan_tx_timeout_work(struct work_struct *work) { … } /*************************************************************** * tlan_start_tx * * Returns: * 0 on success, non-zero on failure. * Parms: * skb A pointer to the sk_buff containing the * frame to be sent. * dev The device to send the data on. * * This function adds a frame to the Tx list to be sent * ASAP. First it verifies that the adapter is ready and * there is room in the queue. Then it sets up the next * available list, copies the frame to the corresponding * buffer. If the adapter Tx channel is idle, it gives * the adapter a Tx Go command on the list, otherwise it * sets the forward address of the previous list to point * to this one. Then it frees the sk_buff. * **************************************************************/ static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev) { … } /*************************************************************** * tlan_handle_interrupt * * Returns: * Nothing * Parms: * irq The line on which the interrupt * occurred. * dev_id A pointer to the device assigned to * this irq line. * * This function handles an interrupt generated by its * assigned TLAN adapter. The function deactivates * interrupts on its adapter, records the type of * interrupt, executes the appropriate subhandler, and * acknowdges the interrupt to the adapter (thus * re-enabling adapter interrupts. * **************************************************************/ static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id) { … } /*************************************************************** * tlan_close * * Returns: * An error code. * Parms: * dev The device structure of the device to * close. * * This function shuts down the adapter. It records any * stats, puts the adapter into reset state, deactivates * its time as needed, and frees the irq it is using. * **************************************************************/ static int tlan_close(struct net_device *dev) { … } /*************************************************************** * tlan_get_stats * * Returns: * A pointer to the device's statistics structure. * Parms: * dev The device structure to return the * stats for. * * This function updates the devices statistics by reading * the TLAN chip's onboard registers. Then it returns the * address of the statistics structure. * **************************************************************/ static struct net_device_stats *tlan_get_stats(struct net_device *dev) { … } /*************************************************************** * tlan_set_multicast_list * * Returns: * Nothing * Parms: * dev The device structure to set the * multicast list for. * * This function sets the TLAN adaptor to various receive * modes. If the IFF_PROMISC flag is set, promiscuous * mode is acitviated. Otherwise, promiscuous mode is * turned off. If the IFF_ALLMULTI flag is set, then * the hash table is set to receive all group addresses. * Otherwise, the first three multicast addresses are * stored in AREG_1-3, and the rest are selected via the * hash table, as necessary. * **************************************************************/ static void tlan_set_multicast_list(struct net_device *dev) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver interrupt vectors and table please see chap. 4, "Interrupt Handling" of the "ThunderLAN Programmer's Guide" for more informations on handling interrupts generated by TLAN based adapters. ****************************************************************************** *****************************************************************************/ /*************************************************************** * tlan_handle_tx_eof * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This function handles Tx EOF interrupts which are raised * by the adapter when it has completed sending the * contents of a buffer. If detemines which list/buffer * was completed and resets it. If the buffer was the last * in the channel (EOC), then the function checks to see if * another buffer is ready to send, and if so, sends a Tx * Go command. Finally, the driver activates/continues the * activity LED. * **************************************************************/ static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int) { … } /*************************************************************** * TLan_HandleStatOverflow * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This function handles the Statistics Overflow interrupt * which means that one or more of the TLAN statistics * registers has reached 1/2 capacity and needs to be read. * **************************************************************/ static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int) { … } /*************************************************************** * TLan_HandleRxEOF * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This function handles the Rx EOF interrupt which * indicates a frame has been received by the adapter from * the net and the frame has been transferred to memory. * The function determines the bounce buffer the frame has * been loaded into, creates a new sk_buff big enough to * hold the frame, and sends it to protocol stack. It * then resets the used buffer and appends it to the end * of the list. If the frame was the last in the Rx * channel (EOC), the function restarts the receive channel * by sending an Rx Go command to the adapter. Then it * activates/continues the activity LED. * **************************************************************/ static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int) { … } /*************************************************************** * tlan_handle_dummy * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This function handles the Dummy interrupt, which is * raised whenever a test interrupt is generated by setting * the Req_Int bit of HOST_CMD to 1. * **************************************************************/ static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int) { … } /*************************************************************** * tlan_handle_tx_eoc * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This driver is structured to determine EOC occurrences by * reading the CSTAT member of the list structure. Tx EOC * interrupts are disabled via the DIO INTDIS register. * However, TLAN chips before revision 3.0 didn't have this * functionality, so process EOC events if this is the * case. * **************************************************************/ static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int) { … } /*************************************************************** * tlan_handle_status_check * * Returns: * 0 if Adapter check, 1 if Network Status check. * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This function handles Adapter Check/Network Status * interrupts generated by the adapter. It checks the * vector in the HOST_INT register to determine if it is * an Adapter Check interrupt. If so, it resets the * adapter. Otherwise it clears the status registers * and services the PHY. * **************************************************************/ static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int) { … } /*************************************************************** * tlan_handle_rx_eoc * * Returns: * 1 * Parms: * dev Device assigned the IRQ that was * raised. * host_int The contents of the HOST_INT * port. * * This driver is structured to determine EOC occurrences by * reading the CSTAT member of the list structure. Rx EOC * interrupts are disabled via the DIO INTDIS register. * However, TLAN chips before revision 3.0 didn't have this * CSTAT member or a INTDIS register, so if this chip is * pre-3.0, process EOC interrupts normally. * **************************************************************/ static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver timer function ****************************************************************************** *****************************************************************************/ /*************************************************************** * tlan_timer * * Returns: * Nothing * Parms: * data A value given to add timer when * add_timer was called. * * This function handles timed functionality for the * TLAN driver. The two current timer uses are for * delaying for autonegotionation and driving the ACT LED. * - Autonegotiation requires being allowed about * 2 1/2 seconds before attempting to transmit a * packet. It would be a very bad thing to hang * the kernel this long, so the driver doesn't * allow transmission 'til after this time, for * certain PHYs. It would be much nicer if all * PHYs were interrupt-capable like the internal * PHY. * - The ACT LED, which shows adapter activity, is * driven by the driver, and so must be left on * for a short period to power up the LED so it * can be seen. This delay can be changed by * changing the TLAN_TIMER_ACT_DELAY in tlan.h, * if desired. 100 ms produces a slightly * sluggish response. * **************************************************************/ static void tlan_timer(struct timer_list *t) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver adapter related routines ****************************************************************************** *****************************************************************************/ /*************************************************************** * tlan_reset_lists * * Returns: * Nothing * Parms: * dev The device structure with the list * structures to be reset. * * This routine sets the variables associated with managing * the TLAN lists to their initial values. * **************************************************************/ static void tlan_reset_lists(struct net_device *dev) { … } static void tlan_free_lists(struct net_device *dev) { … } /*************************************************************** * tlan_print_dio * * Returns: * Nothing * Parms: * io_base Base IO port of the device of * which to print DIO registers. * * This function prints out all the internal (DIO) * registers of a TLAN chip. * **************************************************************/ static void tlan_print_dio(u16 io_base) { … } /*************************************************************** * TLan_PrintList * * Returns: * Nothing * Parms: * list A pointer to the struct tlan_list structure to * be printed. * type A string to designate type of list, * "Rx" or "Tx". * num The index of the list. * * This function prints out the contents of the list * pointed to by the list parameter. * **************************************************************/ static void tlan_print_list(struct tlan_list *list, char *type, int num) { … } /*************************************************************** * tlan_read_and_clear_stats * * Returns: * Nothing * Parms: * dev Pointer to device structure of adapter * to which to read stats. * record Flag indicating whether to add * * This functions reads all the internal status registers * of the TLAN chip, which clears them as a side effect. * It then either adds the values to the device's status * struct, or discards them, depending on whether record * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0). * **************************************************************/ static void tlan_read_and_clear_stats(struct net_device *dev, int record) { … } /*************************************************************** * TLan_Reset * * Returns: * 0 * Parms: * dev Pointer to device structure of adapter * to be reset. * * This function resets the adapter and it's physical * device. See Chap. 3, pp. 9-10 of the "ThunderLAN * Programmer's Guide" for details. The routine tries to * implement what is detailed there, though adjustments * have been made. * **************************************************************/ static void tlan_reset_adapter(struct net_device *dev) { … } static void tlan_finish_reset(struct net_device *dev) { … } /*************************************************************** * tlan_set_mac * * Returns: * Nothing * Parms: * dev Pointer to device structure of adapter * on which to change the AREG. * areg The AREG to set the address in (0 - 3). * mac A pointer to an array of chars. Each * element stores one byte of the address. * IE, it isn't in ascii. * * This function transfers a MAC address to one of the * TLAN AREGs (address registers). The TLAN chip locks * the register on writing to offset 0 and unlocks the * register after writing to offset 5. If NULL is passed * in mac, then the AREG is filled with 0's. * **************************************************************/ static void tlan_set_mac(struct net_device *dev, int areg, const char *mac) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver PHY layer routines ****************************************************************************** *****************************************************************************/ /********************************************************************* * __tlan_phy_print * * Returns: * Nothing * Parms: * dev A pointer to the device structure of the * TLAN device having the PHYs to be detailed. * * This function prints the registers a PHY (aka transceiver). * ********************************************************************/ static void __tlan_phy_print(struct net_device *dev) { … } static void tlan_phy_print(struct net_device *dev) { … } /********************************************************************* * tlan_phy_detect * * Returns: * Nothing * Parms: * dev A pointer to the device structure of the adapter * for which the PHY needs determined. * * So far I've found that adapters which have external PHYs * may also use the internal PHY for part of the functionality. * (eg, AUI/Thinnet). This function finds out if this TLAN * chip has an internal PHY, and then finds the first external * PHY (starting from address 0) if it exists). * ********************************************************************/ static void tlan_phy_detect(struct net_device *dev) { … } static void tlan_phy_power_down(struct net_device *dev) { … } static void tlan_phy_power_up(struct net_device *dev) { … } static void tlan_phy_reset(struct net_device *dev) { … } static void tlan_phy_start_link(struct net_device *dev) { … } static void tlan_phy_finish_auto_neg(struct net_device *dev) { … } /********************************************************************* * * tlan_phy_monitor * * Returns: * None * * Params: * data The device structure of this device. * * * This function monitors PHY condition by reading the status * register via the MII bus, controls LINK LED and notifies the * kernel about link state. * *******************************************************************/ static void tlan_phy_monitor(struct timer_list *t) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver MII routines these routines are based on the information in chap. 2 of the "ThunderLAN Programmer's Guide", pp. 15-24. ****************************************************************************** *****************************************************************************/ /*************************************************************** * __tlan_mii_read_reg * * Returns: * false if ack received ok * true if no ack received or other error * * Parms: * dev The device structure containing * The io address and interrupt count * for this device. * phy The address of the PHY to be queried. * reg The register whose contents are to be * retrieved. * val A pointer to a variable to store the * retrieved value. * * This function uses the TLAN's MII bus to retrieve the contents * of a given register on a PHY. It sends the appropriate info * and then reads the 16-bit register value from the MII bus via * the TLAN SIO register. * **************************************************************/ static bool __tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val) { … } static void tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val) { … } /*************************************************************** * tlan_mii_send_data * * Returns: * Nothing * Parms: * base_port The base IO port of the adapter in * question. * dev The address of the PHY to be queried. * data The value to be placed on the MII bus. * num_bits The number of bits in data that are to * be placed on the MII bus. * * This function sends on sequence of bits on the MII * configuration bus. * **************************************************************/ static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits) { … } /*************************************************************** * TLan_MiiSync * * Returns: * Nothing * Parms: * base_port The base IO port of the adapter in * question. * * This functions syncs all PHYs in terms of the MII configuration * bus. * **************************************************************/ static void tlan_mii_sync(u16 base_port) { … } /*************************************************************** * __tlan_mii_write_reg * * Returns: * Nothing * Parms: * dev The device structure for the device * to write to. * phy The address of the PHY to be written to. * reg The register whose contents are to be * written. * val The value to be written to the register. * * This function uses the TLAN's MII bus to write the contents of a * given register on a PHY. It sends the appropriate info and then * writes the 16-bit register value from the MII configuration bus * via the TLAN SIO register. * **************************************************************/ static void __tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val) { … } static void tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val) { … } /***************************************************************************** ****************************************************************************** ThunderLAN driver eeprom routines the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A EEPROM. these functions are based on information in microchip's data sheet. I don't know how well this functions will work with other Eeproms. ****************************************************************************** *****************************************************************************/ /*************************************************************** * tlan_ee_send_start * * Returns: * Nothing * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * * This function sends a start cycle to an EEPROM attached * to a TLAN chip. * **************************************************************/ static void tlan_ee_send_start(u16 io_base) { … } /*************************************************************** * tlan_ee_send_byte * * Returns: * If the correct ack was received, 0, otherwise 1 * Parms: io_base The IO port base address for the * TLAN device with the EEPROM to * use. * data The 8 bits of information to * send to the EEPROM. * stop If TLAN_EEPROM_STOP is passed, a * stop cycle is sent after the * byte is sent after the ack is * read. * * This function sends a byte on the serial EEPROM line, * driving the clock to send each bit. The function then * reverses transmission direction and reads an acknowledge * bit. * **************************************************************/ static int tlan_ee_send_byte(u16 io_base, u8 data, int stop) { … } /*************************************************************** * tlan_ee_receive_byte * * Returns: * Nothing * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * data An address to a char to hold the * data sent from the EEPROM. * stop If TLAN_EEPROM_STOP is passed, a * stop cycle is sent after the * byte is received, and no ack is * sent. * * This function receives 8 bits of data from the EEPROM * over the serial link. It then sends and ack bit, or no * ack and a stop bit. This function is used to retrieve * data after the address of a byte in the EEPROM has been * sent. * **************************************************************/ static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop) { … } /*************************************************************** * tlan_ee_read_byte * * Returns: * No error = 0, else, the stage at which the error * occurred. * Parms: * io_base The IO port base address for the * TLAN device with the EEPROM to * use. * ee_addr The address of the byte in the * EEPROM whose contents are to be * retrieved. * data An address to a char to hold the * data obtained from the EEPROM. * * This function reads a byte of information from an byte * cell in the EEPROM. * **************************************************************/ static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data) { … }