devices/ccat/module.h
branchstable-1.5
changeset 2636 0613017547fe
parent 2578 d707b650fa52
child 2638 5995331a55fe
--- a/devices/ccat/module.h	Thu Feb 19 15:19:29 2015 +0100
+++ b/devices/ccat/module.h	Tue Oct 13 12:24:16 2015 +0200
@@ -22,140 +22,76 @@
 #define _CCAT_H_
 
 #include <linux/cdev.h>
+#include <linux/fs.h>
 #include <linux/hrtimer.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include "../ecdev.h"
 
 #define DRV_EXTRAVERSION "-ec"
-#define DRV_VERSION      "0.10" DRV_EXTRAVERSION
+#define DRV_VERSION      "0.13" DRV_EXTRAVERSION
 #define DRV_DESCRIPTION  "Beckhoff CCAT Ethernet/EtherCAT Network Driver"
 
 #undef pr_fmt
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+extern struct ccat_driver eth_eim_driver;
+extern struct ccat_driver eth_dma_driver;
+extern struct ccat_driver gpio_driver;
+extern struct ccat_driver sram_driver;
+extern struct ccat_driver update_driver;
+
 /**
  * CCAT function type identifiers (u16)
  */
 enum ccat_info_t {
 	CCATINFO_NOTUSED = 0,
+	CCATINFO_ETHERCAT_NODMA = 0x3,
+	CCATINFO_GPIO = 0xd,
 	CCATINFO_EPCS_PROM = 0xf,
 	CCATINFO_ETHERCAT_MASTER_DMA = 0x14,
-	CCATINFO_COPY_BLOCK = 0x17,
-	CCATINFO_MAX
+	CCATINFO_SRAM = 0x16,
+};
+
+struct ccat_cdev {
+	atomic_t in_use;
+	void __iomem *ioaddr;
+	size_t iosize;
+	dev_t dev;
+	struct cdev cdev;
+	struct ccat_class *class;
 };
 
 /**
- * struct ccat_bar - CCAT PCI Base Address Register(BAR) configuration
- * @start: start address of this BAR
- * @end: end address of this BAR
- * @len: length of this BAR
- * @flags: flags set on this BAR
- * @ioaddr: ioremapped address of this bar
+ * struct cdev_buffer
+ * @ccdev: referenced character device
+ * @data: buffer used for write operations
+ * @size: number of bytes written to the data buffer
  */
-struct ccat_bar {
-	unsigned long start;
-	unsigned long end;
-	unsigned long len;
-	unsigned long flags;
-	void __iomem *ioaddr;
+struct cdev_buffer {
+	struct ccat_cdev *ccdev;
+	size_t size;
+	char data[];
 };
 
-/**
- * struct ccat_dma - CCAT DMA channel configuration
- * @phys: device-viewed address(physical) of the associated DMA memory
- * @virt: CPU-viewed address(virtual) of the associated DMA memory
- * @size: number of bytes in the associated DMA memory
- * @channel: CCAT DMA channel number
- * @dev: valid struct device pointer
- */
-struct ccat_dma {
-	dma_addr_t phys;
-	void *virt;
-	size_t size;
-	size_t channel;
-	struct device *dev;
-};
-
-extern void ccat_dma_free(struct ccat_dma *const dma);
-extern int ccat_dma_init(struct ccat_dma *const dma, size_t channel,
-			 void __iomem * const ioaddr, struct device *const dev);
-
-/**
- * struct ccat_eth_frame - Ethernet frame with DMA descriptor header in front
- * @reservedn: is not used and should always be set to 0
- * @received: used for reception, is set to 1 by the CCAT when data was written
- * @length: number of bytes in the frame including the DMA header
- * @sent: is set to 1 by the CCAT when data was transmitted
- * @timestamp: a 64 bit EtherCAT timestamp
- * @data: the bytes of the ethernet frame
- */
-struct ccat_eth_frame {
-	__le32 reserved1;
-	__le32 rx_flags;
-#define CCAT_FRAME_RECEIVED 0x1
-	__le16 length;
-	__le16 reserved3;
-	__le32 tx_flags;
-#define CCAT_FRAME_SENT 0x1
-	__le64 timestamp;
-	u8 data[0x800 - 3 * sizeof(u64)];
-#define CCAT_ETH_FRAME_HEAD_LEN offsetof(struct ccat_eth_frame, data)
-};
-
-/**
- * struct ccat_eth_register - CCAT register addresses in the PCI BAR
- * @mii: address of the CCAT management interface register
- * @tx_fifo: address of the CCAT TX DMA fifo register
- * @rx_fifo: address of the CCAT RX DMA fifo register
- * @mac: address of the CCAT media access control register
- * @rx_mem: address of the CCAT register holding the RX DMA address
- * @tx_mem: address of the CCAT register holding the TX DMA address
- * @misc: address of a CCAT register holding miscellaneous information
- */
-struct ccat_eth_register {
-	void __iomem *mii;
-	void __iomem *tx_fifo;
-	void __iomem *rx_fifo;
-	void __iomem *mac;
-	void __iomem *rx_mem;
-	void __iomem *tx_mem;
-	void __iomem *misc;
-};
-
-/**
- * struct ccat_eth_dma_fifo - CCAT RX or TX DMA fifo
- * @add: callback used to add a frame to this fifo
- * @reg: PCI register address of this DMA fifo
- * @dma: information about the associated DMA memory
- */
-struct ccat_eth_dma_fifo {
-	void (*add) (struct ccat_eth_dma_fifo *, struct ccat_eth_frame *);
-	void __iomem *reg;
-	const struct ccat_eth_frame *end;
-	struct ccat_eth_frame *next;
-	struct ccat_dma dma;
-};
+extern int ccat_cdev_open(struct inode *const i, struct file *const f);
+extern int ccat_cdev_release(struct inode *const i, struct file *const f);
 
 /**
  * struct ccat_device - CCAT device representation
  * @pdev: pointer to the pci object allocated by the kernel
- * @ethdev: CCAT Ethernet/EtherCAT Master (with DMA) function, NULL if function is not available or failed to initialize
- * @update: CCAT Update function, NULL if function is not available or failed to initialize
- * @bar [0] and [2] holding information about PCI BARs 0 and 2.
+ * @bar_0: holding information about PCI BAR 0
+ * @bar_2: holding information about PCI BAR 2 (optional)
+ * @functions: list of available (driver loaded) FPGA functions
  *
  * One instance of a ccat_device should represent a physical CCAT. Since
- * a CCAT is implemented as FPGA the available functions can vary so
- * the function object pointers can be NULL.
- * Extra note: you will recognize that PCI BAR1 is not used and is a
- * waste of memory, thats true but right now, its very easy to use it
- * this way. So we might optimize it later.
+ * a CCAT is implemented as FPGA the available functions can vary.
  */
 struct ccat_device {
-	struct pci_dev *pdev;
-	struct ccat_eth_priv *ethdev;
-	struct ccat_update *update;
-	struct ccat_bar bar[3];	//TODO optimize this
+	void *pdev;
+	void __iomem *bar_0;
+	void __iomem *bar_2;
+	struct list_head functions;
 };
 
 struct ccat_info_block {
@@ -163,106 +99,59 @@
 	u16 rev;
 	union {
 		u32 config;
+		u8 num_gpios;
+		struct {
+			u16 tx_size;
+			u16 rx_size;
+		};
 		struct {
 			u8 tx_dma_chan;
 			u8 rx_dma_chan;
 		};
+		struct {
+			u8 sram_width;
+			u8 sram_size;
+			u16 reserved;
+		};
 	};
 	u32 addr;
 	u32 size;
 };
 
-/**
- * struct ccat_eth_priv - CCAT Ethernet/EtherCAT Master function (netdev)
- * @ccatdev: pointer to the parent struct ccat_device
- * @netdev: the net_device structure used by the kernel networking stack
- * @info: holds a copy of the CCAT Ethernet/EtherCAT Master function information block (read from PCI config space)
- * @reg: register addresses in PCI config space of the Ethernet/EtherCAT Master function
- * @rx_fifo: DMA fifo used for RX DMA descriptors
- * @tx_fifo: DMA fifo used for TX DMA descriptors
- * @poll_timer: interval timer used to poll CCAT for events like link changed, rx done, tx done
- * @rx_bytes: number of bytes received -> reported with ndo_get_stats64()
- * @rx_dropped: number of received frames, which were dropped -> reported with ndo_get_stats64()
- * @tx_bytes: number of bytes send -> reported with ndo_get_stats64()
- * @tx_dropped: number of frames requested to send, which were dropped -> reported with ndo_get_stats64()
- */
-struct ccat_eth_priv {
-	const struct ccat_device *ccatdev;
-	struct net_device *netdev;
+struct ccat_function {
+	const struct ccat_driver *drv;
+	struct ccat_device *ccat;
 	struct ccat_info_block info;
-	struct ccat_eth_register reg;
-	struct ccat_eth_dma_fifo rx_fifo;
-	struct ccat_eth_dma_fifo tx_fifo;
-	struct hrtimer poll_timer;
-	atomic64_t rx_bytes;
-	atomic64_t rx_dropped;
-	atomic64_t tx_bytes;
-	atomic64_t tx_dropped;
-	ec_device_t *ecdev;
-	void (*carrier_off) (struct net_device * netdev);
-	bool (*carrier_ok) (const struct net_device * netdev);
-	void (*carrier_on) (struct net_device * netdev);
-	void (*kfree_skb_any) (struct sk_buff * skb);
-	void (*start_queue) (struct net_device * netdev);
-	void (*stop_queue) (struct net_device * netdev);
-	void (*unregister) (struct net_device * netdev);
+	struct list_head list;
+	void *private_data;
 };
 
-/**
- * same as: typedef struct _CCatInfoBlockOffs from CCatDefinitions.h
- * TODO add some checking facility outside of the linux tree
- */
-struct ccat_mac_infoblock {
-	u32 reserved;
-	u32 mii;
-	u32 tx_fifo;
-	u32 mac;
-	u32 rx_mem;
-	u32 tx_mem;
-	u32 misc;
+struct ccat_class {
+	dev_t dev;
+	struct class *class;
+	atomic_t instances;
+	const unsigned count;
+	struct ccat_cdev *devices;
+	const char *name;
+	struct file_operations fops;
 };
 
-struct ccat_mac_register {
-	/** MAC error register     @+0x0 */
-	u8 frame_len_err;
-	u8 rx_err;
-	u8 crc_err;
-	u8 link_lost_err;
-	u32 reserved1;
-	/** Buffer overflow errors @+0x8 */
-	u8 rx_mem_full;
-	u8 reserved2[7];
-	/** MAC frame counter      @+0x10 */
-	u32 tx_frames;
-	u32 rx_frames;
-	u64 reserved3;
-	/** MAC fifo level         @+0x20 */
-	u8 tx_fifo_level:7;
-	u8 reserved4:1;
-	u8 reserved5[7];
-	/** TX memory full error   @+0x28 */
-	u8 tx_mem_full;
-	u8 reserved6[7];
-	u64 reserved8[9];
-	/** Connection             @+0x78 */
-	u8 mii_connected;
+extern void ccat_cdev_remove(struct ccat_function *func);
+extern int ccat_cdev_probe(struct ccat_function *func,
+			   struct ccat_class *cdev_class, size_t iosize);
+
+/**
+ * struct ccat_driver - CCAT FPGA function
+ * @probe: add device instance
+ * @remove: remove device instance
+ * @type: type of the FPGA function supported by this driver
+ * @cdev_class: if not NULL that driver supports ccat_class_init()/_exit()
+ */
+struct ccat_driver {
+	int (*probe) (struct ccat_function * func);
+	void (*remove) (struct ccat_function * drv);
+	enum ccat_info_t type;
+	struct ccat_class *cdev_class;
 };
 
-/**
- * struct ccat_update - CCAT Update function (update)
- * @ccatdev: pointer to the parent struct ccat_device
- * @ioaddr: PCI base address of the CCAT Update function
- * dev: device number for this update function
- * cdev: character device used for the CCAT Update function
- * class: pointer to a device class used when registering the CCAT Update device
- * @info: holds a copy of the CCAT Update function information block (read from PCI config space)
- */
-struct ccat_update {
-	struct kref refcount;
-	void __iomem *ioaddr;
-	dev_t dev;
-	struct cdev cdev;
-	struct class *class;
-	struct ccat_info_block info;
-};
 #endif /* #ifndef _CCAT_H_ */