p@2550: /** p@2550: Network Driver for Beckhoff CCAT communication controller p@2550: Copyright (C) 2014 Beckhoff Automation GmbH p@2550: Author: Patrick Bruenn p@2550: p@2550: This program is free software; you can redistribute it and/or modify p@2550: it under the terms of the GNU General Public License as published by p@2550: the Free Software Foundation; either version 2 of the License, or p@2550: (at your option) any later version. p@2550: p@2550: This program is distributed in the hope that it will be useful, p@2550: but WITHOUT ANY WARRANTY; without even the implied warranty of p@2550: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the p@2550: GNU General Public License for more details. p@2550: p@2550: You should have received a copy of the GNU General Public License along p@2550: with this program; if not, write to the Free Software Foundation, Inc., p@2550: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. p@2550: */ p@2550: p@2550: #include p@2550: #include "CCatDefinitions.h" p@2550: #include "module.h" p@2550: #include "print.h" p@2550: p@2550: #define TESTING_ENABLED 1 p@2550: void print_mem(const unsigned char *p, size_t lines) p@2550: { p@2550: #if TESTING_ENABLED p@2550: pr_info("mem at: %p\n", p); p@2550: pr_info(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); p@2550: while (lines > 0) { p@2550: pr_info p@2550: ("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", p@2550: p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p@2550: p[10], p[11], p[12], p[13], p[14], p[15]); p@2550: p += 16; p@2550: --lines; p@2550: } p@2550: #endif /* #if TESTING_ENABLED */ p@2550: } p@2550: p@2550: static const char *CCatFunctionTypes[CCATINFO_MAX + 1] = { p@2550: "not used", p@2550: "Informationblock", p@2550: "EtherCAT Slave", p@2550: "EtherCAT Master without DMA", p@2550: "Ethernet MAC without DMA", p@2550: "Ethernet Switch", p@2550: "Sercos III", p@2550: "Profibus", p@2550: "CAN Controller", p@2550: "KBUS Master", p@2550: "IP-Link Master (planned)", p@2550: "SPI Master", p@2550: "I²C", p@2550: "GPIO", p@2550: "Drive", p@2550: "CCAT Update", p@2550: "Systemtime", p@2550: "Interrupt Controller", p@2550: "EEPROM Controller", p@2550: "DMA Controller", p@2550: "EtherCAT Master with DMA", p@2550: "Ethernet MAC with DMA", p@2550: "SRAM Interface", p@2550: "Internal Copy block", p@2550: "unknown" p@2550: }; p@2550: p@2550: static void print_CCatDmaRxActBuf(const struct ccat_eth_priv *const priv) p@2550: { p@2550: CCatDmaRxActBuf rx_fifo; p@2550: memcpy_fromio(&rx_fifo, priv->reg.rx_fifo, sizeof(rx_fifo)); p@2550: pr_debug("Rx FIFO base address: %p\n", priv->reg.rx_fifo); p@2550: pr_debug(" Rx Frame Header start: 0x%08x\n", rx_fifo.startAddr); p@2550: pr_debug(" reserved: 0x%08x\n", rx_fifo.reserved1); p@2550: pr_debug(" Rx start address valid: %8u\n", rx_fifo.nextValid); p@2550: pr_debug(" reserved: 0x%08x\n", rx_fifo.reserved2); p@2550: pr_debug(" FIFO level: 0x%08x\n", rx_fifo.FifoLevel); p@2550: pr_debug(" Buffer level: 0x%08x\n", rx_fifo.bufferLevel); p@2550: pr_debug(" next address: 0x%08x\n", rx_fifo.nextAddr); p@2550: } p@2550: p@2550: static void print_CCatDmaTxFifo(const struct ccat_eth_priv *const priv) p@2550: { p@2550: CCatDmaTxFifo tx_fifo; p@2550: memcpy_fromio(&tx_fifo, priv->reg.tx_fifo, sizeof(tx_fifo)); p@2550: pr_debug("Tx FIFO base address: %p\n", priv->reg.tx_fifo); p@2550: pr_debug(" Tx Frame Header start: 0x%08x\n", tx_fifo.startAddr); p@2550: pr_debug(" # 64 bit words: %10d\n", tx_fifo.numQuadWords); p@2550: pr_debug(" reserved: 0x%08x\n", tx_fifo.reserved1); p@2550: pr_debug(" FIFO reset: 0x%08x\n", tx_fifo.fifoReset); p@2550: } p@2550: p@2550: static void print_CCatInfoBlock(const CCatInfoBlock * info, p@2550: const void __iomem * const base_addr) p@2550: { p@2550: const size_t index = min((int)info->eCCatInfoType, CCATINFO_MAX); p@2550: pr_debug("%s\n", CCatFunctionTypes[index]); p@2550: pr_debug(" revision: 0x%x\n", info->nRevision); p@2550: pr_debug(" RX channel: %d\n", info->rxDmaChn); p@2550: pr_debug(" TX channel: %d\n", info->txDmaChn); p@2550: pr_debug(" baseaddr: 0x%x\n", info->nAddr); p@2550: pr_debug(" size: 0x%x\n", info->nSize); p@2550: pr_debug(" subfunction: %p\n", base_addr); p@2550: } p@2550: p@2550: static void print_CCatMacRegs(const struct ccat_eth_priv *const priv) p@2550: { p@2550: CCatMacRegs mac; p@2550: memcpy_fromio(&mac, priv->reg.mac, sizeof(mac)); p@2550: pr_debug("MAC base address: %p\n", priv->reg.mac); p@2550: pr_debug(" frame length error count: %10d\n", mac.frameLenErrCnt); p@2550: pr_debug(" RX error count: %10d\n", mac.rxErrCnt); p@2550: pr_debug(" CRC error count: %10d\n", mac.crcErrCnt); p@2550: pr_debug(" Link lost error count: %10d\n", mac.linkLostErrCnt); p@2550: pr_debug(" reserved: 0x%08x\n", mac.reserved1); p@2550: pr_debug(" RX overflow count: %10d\n", p@2550: mac.dropFrameErrCnt); p@2550: pr_debug(" DMA overflow count: %10d\n", mac.reserved2[0]); p@2550: //pr_debug(" reserverd: %10d\n", DRV_NAME, mac.reserved2[1]); p@2550: pr_debug(" TX frame counter: %10d\n", mac.txFrameCnt); p@2550: pr_debug(" RX frame counter: %10d\n", mac.rxFrameCnt); p@2550: pr_debug(" TX-FIFO level: 0x%08x\n", mac.txFifoLevel); p@2550: pr_debug(" MII connection: 0x%08x\n", mac.miiConnected); p@2550: } p@2550: p@2550: static void print_CCatMii(const struct ccat_eth_priv *const priv) p@2550: { p@2550: CCatMii mii; p@2550: memcpy_fromio(&mii, priv->reg.mii, sizeof(mii)); p@2550: pr_debug("MII base address: %p\n", priv->reg.mii); p@2550: pr_debug(" MII cycle: %s\n", p@2550: mii.startMiCycle ? "running" : "no cycle"); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved1); p@2550: pr_debug(" cmd valid: %s\n", mii.cmdErr ? "no" : "yes"); p@2550: pr_debug(" cmd: 0x%x\n", mii.cmd); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved2); p@2550: pr_debug(" PHY addr: 0x%x\n", mii.phyAddr); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved3); p@2550: pr_debug(" PHY reg: 0x%x\n", mii.phyReg); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved4); p@2550: pr_debug(" PHY write: 0x%x\n", mii.phyWriteData); p@2550: pr_debug(" PHY read: 0x%x\n", mii.phyReadData); p@2550: pr_debug(" MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n", p@2550: mii.macAddr.b[0], mii.macAddr.b[1], mii.macAddr.b[2], p@2550: mii.macAddr.b[3], mii.macAddr.b[4], mii.macAddr.b[5]); p@2550: pr_debug(" MAC filter enable: %s\n", p@2550: mii.macFilterEnabled ? "enabled" : "disabled"); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved6); p@2550: pr_debug(" Link State: %s\n", p@2550: mii.linkStatus ? "link" : "no link"); p@2550: pr_debug(" reserved: 0x%x\n", mii.reserved7); p@2550: //pr_debug(" reserved: 0x%x\n", DRV_NAME, mii.reserved8); p@2550: //TODO add leds, systemtime insertion and interrupts p@2550: } p@2550: p@2550: void ccat_print_function_info(struct ccat_eth_priv *priv) p@2550: { p@2550: print_CCatInfoBlock(&priv->info, priv->ccatdev->bar[0].ioaddr); p@2550: print_CCatMii(priv); p@2550: print_CCatDmaTxFifo(priv); p@2550: print_CCatDmaRxActBuf(priv); p@2550: print_CCatMacRegs(priv); p@2550: pr_debug(" RX window: %p\n", priv->reg.rx_mem); p@2550: pr_debug(" TX memory: %p\n", priv->reg.tx_mem); p@2550: pr_debug(" misc: %p\n", priv->reg.misc); p@2550: } p@2550: p@2550: void print_update_info(const CCatInfoBlock * const info, p@2550: void __iomem * const ioaddr) p@2550: { p@2550: const size_t index = min((int)info->eCCatInfoType, CCATINFO_MAX); p@2550: pr_debug("%s\n", CCatFunctionTypes[index]); p@2550: pr_debug(" revision: 0x%x\n", info->nRevision); p@2550: pr_debug(" baseaddr: 0x%x\n", info->nAddr); p@2550: pr_debug(" size: 0x%x\n", info->nSize); p@2550: pr_debug(" PROM ID is: 0x%x\n", ccat_get_prom_id(ioaddr)); p@2550: }