iPXE
dm96xx.h
Go to the documentation of this file.
00001 #ifndef _DM96XX_H
00002 #define _DM96XX_H
00003 
00004 /** @file
00005  *
00006  * Davicom DM96xx USB Ethernet driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <ipxe/usb.h>
00013 #include <ipxe/usbnet.h>
00014 #include <ipxe/if_ether.h>
00015 
00016 /** Read register(s) */
00017 #define DM96XX_READ_REGISTER                                    \
00018         ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE |     \
00019           USB_REQUEST_TYPE ( 0x00 ) )
00020 
00021 /** Write register(s) */
00022 #define DM96XX_WRITE_REGISTER                                   \
00023         ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |    \
00024           USB_REQUEST_TYPE ( 0x01 ) )
00025 
00026 /** Write single register */
00027 #define DM96XX_WRITE1_REGISTER                                  \
00028         ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE |    \
00029           USB_REQUEST_TYPE ( 0x03 ) )
00030 
00031 /** Network control register */
00032 #define DM96XX_NCR 0x00
00033 #define DM96XX_NCR_RST          0x01    /**< Software reset */
00034 
00035 /** Network status register */
00036 #define DM96XX_NSR 0x01
00037 #define DM96XX_NSR_LINKST       0x40    /**< Link status */
00038 
00039 /** Receive control register */
00040 #define DM96XX_RCR 0x05
00041 #define DM96XX_RCR_ALL          0x08    /**< Pass all multicast */
00042 #define DM96XX_RCR_RUNT         0x04    /**< Pass runt packet */
00043 #define DM96XX_RCR_PRMSC        0x02    /**< Promiscuous mode */
00044 #define DM96XX_RCR_RXEN         0x01    /**< RX enable */
00045 
00046 /** Receive status register */
00047 #define DM96XX_RSR 0x06
00048 #define DM96XX_RSR_MF           0x40    /**< Multicast frame */
00049 
00050 /** PHY address registers */
00051 #define DM96XX_PAR 0x10
00052 
00053 /** Chip revision register */
00054 #define DM96XX_CHIPR 0x2c
00055 #define DM96XX_CHIPR_9601       0x00    /**< DM9601 */
00056 #define DM96XX_CHIPR_9620       0x01    /**< DM9620 */
00057 
00058 /** RX header control/status register (DM9620+ only) */
00059 #define DM96XX_MODE_CTL 0x91
00060 #define DM96XX_MODE_CTL_MODE    0x80    /**< 4-byte header mode */
00061 
00062 /** DM96xx interrupt data */
00063 struct dm96xx_interrupt {
00064         /** Network status register */
00065         uint8_t nsr;
00066         /** Transmit status registers */
00067         uint8_t tsr[2];
00068         /** Receive status register */
00069         uint8_t rsr;
00070         /** Receive overflow counter register */
00071         uint8_t rocr;
00072         /** Receive packet counter */
00073         uint8_t rxc;
00074         /** Transmit packet counter */
00075         uint8_t txc;
00076         /** General purpose register */
00077         uint8_t gpr;
00078 } __attribute__ (( packed ));
00079 
00080 /** DM96xx receive header */
00081 struct dm96xx_rx_header {
00082         /** Packet status */
00083         uint8_t rsr;
00084         /** Packet length (excluding this header, including CRC) */
00085         uint16_t len;
00086 } __attribute__ (( packed ));
00087 
00088 /** DM96xx transmit header */
00089 struct dm96xx_tx_header {
00090         /** Packet length (excluding this header) */
00091         uint16_t len;
00092 } __attribute__ (( packed ));
00093 
00094 /** A DM96xx network device */
00095 struct dm96xx_device {
00096         /** USB device */
00097         struct usb_device *usb;
00098         /** USB bus */
00099         struct usb_bus *bus;
00100         /** Network device */
00101         struct net_device *netdev;
00102         /** USB network device */
00103         struct usbnet_device usbnet;
00104 };
00105 
00106 /**
00107  * Read registers
00108  *
00109  * @v dm96xx            DM96xx device
00110  * @v offset            Register offset
00111  * @v data              Data buffer
00112  * @v len               Length of data
00113  * @ret rc              Return status code
00114  */
00115 static inline __attribute__ (( always_inline )) int
00116 dm96xx_read_registers ( struct dm96xx_device *dm96xx, unsigned int offset,
00117                         void *data, size_t len ) {
00118 
00119         return usb_control ( dm96xx->usb, DM96XX_READ_REGISTER, 0, offset,
00120                              data, len );
00121 }
00122 
00123 /**
00124  * Read register
00125  *
00126  * @v dm96xx            DM96xx device
00127  * @v offset            Register offset
00128  * @ret value           Register value, or negative error
00129  */
00130 static inline __attribute__ (( always_inline )) int
00131 dm96xx_read_register ( struct dm96xx_device *dm96xx, unsigned int offset ) {
00132         uint8_t value;
00133         int rc;
00134 
00135         if ( ( rc = dm96xx_read_registers ( dm96xx, offset, &value,
00136                                             sizeof ( value ) ) ) != 0 )
00137                 return rc;
00138         return value;
00139 }
00140 
00141 /**
00142  * Write registers
00143  *
00144  * @v dm96xx            DM96xx device
00145  * @v offset            Register offset
00146  * @v data              Data buffer
00147  * @v len               Length of data
00148  * @ret rc              Return status code
00149  */
00150 static inline __attribute__ (( always_inline )) int
00151 dm96xx_write_registers ( struct dm96xx_device *dm96xx, unsigned int offset,
00152                          void *data, size_t len ) {
00153 
00154         return usb_control ( dm96xx->usb, DM96XX_WRITE_REGISTER, 0, offset,
00155                              data, len );
00156 }
00157 
00158 /**
00159  * Write register
00160  *
00161  * @v dm96xx            DM96xx device
00162  * @v offset            Register offset
00163  * @v value             Register value
00164  * @ret rc              Return status code
00165  */
00166 static inline __attribute__ (( always_inline )) int
00167 dm96xx_write_register ( struct dm96xx_device *dm96xx, unsigned int offset,
00168                         uint8_t value ) {
00169 
00170         return usb_control ( dm96xx->usb, DM96XX_WRITE1_REGISTER, value,
00171                              offset, NULL, 0 );
00172 }
00173 
00174 /** Reset delay (in microseconds) */
00175 #define DM96XX_RESET_DELAY_US 10
00176 
00177 /** Interrupt maximum fill level
00178  *
00179  * This is a policy decision.
00180  */
00181 #define DM96XX_INTR_MAX_FILL 2
00182 
00183 /** Bulk IN maximum fill level
00184  *
00185  * This is a policy decision.
00186  */
00187 #define DM96XX_IN_MAX_FILL 8
00188 
00189 /** Bulk IN buffer size */
00190 #define DM96XX_IN_MTU                                   \
00191         ( 4 /* DM96xx header */ + ETH_FRAME_LEN +       \
00192           4 /* possible VLAN header */ + 4 /* CRC */ )
00193 
00194 #endif /* _DM96XX_H */