These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / dm96xx.h
diff --git a/qemu/roms/ipxe/src/drivers/net/dm96xx.h b/qemu/roms/ipxe/src/drivers/net/dm96xx.h
new file mode 100644 (file)
index 0000000..43a1a4e
--- /dev/null
@@ -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 */