summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/drivers/net/dm96xx.h
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/drivers/net/dm96xx.h')
-rw-r--r--qemu/roms/ipxe/src/drivers/net/dm96xx.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/drivers/net/dm96xx.h b/qemu/roms/ipxe/src/drivers/net/dm96xx.h
new file mode 100644
index 000000000..43a1a4e30
--- /dev/null
+++ b/qemu/roms/ipxe/src/drivers/net/dm96xx.h
@@ -0,0 +1,194 @@
+#ifndef _DM96XX_H
+#define _DM96XX_H
+
+/** @file
+ *
+ * Davicom DM96xx USB Ethernet driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/usb.h>
+#include <ipxe/usbnet.h>
+#include <ipxe/if_ether.h>
+
+/** Read register(s) */
+#define DM96XX_READ_REGISTER \
+ ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
+ USB_REQUEST_TYPE ( 0x00 ) )
+
+/** Write register(s) */
+#define DM96XX_WRITE_REGISTER \
+ ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
+ USB_REQUEST_TYPE ( 0x01 ) )
+
+/** Write single register */
+#define DM96XX_WRITE1_REGISTER \
+ ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
+ USB_REQUEST_TYPE ( 0x03 ) )
+
+/** Network control register */
+#define DM96XX_NCR 0x00
+#define DM96XX_NCR_RST 0x01 /**< Software reset */
+
+/** Network status register */
+#define DM96XX_NSR 0x01
+#define DM96XX_NSR_LINKST 0x40 /**< Link status */
+
+/** Receive control register */
+#define DM96XX_RCR 0x05
+#define DM96XX_RCR_ALL 0x08 /**< Pass all multicast */
+#define DM96XX_RCR_RUNT 0x04 /**< Pass runt packet */
+#define DM96XX_RCR_PRMSC 0x02 /**< Promiscuous mode */
+#define DM96XX_RCR_RXEN 0x01 /**< RX enable */
+
+/** Receive status register */
+#define DM96XX_RSR 0x06
+#define DM96XX_RSR_MF 0x40 /**< Multicast frame */
+
+/** PHY address registers */
+#define DM96XX_PAR 0x10
+
+/** Chip revision register */
+#define DM96XX_CHIPR 0x2c
+#define DM96XX_CHIPR_9601 0x00 /**< DM9601 */
+#define DM96XX_CHIPR_9620 0x01 /**< DM9620 */
+
+/** RX header control/status register (DM9620+ only) */
+#define DM96XX_MODE_CTL 0x91
+#define DM96XX_MODE_CTL_MODE 0x80 /**< 4-byte header mode */
+
+/** DM96xx interrupt data */
+struct dm96xx_interrupt {
+ /** Network status register */
+ uint8_t nsr;
+ /** Transmit status registers */
+ uint8_t tsr[2];
+ /** Receive status register */
+ uint8_t rsr;
+ /** Receive overflow counter register */
+ uint8_t rocr;
+ /** Receive packet counter */
+ uint8_t rxc;
+ /** Transmit packet counter */
+ uint8_t txc;
+ /** General purpose register */
+ uint8_t gpr;
+} __attribute__ (( packed ));
+
+/** DM96xx receive header */
+struct dm96xx_rx_header {
+ /** Packet status */
+ uint8_t rsr;
+ /** Packet length (excluding this header, including CRC) */
+ uint16_t len;
+} __attribute__ (( packed ));
+
+/** DM96xx transmit header */
+struct dm96xx_tx_header {
+ /** Packet length (excluding this header) */
+ uint16_t len;
+} __attribute__ (( packed ));
+
+/** A DM96xx network device */
+struct dm96xx_device {
+ /** USB device */
+ struct usb_device *usb;
+ /** USB bus */
+ struct usb_bus *bus;
+ /** Network device */
+ struct net_device *netdev;
+ /** USB network device */
+ struct usbnet_device usbnet;
+};
+
+/**
+ * Read registers
+ *
+ * @v dm96xx DM96xx device
+ * @v offset Register offset
+ * @v data Data buffer
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+dm96xx_read_registers ( struct dm96xx_device *dm96xx, unsigned int offset,
+ void *data, size_t len ) {
+
+ return usb_control ( dm96xx->usb, DM96XX_READ_REGISTER, 0, offset,
+ data, len );
+}
+
+/**
+ * Read register
+ *
+ * @v dm96xx DM96xx device
+ * @v offset Register offset
+ * @ret value Register value, or negative error
+ */
+static inline __attribute__ (( always_inline )) int
+dm96xx_read_register ( struct dm96xx_device *dm96xx, unsigned int offset ) {
+ uint8_t value;
+ int rc;
+
+ if ( ( rc = dm96xx_read_registers ( dm96xx, offset, &value,
+ sizeof ( value ) ) ) != 0 )
+ return rc;
+ return value;
+}
+
+/**
+ * Write registers
+ *
+ * @v dm96xx DM96xx device
+ * @v offset Register offset
+ * @v data Data buffer
+ * @v len Length of data
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+dm96xx_write_registers ( struct dm96xx_device *dm96xx, unsigned int offset,
+ void *data, size_t len ) {
+
+ return usb_control ( dm96xx->usb, DM96XX_WRITE_REGISTER, 0, offset,
+ data, len );
+}
+
+/**
+ * Write register
+ *
+ * @v dm96xx DM96xx device
+ * @v offset Register offset
+ * @v value Register value
+ * @ret rc Return status code
+ */
+static inline __attribute__ (( always_inline )) int
+dm96xx_write_register ( struct dm96xx_device *dm96xx, unsigned int offset,
+ uint8_t value ) {
+
+ return usb_control ( dm96xx->usb, DM96XX_WRITE1_REGISTER, value,
+ offset, NULL, 0 );
+}
+
+/** Reset delay (in microseconds) */
+#define DM96XX_RESET_DELAY_US 10
+
+/** Interrupt maximum fill level
+ *
+ * This is a policy decision.
+ */
+#define DM96XX_INTR_MAX_FILL 2
+
+/** Bulk IN maximum fill level
+ *
+ * This is a policy decision.
+ */
+#define DM96XX_IN_MAX_FILL 8
+
+/** Bulk IN buffer size */
+#define DM96XX_IN_MTU \
+ ( 4 /* DM96xx header */ + ETH_FRAME_LEN + \
+ 4 /* possible VLAN header */ + 4 /* CRC */ )
+
+#endif /* _DM96XX_H */