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:
parent
ae6a5712e6
commit
eb003e8df3
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ EXTRA_DIST = \
|
|||
Kbuild.in \
|
||||
module.h \
|
||||
netdev.h \
|
||||
print.h \
|
||||
update.h
|
||||
|
||||
BUILT_SOURCES = \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue