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
This commit is contained in:
Patrick Bruenn 2014-06-05 16:30:22 +02:00
parent ae6a5712e6
commit eb003e8df3
6 changed files with 111 additions and 51 deletions

View File

@ -37,7 +37,6 @@ ifeq (@ENABLE_CCAT@,1)
EC_CCAT_OBJ := \
module.o \
netdev.o \
print.o \
update.o
obj-m += ec_ccat.o
ec_ccat-objs := $(EC_CCAT_OBJ)

View File

@ -31,7 +31,6 @@ EXTRA_DIST = \
Kbuild.in \
module.h \
netdev.h \
print.h \
update.h
BUILT_SOURCES = \

View File

@ -152,11 +152,11 @@ int ccat_dma_init(struct ccat_dma *const dma, size_t channel,
*/
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 @@ static int ccat_functions_init(struct ccat_device *const ccatdev)
pr_info("Found: 0x%04x not supported\n", type);
break;
}
addr += sizeof(CCatInfoBlock);
addr += block_size;
}
return status;
}
@ -229,13 +229,9 @@ static int ccat_probe(struct pci_dev *pdev, const struct pci_device_id *id)
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 @@ static struct pci_driver pci_driver = {
.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)
static int __init ccat_init_module(void)
{
BUILD_BUG_ON(offsetof(struct ccat_eth_frame, data) !=
CCAT_DMA_FRAME_HEADER_LENGTH);
pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
return pci_register_driver(&pci_driver);
}

View File

@ -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"
@ -35,6 +34,17 @@
#undef pr_fmt
#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
@ -90,6 +100,7 @@ struct ccat_eth_frame {
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_device {
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 @@ struct ccat_eth_priv {
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;
@ -185,6 +211,47 @@ struct ccat_eth_priv {
void (*unregister) (struct net_device * const netdev);
};
/**
* 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
@ -200,6 +267,6 @@ struct ccat_update {
dev_t dev;
struct cdev cdev;
struct class *class;
CCatInfoBlock info;
struct ccat_info_block info;
};
#endif /* #ifndef _CCAT_H_ */

View File

@ -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 @@ static int ccat_eth_priv_init_dma(struct ccat_eth_priv *priv)
{
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 int ccat_eth_priv_init_dma(struct ccat_eth_priv *priv)
*/
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 @@ static struct rtnl_link_stats64 *ccat_eth_get_stats64(struct net_device *dev, st
*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 @@ struct ccat_eth_priv *ccat_eth_init(const struct ccat_device *const ccatdev,
/* 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 @@ struct ccat_eth_priv *ccat_eth_init(const struct ccat_device *const ccatdev,
}
/* 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 @@ static netdev_tx_t ccat_eth_start_xmit(struct sk_buff *skb,
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 @@ static void ccat_eth_link_up(struct net_device *const dev)
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);

View File

@ -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 @@ struct ccat_update *ccat_update_init(const struct ccat_device *const ccatdev,
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;
}