make ccat driver more linux compliant stable-1.5
authorPatrick Bruenn <p.bruenn@beckhoff.com>
Thu, 05 Jun 2014 16:30:22 +0200
branchstable-1.5
changeset 2569 720172a7563f
parent 2568 2f3078ec9ffb
child 2570 144e11d93e99
make ccat driver more linux compliant
- reduce enum ccat_info_t to the minimal set of defines
- replace CamelCased WINDOWS typedef structs with linux types
- remove print.c/.h from the driver build, but keep the files for debugging
devices/ccat/Kbuild.in
devices/ccat/Makefile.am
devices/ccat/module.c
devices/ccat/module.h
devices/ccat/netdev.c
devices/ccat/update.c
--- a/devices/ccat/Kbuild.in	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/Kbuild.in	Thu Jun 05 16:30:22 2014 +0200
@@ -37,7 +37,6 @@
 	EC_CCAT_OBJ := \
 		module.o \
 		netdev.o \
-		print.o \
 		update.o
 	obj-m += ec_ccat.o
 	ec_ccat-objs := $(EC_CCAT_OBJ)
--- a/devices/ccat/Makefile.am	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/Makefile.am	Thu Jun 05 16:30:22 2014 +0200
@@ -31,7 +31,6 @@
 	Kbuild.in \
 	module.h \
 	netdev.h \
-	print.h \
 	update.h
 
 BUILT_SOURCES = \
--- a/devices/ccat/module.c	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/module.c	Thu Jun 05 16:30:22 2014 +0200
@@ -152,11 +152,11 @@
  */
 static int ccat_functions_init(struct ccat_device *const ccatdev)
 {
-	/* read CCatInfoBlock.nMaxEntries from ccat */
-	const u8 num_func = ioread8(ccatdev->bar[0].ioaddr + 4);
-	void __iomem *addr = ccatdev->bar[0].ioaddr;
-	const void __iomem *end = addr + (sizeof(CCatInfoBlock) * num_func);
-	int status = 0;		/* count init function failures */
+	static const size_t block_size = sizeof(struct ccat_info_block);
+	void __iomem *addr = ccatdev->bar[0].ioaddr; /** first block is the CCAT information block entry */
+	const u8 num_func = ioread8(addr + 4); /** number of CCAT function blocks is at offset 0x4 */
+	const void __iomem *end = addr + (block_size * num_func);
+	int status = 0;	/** count init function failures */
 
 	while (addr < end) {
 		const u8 type = ioread16(addr);
@@ -177,7 +177,7 @@
 			pr_info("Found: 0x%04x not supported\n", type);
 			break;
 		}
-		addr += sizeof(CCatInfoBlock);
+		addr += block_size;
 	}
 	return status;
 }
@@ -229,13 +229,9 @@
 		return status;
 	}
 
-	/* FIXME upgrade to a newer kernel to get support of dma_set_mask_and_coherent()
-	 * (!dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64))) {
-	 */
-	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+	if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
 		pr_debug("64 bit DMA supported, pci rev: %u\n", revision);
-		/*} else if (!dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32))) { */
-	} else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
+	} else if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
 		pr_debug("32 bit DMA supported, pci rev: %u\n", revision);
 	} else {
 		pr_warn("No suitable DMA available, pci rev: %u\n", revision);
@@ -290,15 +286,13 @@
 	.remove = ccat_remove,
 };
 
-static void ccat_exit_module(void)
+static void __exit ccat_exit_module(void)
 {
 	pci_unregister_driver(&pci_driver);
 }
 
-static int ccat_init_module(void)
-{
-	BUILD_BUG_ON(offsetof(struct ccat_eth_frame, data) !=
-		     CCAT_DMA_FRAME_HEADER_LENGTH);
+static int __init ccat_init_module(void)
+{
 	pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 	return pci_register_driver(&pci_driver);
 }
--- a/devices/ccat/module.h	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/module.h	Thu Jun 05 16:30:22 2014 +0200
@@ -25,7 +25,6 @@
 #include <linux/hrtimer.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include "CCatDefinitions.h"
 #include "../ecdev.h"
 
 #define DRV_EXTRAVERSION "-ec"
@@ -36,6 +35,17 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 /**
+ * CCAT function type identifiers (u16)
+ */
+enum ccat_info_t {
+	CCATINFO_NOTUSED = 0,
+	CCATINFO_EPCS_PROM = 0xf,
+	CCATINFO_ETHERCAT_MASTER_DMA = 0x14,
+	CCATINFO_COPY_BLOCK = 0x17,
+	CCATINFO_MAX
+};
+
+/**
  * struct ccat_bar - CCAT PCI Base Address Register(BAR) configuration
  * @start: start address of this BAR
  * @end: end address of this BAR
@@ -90,6 +100,7 @@
 	u32 reserved4:31;
 	u64 timestamp;
 	u8 data[0x800 - 3 * sizeof(u64)];
+#define CCAT_ETH_FRAME_HEAD_LEN offsetof(struct ccat_eth_frame, data)
 };
 
 /**
@@ -145,6 +156,21 @@
 	struct ccat_bar bar[3];	//TODO optimize this
 };
 
+struct ccat_info_block
+{
+	u16 type;
+	u16 rev;
+	union {
+		u32 config;
+		struct {
+			u8 tx_dma_chan;
+			u8 rx_dma_chan;
+		};
+	};
+	u32 addr;
+	u32 size;
+};
+
 /**
  * struct ccat_eth_priv - CCAT Ethernet/EtherCAT Master function (netdev)
  * @ccatdev: pointer to the parent struct ccat_device
@@ -164,7 +190,7 @@
 	const struct ccat_device *ccatdev;
 	struct net_device *netdev;
 	const struct ccat_eth_frame *next_tx_frame;
-	CCatInfoBlock info;
+	struct ccat_info_block info;
 	struct ccat_eth_register reg;
 	struct ccat_eth_dma_fifo rx_fifo;
 	struct ccat_eth_dma_fifo tx_fifo;
@@ -186,6 +212,47 @@
 };
 
 /**
+ * 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_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;
+};
+
+/**
  * struct ccat_update - CCAT Update function (update)
  * @ccatdev: pointer to the parent struct ccat_device
  * @ioaddr: PCI base address of the CCAT Update function
@@ -200,6 +267,6 @@
 	dev_t dev;
 	struct cdev cdev;
 	struct class *class;
-	CCatInfoBlock info;
+	struct ccat_info_block info;
 };
 #endif /* #ifndef _CCAT_H_ */
--- a/devices/ccat/netdev.c	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/netdev.c	Thu Jun 05 16:30:22 2014 +0200
@@ -28,7 +28,6 @@
 #include "compat.h"
 #include "module.h"
 #include "netdev.h"
-#include "print.h"
 
 /**
  * EtherCAT frame to enable forwarding on EtherCAT Terminals
@@ -194,14 +193,14 @@
 {
 	if (ccat_eth_dma_fifo_init
 	    (&priv->rx_fifo, priv->reg.rx_fifo, ccat_eth_rx_fifo_add,
-	     priv->info.rxDmaChn, priv)) {
+	     priv->info.rx_dma_chan, priv)) {
 		pr_warn("init Rx DMA fifo failed.\n");
 		return -1;
 	}
 
 	if (ccat_eth_dma_fifo_init
 	    (&priv->tx_fifo, priv->reg.tx_fifo, ccat_eth_tx_fifo_add_free,
-	     priv->info.txDmaChn, priv)) {
+	     priv->info.tx_dma_chan, priv)) {
 		pr_warn("init Tx DMA fifo failed.\n");
 		ccat_dma_free(&priv->rx_fifo.dma);
 		return -1;
@@ -219,18 +218,18 @@
  */
 static void ccat_eth_priv_init_mappings(struct ccat_eth_priv *priv)
 {
-	CCatInfoBlockOffs offsets;
+	struct ccat_mac_infoblock offsets;
 	void __iomem *const func_base =
-	    priv->ccatdev->bar[0].ioaddr + priv->info.nAddr;
+	    priv->ccatdev->bar[0].ioaddr + priv->info.addr;
 
 	memcpy_fromio(&offsets, func_base, sizeof(offsets));
-	priv->reg.mii = func_base + offsets.nMMIOffs;
-	priv->reg.tx_fifo = func_base + offsets.nTxFifoOffs;
-	priv->reg.rx_fifo = func_base + offsets.nTxFifoOffs + 0x10;
-	priv->reg.mac = func_base + offsets.nMacRegOffs;
-	priv->reg.rx_mem = func_base + offsets.nRxMemOffs;
-	priv->reg.tx_mem = func_base + offsets.nTxMemOffs;
-	priv->reg.misc = func_base + offsets.nMiscOffs;
+	priv->reg.mii = func_base + offsets.mii;
+	priv->reg.tx_fifo = func_base + offsets.tx_fifo;
+	priv->reg.rx_fifo = func_base + offsets.tx_fifo + 0x10;
+	priv->reg.mac = func_base + offsets.mac;
+	priv->reg.rx_mem = func_base + offsets.rx_mem;
+	priv->reg.tx_mem = func_base + offsets.tx_mem;
+	priv->reg.misc = func_base + offsets.misc;
 }
 
 /**
@@ -248,26 +247,26 @@
 						      *storage)
 {
 	struct ccat_eth_priv *const priv = netdev_priv(dev);
-	CCatMacRegs mac;
+	struct ccat_mac_register mac;
 
 	memcpy_fromio(&mac, priv->reg.mac, sizeof(mac));
-	storage->rx_packets = mac.rxFrameCnt;	/* total packets received       */
-	storage->tx_packets = mac.txFrameCnt;	/* total packets transmitted    */
+	storage->rx_packets = mac.rx_frames;	/* total packets received       */
+	storage->tx_packets = mac.tx_frames;	/* total packets transmitted    */
 	storage->rx_bytes = atomic64_read(&priv->rx_bytes);	/* total bytes received         */
 	storage->tx_bytes = atomic64_read(&priv->tx_bytes);	/* total bytes transmitted      */
-	storage->rx_errors = mac.frameLenErrCnt + mac.dropFrameErrCnt + mac.crcErrCnt + mac.rxErrCnt;	/* bad packets received         */
-	//TODO __u64    tx_errors;              /* packet transmit problems     */
+	storage->rx_errors = mac.frame_len_err + mac.rx_mem_full + mac.crc_err + mac.rx_err;	/* bad packets received         */
+	storage->tx_errors = mac.tx_mem_full; /* packet transmit problems     */
 	storage->rx_dropped = atomic64_read(&priv->rx_dropped);	/* no space in linux buffers    */
 	storage->tx_dropped = atomic64_read(&priv->tx_dropped);	/* no space available in linux  */
 	//TODO __u64    multicast;              /* multicast packets received   */
 	//TODO __u64    collisions;
 
 	/* detailed rx_errors: */
-	storage->rx_length_errors = mac.frameLenErrCnt;
-	storage->rx_over_errors = mac.dropFrameErrCnt;	/* receiver ring buff overflow  */
-	storage->rx_crc_errors = mac.crcErrCnt;	/* recved pkt with crc error    */
-	storage->rx_frame_errors = mac.rxErrCnt;	/* recv'd frame alignment error */
-	storage->rx_fifo_errors = mac.dropFrameErrCnt;	/* recv'r fifo overrun          */
+	storage->rx_length_errors = mac.frame_len_err;
+	storage->rx_over_errors = mac.rx_mem_full;	/* receiver ring buff overflow  */
+	storage->rx_crc_errors = mac.crc_err;	/* recved pkt with crc error    */
+	storage->rx_frame_errors = mac.rx_err;	/* recv'd frame alignment error */
+	storage->rx_fifo_errors = mac.rx_mem_full;	/* recv'r fifo overrun          */
 	//TODO __u64    rx_missed_errors;       /* receiver missed packet       */
 
 	/* detailed tx_errors */
@@ -297,7 +296,9 @@
 	/* ccat register mappings */
 	memcpy_fromio(&priv->info, addr, sizeof(priv->info));
 	ccat_eth_priv_init_mappings(priv);
-	ccat_print_function_info(priv);
+	/* XXX disabled in release
+	 * ccat_print_function_info(priv);
+	 */
 
 	if (ccat_eth_priv_init_dma(priv)) {
 		pr_warn("%s(): DMA initialization failed.\n", __FUNCTION__);
@@ -306,7 +307,7 @@
 	}
 
 	/* init netdev with MAC and stack callbacks */
-	memcpy_fromio(netdev->dev_addr, priv->reg.mii + 8, 6);
+	memcpy_fromio(netdev->dev_addr, priv->reg.mii + 8, netdev->addr_len);
 	netdev->netdev_ops = &ccat_eth_netdev_ops;
 
 	/* use as EtherCAT device? */
@@ -455,7 +456,7 @@
 
 	addr_and_length = 8 + (next * sizeof(*frame));
 	addr_and_length +=
-	    ((frame[next].length + CCAT_DMA_FRAME_HEADER_LENGTH) / 8) << 24;
+	    ((frame[next].length + CCAT_ETH_FRAME_HEAD_LEN) / 8) << 24;
 	iowrite32(addr_and_length, priv->reg.tx_fifo);	/* add to DMA fifo */
 	atomic64_add(frame[next].length, &priv->tx_bytes);	/* update stats */
 
@@ -497,6 +498,9 @@
 
 	ccat_eth_dma_fifo_reset(&priv->rx_fifo);
 	ccat_eth_dma_fifo_reset(&priv->tx_fifo);
+
+	/* TODO reset CCAT MAC register */
+
 	ccat_eth_xmit_raw(dev, frameForwardEthernetFrames,
 			  sizeof(frameForwardEthernetFrames));
 	priv->carrier_on(dev);
--- a/devices/ccat/update.c	Thu Jun 05 16:14:13 2014 +0200
+++ b/devices/ccat/update.c	Thu Jun 05 16:30:22 2014 +0200
@@ -25,7 +25,6 @@
 #include <linux/uaccess.h>
 #include "compat.h"
 #include "module.h"
-#include "print.h"
 #include "update.h"
 
 #define CCAT_DATA_IN_4 0x038
@@ -401,11 +400,9 @@
 	kref_init(&update->refcount);
 	update->ioaddr = ccatdev->bar[0].ioaddr + ioread32(addr + 0x8);
 	memcpy_fromio(&update->info, addr, sizeof(update->info));
-	print_update_info(&update->info, update->ioaddr);
-
-	if (0x00 != update->info.nRevision) {
-		pr_warn("CCAT Update rev. %d not supported\n",
-			update->info.nRevision);
+
+	if (0x00 != update->info.rev) {
+		pr_warn("CCAT Update rev. %d not supported\n", update->info.rev);
 		goto cleanup;
 	}