From 847b347e065cd77e0ac8d2b07b2b6e69ce9ddebf Mon Sep 17 00:00:00 2001 From: Wentao Guan Date: Tue, 5 Nov 2024 22:23:03 +0800 Subject: [PATCH] ethernet: release motorcomm yt6801 v1.0.29 Signed-off-by: Wentao Guan --- .../net/ethernet/motorcomm/yt6801/Makefile | 2 +- .../ethernet/motorcomm/yt6801/fuxi-efuse.c | 188 ++-- .../ethernet/motorcomm/yt6801/fuxi-efuse.h | 12 +- .../ethernet/motorcomm/yt6801/fuxi-errno.h | 163 ++++ .../motorcomm/yt6801/fuxi-gmac-common.c | 32 +- .../motorcomm/yt6801/fuxi-gmac-debugfs.c | 801 ------------------ .../motorcomm/yt6801/fuxi-gmac-desc.c | 163 +++- .../motorcomm/yt6801/fuxi-gmac-ethtool.c | 91 +- .../ethernet/motorcomm/yt6801/fuxi-gmac-hw.c | 573 +++++++++---- .../motorcomm/yt6801/fuxi-gmac-ioctl.c | 521 ++++++++++++ .../ethernet/motorcomm/yt6801/fuxi-gmac-net.c | 447 ++++------ .../ethernet/motorcomm/yt6801/fuxi-gmac-pci.c | 17 +- .../ethernet/motorcomm/yt6801/fuxi-gmac-phy.c | 153 +++- .../ethernet/motorcomm/yt6801/fuxi-gmac-reg.h | 258 ++++-- .../net/ethernet/motorcomm/yt6801/fuxi-gmac.h | 143 ++-- .../net/ethernet/motorcomm/yt6801/fuxi-os.h | 162 ++-- 16 files changed, 2039 insertions(+), 1687 deletions(-) create mode 100644 drivers/net/ethernet/motorcomm/yt6801/fuxi-errno.h delete mode 100644 drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-debugfs.c create mode 100644 drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ioctl.c diff --git a/drivers/net/ethernet/motorcomm/yt6801/Makefile b/drivers/net/ethernet/motorcomm/yt6801/Makefile index 93b5c4510eb05..904db987b7cee 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/Makefile +++ b/drivers/net/ethernet/motorcomm/yt6801/Makefile @@ -12,4 +12,4 @@ yt6801-objs := fuxi-gmac-common.o \ fuxi-gmac-pci.o \ fuxi-gmac-phy.o \ fuxi-efuse.o \ - fuxi-gmac-debugfs.o + fuxi-gmac-ioctl.o diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.c index fa85188355e82..56cb77d2b453a 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.c @@ -7,13 +7,13 @@ /* read patch per index. */ bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata *pdata, - u8 index, u32 *offset, u32 *value) + u8 index, u32 __far *offset, u32 __far *value) { unsigned int wait, i; u32 regval = 0; bool succeed = false; - if (index >= FUXI_EFUSE_MAX_ENTRY) { + if (index >= FXGMAC_EFUSE_MAX_ENTRY) { FXGMAC_PR("Reading efuse out of range, index %d\n", index); return false; } @@ -105,6 +105,95 @@ bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata *pdata, return succeed; } + +bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata *pdata, u8 *mac_addr, + u32 *subsys, u32 *revid) +{ + u32 offset = 0, value = 0; + u32 machr = 0, maclr = 0; + bool succeed = true; + u8 index = 0; + + for (index = 0;; index++) { + if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, + &offset, &value)) { + succeed = false; + break; /* reach the last item. */ + } + if (0x00 == offset) { + break; /* reach the blank. */ + } + if (MACA0LR_FROM_EFUSE == offset) { + maclr = value; + } + if (MACA0HR_FROM_EFUSE == offset) { + machr = value; + } + + if ((0x08 == offset) && revid) { + *revid = value; + } + if ((0x2C == offset) && subsys) { + *subsys = value; + } + } + if (mac_addr) { + mac_addr[5] = (u8)(maclr & 0xFF); + mac_addr[4] = (u8)((maclr >> 8) & 0xFF); + mac_addr[3] = (u8)((maclr >> 16) & 0xFF); + mac_addr[2] = (u8)((maclr >> 24) & 0xFF); + mac_addr[1] = (u8)(machr & 0xFF); + mac_addr[0] = (u8)((machr >> 8) & 0xFF); + } + + return succeed; +} + + +bool fxgmac_efuse_read_data(struct fxgmac_pdata *pdata, u32 offset, u32 __far *value) +{ + bool succeed = false; + unsigned int wait; + u32 reg_val = 0; + + if (value) { + *value = 0; + } + + reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, + EFUSE_OP_ADDR_LEN, offset); + reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, + EFUSE_OP_START_LEN, 1); + reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, + EFUSE_OP_MODE_LEN, + EFUSE_OP_MODE_ROW_READ); + writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0); + wait = 1000; + while (wait--) { + usleep_range_ex(pdata->pAdapter, 20, 50); + reg_val = readreg(pdata->pAdapter, + pdata->base_mem + EFUSE_OP_CTRL_1); + if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, + EFUSE_OP_DONE_LEN)) { + succeed = true; + break; + } + } + + if (succeed) { + if (value) { + *value = FXGMAC_GET_REG_BITS(reg_val, + EFUSE_OP_RD_DATA_POS, + EFUSE_OP_RD_DATA_LEN); + } + } else { + FXGMAC_PR("Fail to reading efuse Byte%d\n", offset); + } + + return succeed; +} + +#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE bool fxgmac_read_patch_from_efuse(struct fxgmac_pdata *pdata, u32 offset, u32 *value) /* read patch per index. */ { @@ -120,7 +209,7 @@ bool fxgmac_read_patch_from_efuse(struct fxgmac_pdata *pdata, u32 offset, return false; } - for (index = 0; index < FUXI_EFUSE_MAX_ENTRY; index++) { + for (index = 0; index < FXGMAC_EFUSE_MAX_ENTRY; index++) { if (!fxgmac_read_patch_from_efuse_per_index( pdata, index, ®_offset, ®_val)) { succeed = false; @@ -146,7 +235,7 @@ bool fxgmac_write_patch_to_efuse_per_index(struct fxgmac_pdata *pdata, u8 index, u32 reg_val; bool succeed = false; u32 cur_reg, cur_val; - u8 max_index = FUXI_EFUSE_MAX_ENTRY; + u8 max_index = FXGMAC_EFUSE_MAX_ENTRY; if (offset >> 16) { FXGMAC_PR( @@ -157,7 +246,7 @@ bool fxgmac_write_patch_to_efuse_per_index(struct fxgmac_pdata *pdata, u8 index, fxgmac_efuse_read_data(pdata, EFUSE_LED_ADDR, ®_val); if (EFUSE_LED_COMMON_SOLUTION == reg_val) { - max_index = FUXI_EFUSE_MAX_ENTRY_UNDER_LED_COMMON; + max_index = FXGMAC_EFUSE_MAX_ENTRY_UNDER_LED_COMMON; } if (index >= max_index) { @@ -370,49 +459,6 @@ bool fxgmac_write_patch_to_efuse(struct fxgmac_pdata *pdata, u32 offset, return succeed; } -bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata *pdata, u8 *mac_addr, - u32 *subsys, u32 *revid) -{ - u32 offset = 0, value = 0; - u32 machr = 0, maclr = 0; - bool succeed = true; - u8 index = 0; - - for (index = 0;; index++) { - if (!fxgmac_read_patch_from_efuse_per_index(pdata, index, - &offset, &value)) { - succeed = false; - break; /* reach the last item. */ - } - if (0x00 == offset) { - break; /* reach the blank. */ - } - if (MACA0LR_FROM_EFUSE == offset) { - maclr = value; - } - if (MACA0HR_FROM_EFUSE == offset) { - machr = value; - } - - if ((0x08 == offset) && revid) { - *revid = value; - } - if ((0x2C == offset) && subsys) { - *subsys = value; - } - } - if (mac_addr) { - mac_addr[5] = (u8)(maclr & 0xFF); - mac_addr[4] = (u8)((maclr >> 8) & 0xFF); - mac_addr[3] = (u8)((maclr >> 16) & 0xFF); - mac_addr[2] = (u8)((maclr >> 24) & 0xFF); - mac_addr[1] = (u8)(machr & 0xFF); - mac_addr[0] = (u8)((machr >> 8) & 0xFF); - } - - return succeed; -} - bool fxgmac_write_mac_subsys_to_efuse(struct fxgmac_pdata *pdata, u8 *mac_addr, u32 *subsys, u32 *revid) { @@ -592,49 +638,6 @@ bool fxgmac_efuse_load(struct fxgmac_pdata *pdata) return succeed; } -bool fxgmac_efuse_read_data(struct fxgmac_pdata *pdata, u32 offset, u32 *value) -{ - bool succeed = false; - unsigned int wait; - u32 reg_val = 0; - - if (value) { - *value = 0; - } - - reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_ADDR_POS, - EFUSE_OP_ADDR_LEN, offset); - reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_START_POS, - EFUSE_OP_START_LEN, 1); - reg_val = FXGMAC_SET_REG_BITS(reg_val, EFUSE_OP_MODE_POS, - EFUSE_OP_MODE_LEN, - EFUSE_OP_MODE_ROW_READ); - writereg(pdata->pAdapter, reg_val, pdata->base_mem + EFUSE_OP_CTRL_0); - wait = 1000; - while (wait--) { - usleep_range_ex(pdata->pAdapter, 20, 50); - reg_val = readreg(pdata->pAdapter, - pdata->base_mem + EFUSE_OP_CTRL_1); - if (FXGMAC_GET_REG_BITS(reg_val, EFUSE_OP_DONE_POS, - EFUSE_OP_DONE_LEN)) { - succeed = true; - break; - } - } - - if (succeed) { - if (value) { - *value = FXGMAC_GET_REG_BITS(reg_val, - EFUSE_OP_RD_DATA_POS, - EFUSE_OP_RD_DATA_LEN); - } - } else { - FXGMAC_PR("Fail to reading efuse Byte%d\n", offset); - } - - return succeed; -} - bool fxgmac_efuse_write_oob(struct fxgmac_pdata *pdata) { bool succeed = false; @@ -1348,4 +1351,5 @@ bool fxgmac_read_led_setting_from_efuse(struct fxgmac_pdata *pdata) } return bsucceed; -} \ No newline at end of file +} +#endif diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.h b/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.h index fa0446958719c..cc99ac0baa2da 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.h +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-efuse.h @@ -1,12 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#ifndef __FUXI_EFUSE_H__ -#define __FUXI_EFUSE_H__ +#ifndef __FXGMAC_EFUSE_H__ +#define __FXGMAC_EFUSE_H__ +bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata *pdata, u8 index, u32 __far *offset, u32 __far *value); /* read patch per 0-based index. */ +bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata *pdata, u8 *mac_addr, u32 *subsys, u32 *revid); +bool fxgmac_efuse_read_data(struct fxgmac_pdata *pdata, u32 offset, u32 __far *value); +#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE bool fxgmac_read_patch_from_efuse(struct fxgmac_pdata *pdata, u32 offset, u32 *value); /* read patch per register offset. */ -bool fxgmac_read_patch_from_efuse_per_index(struct fxgmac_pdata *pdata, u8 index, u32 *offset, u32 *value); /* read patch per 0-based index. */ bool fxgmac_write_patch_to_efuse(struct fxgmac_pdata *pdata, u32 offset, u32 value); bool fxgmac_write_patch_to_efuse_per_index(struct fxgmac_pdata *pdata, u8 index, u32 offset, u32 value); bool fxgmac_read_mac_subsys_from_efuse(struct fxgmac_pdata *pdata, u8 *mac_addr, u32 *subsys, u32 *revid); @@ -21,5 +24,6 @@ bool fxgmac_efuse_write_oob(struct fxgmac_pdata *pdata); bool fxgmac_efuse_write_led(struct fxgmac_pdata *pdata, u32 value); bool fxgmac_read_led_setting_from_efuse(struct fxgmac_pdata *pdata); bool fxgmac_write_led_setting_to_efuse(struct fxgmac_pdata *pdata); +#endif -#endif /* __FUXI_EFUSE_H__ */ \ No newline at end of file +#endif /* __FXGMAC_EFUSE_H__ */ \ No newline at end of file diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-errno.h b/drivers/net/ethernet/motorcomm/yt6801/fuxi-errno.h new file mode 100644 index 0000000000000..ec085e366af3b --- /dev/null +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-errno.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2021 Motorcomm Corporation. */ + +#ifndef __FXGMAC_ERROR_H__ +#define __FXGMAC_ERROR_H__ + +#define EOK 0 + +/* ref linux https://elixir.bootlin.com/linux/v5.18-rc7/source/include/uapi/asm-generic/errno.h#L93 */ +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + + + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ + +/* + * This error code is special: arch syscall entry code will return + * -ENOSYS if users try to call a syscall that doesn't exist. To keep + * failures of syscalls that really do exist distinguishable from + * failures due to attempts to use a nonexistent syscall, syscall + * implementations should refrain from returning -ENOSYS. + */ +#define ENOSYS 38 /* Invalid system call number */ + +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#define ERFKILL 132 /* Operation not possible due to RF-kill */ + +#define EHWPOISON 133 /* Memory page has hardware error */ + +#endif // __FXGMAC_ERROR_H__ \ No newline at end of file diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-common.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-common.c index 5ca25a0e39ff2..9eeae95d13759 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-common.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-common.c @@ -1,14 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#include -#include - -#include "fuxi-os.h" #include "fuxi-gmac.h" #include "fuxi-gmac-reg.h" -MODULE_LICENSE("Dual BSD/GPL"); +MODULE_LICENSE("GPL"); static int debug = 16; module_param(debug, int, 0644); @@ -50,7 +46,7 @@ static void fxgmac_default_config(struct fxgmac_pdata *pdata) pdata->rss = 0; #endif /* open interrupt moderation default */ - pdata->intr_mod = 1; + pdata->intr_mod = FXGMAC_INT_MODERATION_ENABLED; pdata->crc_check = 1; /* set based on phy status. pdata->phy_speed = SPEED_1000; */ @@ -59,6 +55,9 @@ static void fxgmac_default_config(struct fxgmac_pdata *pdata) pdata->phy_duplex = DUPLEX_FULL; pdata->expansion.phy_link = false; pdata->phy_speed = SPEED_1000; + pdata->expansion.pre_phy_speed = pdata->phy_speed; + pdata->expansion.pre_phy_duplex = pdata->phy_duplex; + pdata->expansion.pre_phy_autoneg = pdata->phy_autoeng; /* default to magic */ pdata->expansion.wol = WAKE_MAGIC; @@ -112,7 +111,7 @@ int fxgmac_init(struct fxgmac_pdata *pdata, bool save_private_reg) /* Set the DMA mask */ #ifdef CONFIG_ARM64 - dma_width = FUXI_DMA_BIT_MASK; + dma_width = FXGMAC_DMA_BIT_MASK; #else dma_width = pdata->hw_feat.dma_width; #endif @@ -196,7 +195,7 @@ int fxgmac_init(struct fxgmac_pdata *pdata, bool save_private_reg) hw_ops->get_rss_hash_key(pdata, (u8 *)pdata->rss_key); #endif -#if FXGMAC_MSIX_CH0RXDIS_EN +#if FXGMAC_MSIX_CH0RXDIS_ENABLED for (i = 0; i < FXGMAC_RSS_MAX_TABLE_SIZE; i++) { pdata->rss_table[i] = FXGMAC_SET_REG_BITS( pdata->rss_table[i], MAC_RSSDR_DMCH_POS, @@ -288,7 +287,7 @@ int fxgmac_init(struct fxgmac_pdata *pdata, bool save_private_reg) /* Use default watchdog timeout */ netdev->watchdog_timeo = msecs_to_jiffies(5000); /* refer to sunxi-gmac, 5s */ - netdev->gso_max_size = NIC_MAX_TCP_OFFLOAD_SIZE; + netif_set_tso_max_size(netdev, NIC_MAX_TCP_OFFLOAD_SIZE); /* Tx coalesce parameters initialization */ pdata->tx_usecs = FXGMAC_INIT_DMA_TX_USECS; @@ -317,7 +316,7 @@ static void fxgmac_init_interrupt_scheme(struct fxgmac_pdata *pdata) */ vectors = num_online_cpus(); if (vectors >= FXGMAC_MAX_DMA_CHANNELS) { - /* 0-3 for rx, 4 for tx, 5 for phy */ + /* 0-3 for rx, 4 for tx, 5 for misc */ req_vectors = FXGMAC_MSIX_INT_NUMS; pdata->expansion.msix_entries = kcalloc( req_vectors, sizeof(struct msix_entry), GFP_KERNEL); @@ -426,7 +425,7 @@ int fxgmac_drv_probe(struct device *dev, struct fxgmac_resources *res) pdata->mac_regs = res->addr; pdata->base_mem = res->addr; - pdata->mac_regs = pdata->mac_regs + FUXI_MAC_REGS_OFFSET; + pdata->mac_regs = pdata->mac_regs + FXGMAC_MAC_REGS_OFFSET; ret = fxgmac_init(pdata, true); if (ret) { @@ -446,11 +445,6 @@ int fxgmac_drv_probe(struct device *dev, struct fxgmac_resources *res) DPRINTK("fxgamc_drv_prob callout, netdev num_tx_q=%u\n", netdev->real_num_tx_queues); -#ifdef HAVE_FXGMAC_DEBUG_FS - fxgmac_dbg_init(pdata); - fxgmac_dbg_adapter_init(pdata); -#endif /* HAVE_FXGMAC_DEBUG_FS */ - return 0; err_free_netdev: @@ -466,9 +460,6 @@ int fxgmac_drv_remove(struct device *dev) struct fxgmac_pdata *pdata = netdev_priv(netdev); struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; -#ifdef HAVE_FXGMAC_DEBUG_FS - fxgmac_dbg_adapter_exit(pdata); -#endif /*HAVE_FXGMAC_DEBUG_FS */ hw_ops->led_under_shutdown(pdata); unregister_netdev(netdev); @@ -576,8 +567,7 @@ void fxgmac_get_all_hw_features(struct fxgmac_pdata *pdata) hw_feat->version = readl(pdata->mac_regs + MAC_VR); if (netif_msg_drv(pdata)) - DPRINTK("get offset 0x110, ver=%#x\n", - readl(pdata->mac_regs + 0x110)); + DPRINTK("Mac ver=%#x\n", hw_feat->version); /* Hardware feature register 0 */ hw_feat->phyifsel = FXGMAC_GET_REG_BITS( diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-debugfs.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-debugfs.c deleted file mode 100644 index 0d7fd5a174113..0000000000000 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-debugfs.c +++ /dev/null @@ -1,801 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2021 Motorcomm Corporation. */ - -#include "fuxi-gmac.h" -#include "fuxi-gmac-reg.h" -#ifdef HAVE_FXGMAC_DEBUG_FS -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEST_MAC_HEAD 14 -#define TEST_TCP_HEAD_LEN_OFFSET 12 -#define TEST_TCP_OFFLOAD_LEN_OFFSET 48 -#define TEST_TCP_FIX_HEAD_LEN 24 -#define TEST_TCP_MSS_OFFSET 56 - -#define DF_MAX_NIC_NUM 16 - -#ifdef HAVE_FXGMAC_DEBUG_FS - -/** - * fxgmac_dbg_netdev_ops_read - read for netdev_ops datum - * @filp: the opened file - * @buffer: where to write the data for the user to read - * @count: the size of the user's buffer - * @ppos: file position offset - **/ -static ssize_t fxgmac_dbg_netdev_ops_read(struct file *filp, - char __user *buffer, size_t count, - loff_t *ppos) -{ - struct fxgmac_pdata *pdata = filp->private_data; - char *buf; - int len; - - /* don't allow partial reads */ - if (*ppos != 0) - return 0; - - buf = kasprintf(GFP_KERNEL, "%s: %s\n", pdata->netdev->name, - pdata->expansion.fxgmac_dbg_netdev_ops_buf); - if (!buf) - return -ENOMEM; - - if (count < strlen(buf)) { - kfree(buf); - return -ENOSPC; - } - - len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); - - kfree(buf); - return len; -} - -/** - * fxgmac_dbg_netdev_ops_write - write into netdev_ops datum - * @filp: the opened file - * @buffer: where to find the user's data - * @count: the length of the user's data - * @ppos: file position offset - **/ -static ssize_t fxgmac_dbg_netdev_ops_write(struct file *filp, - const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct fxgmac_pdata *pdata = filp->private_data; - int len; - - /* don't allow partial writes */ - if (*ppos != 0) - return 0; - if (count >= sizeof(pdata->expansion.fxgmac_dbg_netdev_ops_buf)) - return -ENOSPC; - - len = simple_write_to_buffer( - pdata->expansion.fxgmac_dbg_netdev_ops_buf, - sizeof(pdata->expansion.fxgmac_dbg_netdev_ops_buf) - 1, ppos, - buffer, count); - if (len < 0) - return len; - - pdata->expansion.fxgmac_dbg_netdev_ops_buf[len] = '\0'; - - if (strncmp(pdata->expansion.fxgmac_dbg_netdev_ops_buf, "tx_timeout", - 10) == 0) { - DPRINTK("tx_timeout called\n"); - } else { - FXGMAC_PR("Unknown command: %s\n", - pdata->expansion.fxgmac_dbg_netdev_ops_buf); - FXGMAC_PR("Available commands:\n"); - FXGMAC_PR(" tx_timeout\n"); - } - return count; -} -#endif - -static void fxgmac_dbg_tx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data) -{ - unsigned int pktLen = 0; - struct sk_buff *skb; - pfxgmac_test_packet pPkt; - u8 *pTx_data = NULL; - u8 *pSkb_data = NULL; - u32 offload_len = 0; - u8 ipHeadLen, tcpHeadLen, headTotalLen; - static u32 lastGsoSize = 806; /* initial default value */ - - /* get fxgmac_test_packet */ - pPkt = (pfxgmac_test_packet)(pcmd_data + sizeof(struct ext_ioctl_data)); - pktLen = pPkt->length; - - /* get pkt data */ - pTx_data = (u8 *)pPkt + sizeof(fxgmac_test_packet); - - /* alloc sk_buff */ - skb = alloc_skb(pktLen, GFP_ATOMIC); - if (!skb) { - DPRINTK("alloc skb fail\n"); - return; - } - - /* copy data to skb */ - pSkb_data = skb_put(skb, pktLen); - memset(pSkb_data, 0, pktLen); - memcpy(pSkb_data, pTx_data, pktLen); - - /* set skb parameters */ - skb->dev = pdata->netdev; - skb->pkt_type = PACKET_OUTGOING; - skb->protocol = ntohs(ETH_P_IP); - skb->no_fcs = 1; - skb->ip_summed = CHECKSUM_PARTIAL; - if (skb->len > 1514) { - /* TSO packet */ - /* set tso test flag */ - pdata->expansion.fxgmac_test_tso_flag = true; - - /* get protocol head length */ - ipHeadLen = (pSkb_data[TEST_MAC_HEAD] & 0xF) * 4; - tcpHeadLen = (pSkb_data[TEST_MAC_HEAD + ipHeadLen + - TEST_TCP_HEAD_LEN_OFFSET] >> - 4 & - 0xF) * - 4; - headTotalLen = TEST_MAC_HEAD + ipHeadLen + tcpHeadLen; - offload_len = (pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET] << 8 | - pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET + 1]) & - 0xFFFF; - /* set tso skb parameters */ - skb->transport_header = ipHeadLen + TEST_MAC_HEAD; - skb->network_header = TEST_MAC_HEAD; - skb->inner_network_header = TEST_MAC_HEAD; - skb->mac_len = TEST_MAC_HEAD; - - /* set skb_shinfo parameters */ - if (tcpHeadLen > TEST_TCP_FIX_HEAD_LEN) { - skb_shinfo(skb)->gso_size = - (pSkb_data[TEST_TCP_MSS_OFFSET] << 8 | - pSkb_data[TEST_TCP_MSS_OFFSET + 1]) & - 0xFFFF; - } else { - skb_shinfo(skb)->gso_size = 0; - } - if (skb_shinfo(skb)->gso_size != 0) { - lastGsoSize = skb_shinfo(skb)->gso_size; - } else { - skb_shinfo(skb)->gso_size = lastGsoSize; - } - /* get segment size */ - if (offload_len % skb_shinfo(skb)->gso_size == 0) { - skb_shinfo(skb)->gso_segs = - offload_len / skb_shinfo(skb)->gso_size; - pdata->expansion.fxgmac_test_last_tso_len = - skb_shinfo(skb)->gso_size + headTotalLen; - } else { - skb_shinfo(skb)->gso_segs = - offload_len / skb_shinfo(skb)->gso_size + 1; - pdata->expansion.fxgmac_test_last_tso_len = - offload_len % skb_shinfo(skb)->gso_size + - headTotalLen; - } - pdata->expansion.fxgmac_test_tso_seg_num = - skb_shinfo(skb)->gso_segs; - - skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; - skb_shinfo(skb)->frag_list = NULL; - skb->csum_start = skb_headroom(skb) + TEST_MAC_HEAD + ipHeadLen; - skb->csum_offset = skb->len - TEST_MAC_HEAD - ipHeadLen; - - pdata->expansion.fxgmac_test_packet_len = - skb_shinfo(skb)->gso_size + headTotalLen; - } else { - /* set non-TSO packet parameters */ - pdata->expansion.fxgmac_test_packet_len = skb->len; - } - - /* send data */ - if (dev_queue_xmit(skb) != NET_XMIT_SUCCESS) { - DPRINTK("xmit data fail \n"); - } -} - -static void fxgmac_dbg_rx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data) -{ - unsigned int totalLen = 0; - struct sk_buff *rx_skb; - struct ext_ioctl_data *pcmd; - fxgmac_test_packet pkt; - void *addr = 0; - u8 *rx_data = (u8 *)kzalloc(FXGMAC_MAX_DBG_RX_DATA, GFP_KERNEL); - if (!rx_data) - return; - - /* initial dest data region */ - pcmd = (struct ext_ioctl_data *)pcmd_data; - addr = pcmd->cmd_buf.buf; - while (pdata->expansion.fxgmac_test_skb_arr_in_index != - pdata->expansion.fxgmac_test_skb_arr_out_index) { - /* get received skb data */ - rx_skb = - pdata->expansion.fxgmac_test_skb_array - [pdata->expansion.fxgmac_test_skb_arr_out_index]; - - if (rx_skb->len + sizeof(fxgmac_test_packet) + totalLen < - 64000) { - pkt.length = rx_skb->len; - pkt.type = 0x80; - pkt.buf[0].offset = - totalLen + sizeof(fxgmac_test_packet); - pkt.buf[0].length = rx_skb->len; - - /* get data from skb */ - memcpy(rx_data, rx_skb->data, rx_skb->len); - - /* update next pointer */ - if ((pdata->expansion.fxgmac_test_skb_arr_out_index + - 1) % FXGMAC_MAX_DBG_TEST_PKT == - pdata->expansion.fxgmac_test_skb_arr_in_index) { - pkt.next = NULL; - } else { - pkt.next = - (pfxgmac_test_packet)(addr + totalLen + - sizeof(fxgmac_test_packet) + - pkt.length); - } - - /* copy data to user space */ - if (copy_to_user((void *)(addr + totalLen), - (void *)(&pkt), - sizeof(fxgmac_test_packet))) { - DPRINTK("cppy pkt data to user fail..."); - } - if (copy_to_user((void *)(addr + totalLen + - sizeof(fxgmac_test_packet)), - (void *)rx_data, rx_skb->len)) { - DPRINTK("cppy data to user fail..."); - } - - /* update total length */ - totalLen += (sizeof(fxgmac_test_packet) + rx_skb->len); - - /* free skb */ - kfree_skb(rx_skb); - pdata->expansion.fxgmac_test_skb_array - [pdata->expansion.fxgmac_test_skb_arr_out_index] = - NULL; - - /* update gCurSkbOutIndex */ - pdata->expansion.fxgmac_test_skb_arr_out_index = - (pdata->expansion.fxgmac_test_skb_arr_out_index + - 1) % - FXGMAC_MAX_DBG_TEST_PKT; - } else { - DPRINTK("receive data more receive buffer... \n"); - break; - } - } - - if (rx_data) - kfree(rx_data); -} - -/* Based on the current application scenario, we only use CMD_DATA for data. - * if you use other struct, you should recalculate in_total_size - */ -long fxgmac_dbg_netdev_ops_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - bool ret = true; - int regval = 0; - struct fxgmac_pdata *pdata = file->private_data; - struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; - FXGMAC_PDATA_OF_PLATFORM *ex = &pdata->expansion; - CMD_DATA ex_data; - struct ext_ioctl_data pcmd; - u8 *data = NULL; - u8 *buf = NULL; - int in_total_size, in_data_size, out_total_size; - int ioctl_cmd_size = sizeof(struct ext_ioctl_data); - u8 mac[ETH_ALEN] = { 0 }; - struct sk_buff *tmpskb; - - if (!arg) { - DPRINTK("[%s] command arg is %lx !\n", __func__, arg); - goto err; - } - - /* check device type */ - if (_IOC_TYPE(cmd) != IOC_MAGIC) { - DPRINTK("[%s] command type [%c] error!\n", __func__, - _IOC_TYPE(cmd)); - goto err; - } - - /* check command number*/ - if (_IOC_NR(cmd) > IOC_MAXNR) { - DPRINTK("[%s] command numer [%d] exceeded!\n", __func__, - _IOC_NR(cmd)); - goto err; - } - - if (copy_from_user(&pcmd, (void *)arg, ioctl_cmd_size)) { - DPRINTK("copy data from user fail... \n"); - goto err; - } - - in_total_size = pcmd.cmd_buf.size_in; - in_data_size = in_total_size - ioctl_cmd_size; - out_total_size = pcmd.cmd_buf.size_out; - - buf = (u8 *)kzalloc(in_total_size, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, (void *)arg, in_total_size)) { - DPRINTK("copy data from user fail... \n"); - goto err; - } - data = buf + ioctl_cmd_size; - - if (arg != 0) { - switch (pcmd.cmd_type) { - /* ioctl diag begin */ - case FUXI_DFS_IOCTL_DIAG_BEGIN: - DPRINTK("Debugfs received diag begin command.\n"); - if (netif_running(pdata->netdev)) { - fxgmac_restart_dev(pdata); - } - - /* release last loopback test abnormal exit buffer */ - while (ex->fxgmac_test_skb_arr_in_index != - ex->fxgmac_test_skb_arr_out_index) { - tmpskb = - ex->fxgmac_test_skb_array - [ex->fxgmac_test_skb_arr_out_index]; - if (tmpskb) { - kfree_skb(tmpskb); - ex->fxgmac_test_skb_array - [ex->fxgmac_test_skb_arr_out_index] = - NULL; - } - - ex->fxgmac_test_skb_arr_out_index = - (ex->fxgmac_test_skb_arr_out_index + - 1) % - FXGMAC_MAX_DBG_TEST_PKT; - } - - /* init loopback test parameters */ - ex->fxgmac_test_skb_arr_in_index = 0; - ex->fxgmac_test_skb_arr_out_index = 0; - ex->fxgmac_test_tso_flag = false; - ex->fxgmac_test_tso_seg_num = 0; - ex->fxgmac_test_last_tso_len = 0; - ex->fxgmac_test_packet_len = 0; - break; - - /* ioctl diag end */ - case FUXI_DFS_IOCTL_DIAG_END: - DPRINTK("Debugfs received diag end command.\n"); - if (netif_running(pdata->netdev)) { - fxgmac_restart_dev(pdata); - } - break; - - /* ioctl diag tx pkt */ - case FUXI_DFS_IOCTL_DIAG_TX_PKT: - fxgmac_dbg_tx_pkt(pdata, buf); - break; - - /* ioctl diag rx pkt */ - case FUXI_DFS_IOCTL_DIAG_RX_PKT: - fxgmac_dbg_rx_pkt(pdata, buf); - break; - - /* ioctl device reset */ - case FUXI_DFS_IOCTL_DEVICE_RESET: - DPRINTK("Debugfs received device reset command.\n"); - if (netif_running(pdata->netdev)) { - fxgmac_restart_dev(pdata); - } - break; - - case FXGMAC_EFUSE_LED_TEST: - DPRINTK("Debugfs received device led test command.\n"); - memcpy(&pdata->led, data, sizeof(struct led_setting)); - fxgmac_restart_dev(pdata); - break; - - case FXGMAC_EFUSE_UPDATE_LED_CFG: - DPRINTK("Debugfs received device led update command.\n"); - memcpy(&pdata->ledconfig, data, - sizeof(struct led_setting)); - ret = hw_ops->write_led_config(pdata); - hw_ops->read_led_config(pdata); - hw_ops->led_under_active(pdata); - break; - - case FXGMAC_EFUSE_WRITE_LED: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - DPRINTK("FXGMAC_EFUSE_WRITE_LED, val = 0x%x\n", - ex_data.val0); - ret = hw_ops->write_led(pdata, ex_data.val0); - break; - - case FXGMAC_EFUSE_WRITE_OOB: - DPRINTK("FXGMAC_EFUSE_WRITE_OOB.\n"); - ret = hw_ops->write_oob(pdata); - break; - - case FXGMAC_EFUSE_READ_REGIONABC: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->read_efuse_data(pdata, ex_data.val0, - &ex_data.val1); - /* - * DPRINTK("FXGMAC_EFUSE_READ_REGIONABC, address = 0x%x, val = 0x%x\n", - * ex_data.val0, - * ex_data.val1); - */ - if (ret) { - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = - ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - break; - - case FXGMAC_EFUSE_WRITE_PATCH_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - /* - * DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_REG, address = 0x%x, val = 0x%x\n", - * ex_data.val0, - * ex_data.val1); - */ - ret = hw_ops->write_patch_to_efuse(pdata, ex_data.val0, - ex_data.val1); - break; - - case FXGMAC_EFUSE_READ_PATCH_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->read_patch_from_efuse(pdata, ex_data.val0, - &ex_data.val1); - /* - * DPRINTK("FXGMAC_EFUSE_READ_PATCH_REG, address = 0x%x, val = 0x%x\n", - * ex_data.val0, ex_data.val1); - */ - if (ret) { - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = - ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - break; - - case FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->write_patch_to_efuse_per_index( - pdata, ex_data.val0, ex_data.val1, - ex_data.val2); - /* - * DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX, index = %d, address = 0x%x, val = 0x%x\n", - * ex_data.val0, ex_data.val1, ex_data.val2); - */ - break; - - case FXGMAC_EFUSE_READ_PATCH_PER_INDEX: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->read_patch_from_efuse_per_index( - pdata, ex_data.val0, &ex_data.val1, - &ex_data.val2); - /* - * DPRINTK("FXGMAC_EFUSE_READ_PATCH_PER_INDEX, address = 0x%x, val = 0x%x\n", - * ex_data.val1, ex_data.val2); - */ - if (ret) { - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = - ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - break; - - case FXGMAC_EFUSE_LOAD: - DPRINTK("FXGMAC_EFUSE_LOAD.\n"); - ret = hw_ops->efuse_load(pdata); - break; - - case FXGMAC_GET_MAC_DATA: - ret = hw_ops->read_mac_subsys_from_efuse(pdata, mac, - NULL, NULL); - if (ret) { - memcpy(data, mac, ETH_ALEN); - out_total_size = ioctl_cmd_size + ETH_ALEN; - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - break; - - case FXGMAC_SET_MAC_DATA: - if (in_data_size != ETH_ALEN) - goto err; - memcpy(mac, data, ETH_ALEN); - ret = hw_ops->write_mac_subsys_to_efuse(pdata, mac, - NULL, NULL); - if (ret) { - eth_hw_addr_set(pdata->netdev, mac); - memcpy(pdata->mac_addr, mac, ETH_ALEN); - hw_ops->set_mac_address(pdata, mac); - hw_ops->set_mac_hash(pdata); - } - break; - - case FXGMAC_GET_SUBSYS_ID: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->read_mac_subsys_from_efuse( - pdata, NULL, &ex_data.val0, NULL); - if (ret) { - ex_data.val1 = 0xFFFF; /* invalid value */ - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = - ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - break; - - case FXGMAC_SET_SUBSYS_ID: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ret = hw_ops->write_mac_subsys_to_efuse( - pdata, NULL, &ex_data.val0, NULL); - break; - - case FXGMAC_GET_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - ex_data.val1 = hw_ops->get_gmac_register( - pdata, (u8 *)(pdata->mac_regs + ex_data.val0)); - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - break; - - case FXGMAC_SET_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - regval = hw_ops->set_gmac_register( - pdata, (u8 *)(pdata->mac_regs + ex_data.val0), - ex_data.val1); - ret = (regval == 0 ? true : false); - break; - - case FXGMAC_GET_PHY_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - regval = hw_ops->read_ephy_reg(pdata, ex_data.val0, - &ex_data.val1); - if (regval != -1) { - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = - ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - } - ret = (regval == -1 ? false : true); - break; - - case FXGMAC_SET_PHY_REG: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - regval = hw_ops->write_ephy_reg(pdata, ex_data.val0, - ex_data.val1); - ret = (regval == 0 ? true : false); - break; - - case FXGMAC_GET_PCIE_LOCATION: - ex_data.val0 = pdata->pdev->bus->number; - ex_data.val1 = PCI_SLOT(pdata->pdev->devfn); - ex_data.val2 = PCI_FUNC(pdata->pdev->devfn); - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - break; - - case FXGMAC_GET_GSO_SIZE: - ex_data.val0 = pdata->netdev->gso_max_size; - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - break; - - case FXGMAC_SET_GSO_SIZE: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - pdata->netdev->gso_max_size = ex_data.val0; - break; - - case FXGMAC_SET_RX_MODERATION: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - regval = readreg(pdata->pAdapter, - pdata->base_mem + INT_MOD); - regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_RX_POS, - INT_MOD_RX_LEN, - ex_data.val0); - writereg(pdata->pAdapter, regval, - pdata->base_mem + INT_MOD); - break; - - case FXGMAC_SET_TX_MODERATION: - memcpy(&ex_data, data, sizeof(CMD_DATA)); - regval = readreg(pdata->pAdapter, - pdata->base_mem + INT_MOD); - regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_TX_POS, - INT_MOD_TX_LEN, - ex_data.val0); - writereg(pdata->pAdapter, regval, - pdata->base_mem + INT_MOD); - break; - - case FXGMAC_GET_TXRX_MODERATION: - regval = readreg(pdata->pAdapter, - pdata->base_mem + INT_MOD); - ex_data.val0 = FXGMAC_GET_REG_BITS( - regval, INT_MOD_RX_POS, INT_MOD_RX_LEN); - ex_data.val1 = FXGMAC_GET_REG_BITS( - regval, INT_MOD_TX_POS, INT_MOD_TX_LEN); - memcpy(data, &ex_data, sizeof(CMD_DATA)); - out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); - if (copy_to_user((void *)arg, (void *)buf, - out_total_size)) - goto err; - break; - - default: - DPRINTK("Debugfs received invalid command: %x.\n", - pcmd.cmd_type); - ret = false; - break; - } - } - - if (buf) - kfree(buf); - return ret ? FXGMAC_SUCCESS : FXGMAC_FAIL; - -err: - if (buf) - kfree(buf); - return FXGMAC_FAIL; -} - -#ifdef HAVE_FXGMAC_DEBUG_FS - -static struct file_operations fxgmac_dbg_netdev_ops_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = fxgmac_dbg_netdev_ops_read, - .write = fxgmac_dbg_netdev_ops_write, - .unlocked_ioctl = fxgmac_dbg_netdev_ops_ioctl, -}; - -/** - * fxgmac_dbg_adapter_init - setup the debugfs directory for the adapter - * @pdata: board private structure - **/ -void fxgmac_dbg_adapter_init(struct fxgmac_pdata *pdata) -{ - const char *name = pdata->drv_name; - struct dentry *pfile; - - pdata->expansion.dbg_adapter = - debugfs_create_dir(name, pdata->expansion.fxgmac_dbg_root); - if (pdata->expansion.dbg_adapter) { - pfile = debugfs_create_file("netdev_ops", 0600, - pdata->expansion.dbg_adapter, pdata, - &fxgmac_dbg_netdev_ops_fops); - if (!pfile) - DPRINTK("debugfs netdev_ops for %s failed\n", name); - } else { - DPRINTK("debugfs entry for %s failed\n", name); - } -} - -/** - * fxgmac_dbg_adapter_exit - clear out the adapter's debugfs entries - * @pdata: board private structure - **/ -void fxgmac_dbg_adapter_exit(struct fxgmac_pdata *pdata) -{ - if (pdata->expansion.dbg_adapter) - debugfs_remove_recursive(pdata->expansion.dbg_adapter); - pdata->expansion.dbg_adapter = NULL; -} - -/** - * fxgmac_dbg_init - start up debugfs for the driver - * @pdata: board private structure - **/ -void fxgmac_dbg_init(struct fxgmac_pdata *pdata) -{ - unsigned int i; - char num[3]; - const char debug_path[] = "/sys/kernel/debug/"; - const char file_prefix[] = "fuxi_"; - char file_path[50]; - char file_name[8]; - - /* init file_path */ - memset(file_path, '\0', sizeof(file_path)); - memcpy(file_path, debug_path, sizeof(debug_path)); - - for (i = 0; i < DF_MAX_NIC_NUM; i++) { - /* init num and filename */ - memset(num, '\0', sizeof(num)); - memset(file_name, '\0', sizeof(file_name)); - - /* int to string */ - sprintf(num, "%d", i); - - /* file name */ - memcpy(file_name, file_prefix, sizeof(file_prefix)); - memcpy(file_name + strlen(file_prefix), num, sizeof(num)); - - /* file path */ - memcpy(file_path + sizeof(debug_path) - 1, file_name, - sizeof(file_name)); - - /* whether file exist */ - pdata->expansion.fxgmac_dbg_root = - debugfs_lookup(file_name, NULL); - if (!pdata->expansion.fxgmac_dbg_root) { - /* create file */ - pdata->expansion.fxgmac_dbg_root = - debugfs_create_dir(file_name, NULL); - if (IS_ERR(pdata->expansion.fxgmac_dbg_root)) - DPRINTK("fxgmac init of debugfs failed\n"); - - break; - } - } -} - -/** - * fxgmac_dbg_exit - clean out the driver's debugfs entries - * @pdata: board private structure - **/ -void fxgmac_dbg_exit(struct fxgmac_pdata *pdata) -{ - if (pdata->expansion.fxgmac_dbg_root) - debugfs_remove_recursive(pdata->expansion.fxgmac_dbg_root); -} - -#endif /* HAVE_XLGMAC_DEBUG_FS */ diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-desc.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-desc.c index d523e307820b5..933e91e1408dd 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-desc.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-desc.c @@ -19,17 +19,31 @@ static void fxgmac_unmap_desc_data(struct fxgmac_pdata *pdata, desc_data->skb_dma_len = 0; } - if (desc_data->rx.buf.dma_base) { - dma_unmap_single(pdata->dev, desc_data->rx.buf.dma_base, - pdata->rx_buf_size, DMA_FROM_DEVICE); - desc_data->rx.buf.dma_base = 0; - } - if (desc_data->skb) { dev_kfree_skb_any(desc_data->skb); desc_data->skb = NULL; } + if (desc_data->rx.hdr.pa.pages) + put_page(desc_data->rx.hdr.pa.pages); + + if (desc_data->rx.hdr.pa_unmap.pages) { + dma_unmap_page(pdata->dev, desc_data->rx.hdr.pa_unmap.pages_dma, + desc_data->rx.hdr.pa_unmap.pages_len, + DMA_FROM_DEVICE); + put_page(desc_data->rx.hdr.pa_unmap.pages); + } + + if (desc_data->rx.buf.pa.pages) + put_page(desc_data->rx.buf.pa.pages); + + if (desc_data->rx.buf.pa_unmap.pages) { + dma_unmap_page(pdata->dev, desc_data->rx.buf.pa_unmap.pages_dma, + desc_data->rx.buf.pa_unmap.pages_len, + DMA_FROM_DEVICE); + put_page(desc_data->rx.buf.pa_unmap.pages); + } + memset(&desc_data->tx, 0, sizeof(desc_data->tx)); memset(&desc_data->rx, 0, sizeof(desc_data->rx)); @@ -62,6 +76,28 @@ static void fxgmac_free_ring(struct fxgmac_pdata *pdata, ring->desc_data_head = NULL; } + if (ring->rx_hdr_pa.pages) { + dma_unmap_page(pdata->dev, ring->rx_hdr_pa.pages_dma, + ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE); + put_page(ring->rx_hdr_pa.pages); + + ring->rx_hdr_pa.pages = NULL; + ring->rx_hdr_pa.pages_len = 0; + ring->rx_hdr_pa.pages_offset = 0; + ring->rx_hdr_pa.pages_dma = 0; + } + + if (ring->rx_buf_pa.pages) { + dma_unmap_page(pdata->dev, ring->rx_buf_pa.pages_dma, + ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE); + put_page(ring->rx_buf_pa.pages); + + ring->rx_buf_pa.pages = NULL; + ring->rx_buf_pa.pages_len = 0; + ring->rx_buf_pa.pages_offset = 0; + ring->rx_buf_pa.pages_dma = 0; + } + if (ring->dma_desc_head) { dma_free_coherent( pdata->dev, @@ -147,12 +183,16 @@ static int fxgmac_alloc_rings(struct fxgmac_pdata *pdata) "error initializing Rx ring\n"); goto err_init_ring; } - if (netif_msg_drv(pdata)) - DPRINTK("fxgmac_alloc_ring..ch=%u, tx_desc_cnt=%u, rx_desc_cnt=%u\n", - i, pdata->tx_desc_count, pdata->rx_desc_count); + if (netif_msg_drv(pdata)) { + DPRINTK("fxgmac_alloc_ring..ch=%u,", i); + if (i < pdata->tx_ring_count) + DPRINTK(" tx_desc_cnt=%u,", pdata->tx_desc_count); + + DPRINTK(" rx_desc_cnt=%u.\n", pdata->rx_desc_count); + } } if (netif_msg_drv(pdata)) - DPRINTK("alloc_rings callout ok\n"); + DPRINTK("alloc_rings callout ok ch=%u\n", i); return 0; @@ -168,19 +208,19 @@ static void fxgmac_free_channels(struct fxgmac_pdata *pdata) if (!pdata->channel_head) return; if (netif_msg_drv(pdata)) - DPRINTK("free_channels, tx_ring=%p\n", + DPRINTK("free_channels, tx_ring=%p", pdata->channel_head->tx_ring); kfree(pdata->channel_head->tx_ring); pdata->channel_head->tx_ring = NULL; if (netif_msg_drv(pdata)) - DPRINTK("free_channels, rx_ring=%p\n", + DPRINTK(" , rx_ring=%p", pdata->channel_head->rx_ring); kfree(pdata->channel_head->rx_ring); pdata->channel_head->rx_ring = NULL; if (netif_msg_drv(pdata)) - DPRINTK("free_channels, channel=%p\n", pdata->channel_head); + DPRINTK(" , channel=%p\n", pdata->channel_head); kfree(pdata->channel_head); pdata->channel_head = NULL; @@ -202,7 +242,7 @@ static int fxgmac_alloc_channels(struct fxgmac_pdata *pdata) channel_head = kcalloc(pdata->channel_count, sizeof(struct fxgmac_channel), GFP_KERNEL); if (netif_msg_drv(pdata)) - DPRINTK("alloc_channels, channel_head=%p, size=%d*%ld\n", + DPRINTK("alloc_channels, channel_head=%p, size=%d*%d\n", channel_head, pdata->channel_count, sizeof(struct fxgmac_channel)); @@ -215,7 +255,7 @@ static int fxgmac_alloc_channels(struct fxgmac_pdata *pdata) goto err_tx_ring; if (netif_msg_drv(pdata)) - DPRINTK("alloc_channels, tx_ring=%p, size=%d*%ld\n", tx_ring, + DPRINTK("alloc_channels, tx_ring=%p, size=%d*%d\n", tx_ring, pdata->tx_ring_count, sizeof(struct fxgmac_ring)); rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct fxgmac_ring), GFP_KERNEL); @@ -223,7 +263,7 @@ static int fxgmac_alloc_channels(struct fxgmac_pdata *pdata) goto err_rx_ring; if (netif_msg_drv(pdata)) - DPRINTK("alloc_channels, rx_ring=%p, size=%d*%ld\n", rx_ring, + DPRINTK("alloc_channels, rx_ring=%p, size=%d*%d\n", rx_ring, pdata->rx_ring_count, sizeof(struct fxgmac_ring)); for (i = 0, channel = channel_head; i < pdata->channel_count; @@ -331,28 +371,82 @@ static int fxgmac_alloc_channels_and_rings(struct fxgmac_pdata *pdata) return ret; } +static void fxgmac_set_buffer_data(struct fxgmac_buffer_data *bd, + struct fxgmac_page_alloc *pa, + unsigned int len) +{ + get_page(pa->pages); + bd->pa = *pa; + + bd->dma_base = pa->pages_dma; + bd->dma_off = pa->pages_offset; + bd->dma_len = len; + + pa->pages_offset += len; + if ((pa->pages_offset + len) > pa->pages_len) { + /* This data descriptor is responsible for unmapping page(s) */ + bd->pa_unmap = *pa; + + /* Get a new allocation next time */ + pa->pages = NULL; + pa->pages_len = 0; + pa->pages_offset = 0; + pa->pages_dma = 0; + } +} + +static int fxgmac_alloc_pages(struct fxgmac_pdata *pdata, + struct fxgmac_page_alloc *pa, + gfp_t gfp, int order) +{ + struct page *pages = NULL; + dma_addr_t pages_dma; + + /* Try to obtain pages, decreasing order if necessary */ + gfp |= __GFP_COMP | __GFP_NOWARN; + while (order >= 0) { + pages = alloc_pages(gfp, order); + if (pages) + break; + + order--; + } + if (!pages) + return -ENOMEM; + + /* Map the pages */ + pages_dma = dma_map_page(pdata->dev, pages, 0, + PAGE_SIZE << order, DMA_FROM_DEVICE); + if (dma_mapping_error(pdata->dev, pages_dma)) { + put_page(pages); + return -ENOMEM; + } + + pa->pages = pages; + pa->pages_len = PAGE_SIZE << order; + pa->pages_offset = 0; + pa->pages_dma = pages_dma; + + return 0; +} + static int fxgmac_map_rx_buffer(struct fxgmac_pdata *pdata, struct fxgmac_ring *ring, struct fxgmac_desc_data *desc_data) { - struct sk_buff *skb; - skb = __netdev_alloc_skb_ip_align(pdata->netdev, pdata->rx_buf_size, - GFP_ATOMIC); - if (!skb) { - netdev_err(pdata->netdev, "%s: Rx init fails; skb is NULL\n", - __func__); - return -ENOMEM; - } + int ret; - desc_data->skb = skb; - desc_data->rx.buf.dma_base = dma_map_single( - pdata->dev, skb->data, pdata->rx_buf_size, DMA_FROM_DEVICE); - if (dma_mapping_error(pdata->dev, desc_data->rx.buf.dma_base)) { - netdev_err(pdata->netdev, "%s: DMA mapping error\n", __func__); - dev_kfree_skb_any(skb); - return -EINVAL; + if (!ring->rx_hdr_pa.pages) { + ret = fxgmac_alloc_pages(pdata, &ring->rx_hdr_pa, + GFP_ATOMIC, 0); + if (ret) + return ret; } + /* Set up the header page info */ + fxgmac_set_buffer_data(&desc_data->rx.hdr, &ring->rx_hdr_pa, + pdata->rx_buf_size); + return 0; } @@ -448,6 +542,7 @@ static void fxgmac_rx_desc_reset(struct fxgmac_pdata *pdata, unsigned int index) { struct fxgmac_dma_desc *dma_desc = desc_data->dma_desc; + dma_addr_t hdr_dma; /* Reset the Rx descriptor * Set buffer 1 (lo) address to header dma address (lo) @@ -456,10 +551,10 @@ static void fxgmac_rx_desc_reset(struct fxgmac_pdata *pdata, * Set buffer 2 (hi) address to buffer dma address (hi) and * set control bits OWN and INTE */ - //hdr_dma = desc_data->rx.hdr.dma_base + desc_data->rx.hdr.dma_off; + hdr_dma = desc_data->rx.hdr.dma_base + desc_data->rx.hdr.dma_off; //buf_dma = desc_data->rx.buf.dma_base + desc_data->rx.buf.dma_off; - dma_desc->desc0 = cpu_to_le32(lower_32_bits(desc_data->rx.buf.dma_base)); - dma_desc->desc1 = cpu_to_le32(upper_32_bits(desc_data->rx.buf.dma_base)); + dma_desc->desc0 = cpu_to_le32(lower_32_bits(hdr_dma)); + dma_desc->desc1 = cpu_to_le32(upper_32_bits(hdr_dma)); dma_desc->desc2 = 0;//cpu_to_le32(lower_32_bits(buf_dma)); dma_desc->desc3 = 0;//cpu_to_le32(upper_32_bits(buf_dma)); dma_desc->desc3 = FXGMAC_SET_REG_BITS_LE( diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ethtool.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ethtool.c index 9b274213ecf27..c053fc0d0b185 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ethtool.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ethtool.c @@ -1,10 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#include -#include -#include - #include "fuxi-gmac.h" #include "fuxi-gmac-reg.h" @@ -115,7 +111,6 @@ static void fxgmac_ethtool_get_drvinfo(struct net_device *netdev, devid = FXGMAC_GET_REG_BITS(ver, MAC_VR_DEVID_POS, MAC_VR_DEVID_LEN); userver = FXGMAC_GET_REG_BITS(ver, MAC_VR_USERVER_POS, MAC_VR_USERVER_LEN); - /*DPRINTK("xlgma: No userver (%x) here, sver (%x) should be 0x51\n", userver, sver);*/ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "S.D.U: %x.%x.%x", sver, devid, userver); } @@ -302,7 +297,7 @@ static int fxgmac_set_rxfh(struct net_device *netdev, const u32 *indir, /* Fill out the redirection table */ if (indir) { -#if FXGMAC_MSIX_CH0RXDIS_EN +#if FXGMAC_MSIX_CH0RXDIS_ENABLED max_queues = max_queues; reta_entries = reta_entries; i = i; @@ -440,9 +435,6 @@ static int fxgmac_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, case ETHTOOL_GRXCLSRLALL: cmd->rule_cnt = 0; ret = 0; - /*ret = ixgbe_get_ethtool_fdir_all(adapter, cmd, - (u32 *)rule_locs); - */ DPRINTK("fxmac, get_rxnfc for classify both cnt and rules\n"); break; case ETHTOOL_GRXFH: @@ -456,7 +448,6 @@ static int fxgmac_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, return ret; } -#define UDP_RSS_FLAGS (BIT(MAC_RSSCR_UDP4TE_POS) | BIT(MAC_RSSCR_UDP6TE_POS)) static int fxgmac_set_rss_hash_opt(struct fxgmac_pdata *pdata, struct ethtool_rxnfc *nfc) { @@ -656,11 +647,6 @@ static void fxgmac_get_wol(struct net_device *netdev, { struct fxgmac_pdata *pdata = netdev_priv(netdev); - /* for further feature implementation - * wol->supported = WAKE_PHY | WAKE_UCAST | WAKE_MCAST | - * WAKE_BCAST | WAKE_MAGIC; - */ - wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC | WAKE_ARP; #if FXGMAC_WOL_UPON_EPHY_LINK @@ -674,7 +660,6 @@ static void fxgmac_get_wol(struct net_device *netdev, return; } wol->wolopts = pdata->expansion.wol; - /* DPRINTK("fxmac, get_wol, 0x%x, 0x%x\n", wol->wolopts, pdata->expansion.wol); */ } // only supports four patterns, and patterns will be cleared on every call @@ -878,7 +863,6 @@ static void fxgmac_get_regs(struct net_device *netdev, regs_buff[REG_MII_PHYSID2]; } -#if FXGMAC_PAUSE_FEATURE_ENABLED static int fxgmac_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { @@ -886,9 +870,10 @@ static int fxgmac_get_link_ksettings(struct net_device *netdev, struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 duplex, regval, link_status; u32 adv = 0xFFFFFFFF; + int ret; - regval = fxgmac_ephy_autoneg_ability_get(pdata, &adv); - if (regval) + ret = fxgmac_ephy_autoneg_ability_get(pdata, &adv); + if (ret < 0) return -ETIMEDOUT; ethtool_link_ksettings_zero_link_mode(cmd, supported); @@ -904,7 +889,10 @@ static int fxgmac_get_link_ksettings(struct net_device *netdev, /* Indicate pause support */ ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause); - hw_ops->read_ephy_reg(pdata, REG_MII_ADVERTISE, ®val); + ret = hw_ops->read_ephy_reg(pdata, REG_MII_ADVERTISE, ®val); + if (ret < 0) + return ret; + if (FXGMAC_GET_REG_BITS(regval, PHY_MII_ADVERTISE_PAUSE_POS, PHY_MII_ADVERTISE_PAUSE_LEN)) ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); if (FXGMAC_GET_REG_BITS(regval, PHY_MII_ADVERTISE_ASYPAUSE_POS, PHY_MII_ADVERTISE_ASYPAUSE_LEN)) @@ -914,7 +902,9 @@ static int fxgmac_get_link_ksettings(struct net_device *netdev, cmd->base.port = PORT_MII; ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); - hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, ®val); + ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, ®val); + if (ret < 0) + return ret; regval = FXGMAC_GET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN); if (regval) { @@ -974,8 +964,12 @@ static int fxgmac_get_link_ksettings(struct net_device *netdev, } cmd->base.autoneg = pdata->phy_autoeng ? regval : 0; - hw_ops->read_ephy_reg(pdata, REG_MII_SPEC_STATUS, ®val); - link_status = regval & (BIT(FUXI_EPHY_LINK_STATUS_BIT)); + regval = 0; + ret = hw_ops->read_ephy_reg(pdata, REG_MII_SPEC_STATUS, ®val); + if (ret < 0) + return ret; + + link_status = regval & (BIT(FXGMAC_EPHY_LINK_STATUS_BIT)); if (link_status) { duplex = FXGMAC_GET_REG_BITS(regval, PHY_MII_SPEC_DUPLEX_POS, PHY_MII_SPEC_DUPLEX_LEN); @@ -1013,47 +1007,53 @@ static int fxgmac_set_link_ksettings(struct net_device *netdev, (!pdata->phy_autoeng && cmd->base.speed == SPEED_1000)) { ret = hw_ops->read_ephy_reg(pdata, REG_MII_ADVERTISE, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv &= ~REG_BIT_ADVERTISE_100_10_CAP; adv |= ethtool_adv_to_mii_adv_t(advertising); ret = hw_ops->write_ephy_reg(pdata, REG_MII_ADVERTISE, adv); if (ret < 0) - return -ETIMEDOUT; + return ret; ret = hw_ops->read_ephy_reg(pdata, REG_MII_CTRL1000, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv &= ~REG_BIT_ADVERTISE_1000_CAP; adv |= ethtool_adv_to_mii_ctrl1000_t(advertising); ret = hw_ops->write_ephy_reg(pdata, REG_MII_CTRL1000, adv); if (ret < 0) - return -ETIMEDOUT; + return ret; ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv = FXGMAC_SET_REG_BITS(adv, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, 1); ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, adv); if (ret < 0) - return -ETIMEDOUT; + return ret; ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv = FXGMAC_SET_REG_BITS(adv, PHY_CR_RE_AUTOENG_POS, PHY_CR_RE_AUTOENG_LEN, 1); ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, adv); if (ret < 0) - return -ETIMEDOUT; + return ret; } else { pdata->phy_duplex = cmd->base.duplex; pdata->phy_speed = cmd->base.speed; fxgmac_phy_force_mode(pdata); } + /* Save speed is used to restore it when resuming */ + pdata->expansion.pre_phy_speed = cmd->base.speed; + pdata->expansion.pre_phy_autoneg = cmd->base.autoneg; + pdata->expansion.pre_phy_duplex = cmd->base.duplex; + return 0; } +#if FXGMAC_PAUSE_FEATURE_ENABLED static void fxgmac_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { @@ -1098,7 +1098,7 @@ static int fxgmac_set_pauseparam(struct net_device *netdev, if (pause->autoneg) { ret = hw_ops->read_ephy_reg(pdata, REG_MII_ADVERTISE, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv = FXGMAC_SET_REG_BITS(adv, PHY_MII_ADVERTISE_PAUSE_POS, PHY_MII_ADVERTISE_PAUSE_LEN, enable_pause); @@ -1107,16 +1107,16 @@ static int fxgmac_set_pauseparam(struct net_device *netdev, enable_pause); ret = hw_ops->write_ephy_reg(pdata, REG_MII_ADVERTISE, adv); if (ret < 0) { - return -ETIMEDOUT; + return ret; } ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, &adv); if (ret < 0) - return -ETIMEDOUT; + return ret; adv = FXGMAC_SET_REG_BITS(adv, PHY_CR_RE_AUTOENG_POS, PHY_CR_RE_AUTOENG_LEN, 1); ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, adv); if (ret < 0) - return -ETIMEDOUT; + return ret; } else { DPRINTK("Can't set phy pause because autoneg is off.\n"); } @@ -1128,14 +1128,6 @@ static int fxgmac_set_pauseparam(struct net_device *netdev, } #endif /*FXGMAC_PAUSE_FEATURE_ENABLED*/ -/* yzhang added for debug sake. descriptors status checking - * 2021.03.29 - */ -#define FXGMAC_ETH_GSTRING_LEN 32 - -#define FXGMAC_TEST_LEN (sizeof(fxgmac_gstrings_test) / FXGMAC_ETH_GSTRING_LEN) -#define DBG_ETHTOOL_CHECK_NUM_OF_DESC 5 - static void fxgmac_ethtool_get_strings(struct net_device *netdev, u32 stringset, u8 *data) { @@ -1181,7 +1173,6 @@ static void fxgmac_ethtool_get_ethtool_stats(struct net_device *netdev, int i; #if FXGMAC_PM_FEATURE_ENABLED - /* 20210709 for net power down */ if (!test_bit(FXGMAC_POWER_STATE_DOWN, &pdata->expansion.powerstate)) #endif { @@ -1205,6 +1196,7 @@ static int fxgmac_ethtool_reset(struct net_device *netdev, u32 *flag) struct fxgmac_pdata *pdata = netdev_priv(netdev); struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 val; + int ret = 0; val = (*flag & ETH_RESET_ALL) || (*flag & ETH_RESET_PHY); if (!val) { @@ -1226,12 +1218,17 @@ static int fxgmac_ethtool_reset(struct net_device *netdev, u32 *flag) val = FXGMAC_SET_REG_BITS(val, PHY_CR_POWER_POS, PHY_CR_POWER_LEN, PHY_POWER_DOWN); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, val); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, val); + if (ret < 0) + return ret; usleep_range_ex(pdata->pAdapter, 9000, 10000); val = FXGMAC_SET_REG_BITS(val, PHY_CR_POWER_POS, PHY_CR_POWER_LEN, PHY_POWER_UP); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, val); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, val); + if (ret < 0) + return ret; + *flag = 0; break; default: @@ -1284,10 +1281,8 @@ static const struct ethtool_ops fxgmac_ethtool_ops = { .set_wol = fxgmac_set_wol, #endif #if (FXGMAC_PAUSE_FEATURE_ENABLED) -#ifdef ETHTOOL_GLINKSETTINGS .get_link_ksettings = fxgmac_get_link_ksettings, .set_link_ksettings = fxgmac_set_link_ksettings, -#endif /* ETHTOOL_GLINKSETTINGS */ .get_pauseparam = fxgmac_get_pauseparam, .set_pauseparam = fxgmac_set_pauseparam, #endif diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-hw.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-hw.c index 5d0f0034de4d7..4c2191e3f3759 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-hw.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-hw.c @@ -24,7 +24,7 @@ static int fxgmac_disable_rx_csum(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MAC_CR_IPC_POS, MAC_CR_IPC_LEN, 0); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_CR); - DPRINTK("fxgmac disable rx checksum.\n"); + DPRINTK("fxgmac disable rx checksum.\n, set val = %x.\n", regval); return 0; } @@ -36,17 +36,17 @@ static int fxgmac_enable_rx_csum(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MAC_CR_IPC_POS, MAC_CR_IPC_LEN, 1); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_CR); - DPRINTK("fxgmac enable rx checksum.\n"); + DPRINTK("fxgmac enable rx checksum.\n, set val = %x.\n", regval); return 0; } static int fxgmac_set_mac_address(struct fxgmac_pdata *pdata, u8 *addr) { - unsigned int mac_addr_hi, mac_addr_lo; + u32 mac_addr_hi, mac_addr_lo; - mac_addr_hi = (addr[5] << 8) | (addr[4] << 0); - mac_addr_lo = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | - (addr[0] << 0); + mac_addr_hi = (((u32)(addr[5]) << 8) | ((u32)(addr[4]) << 0)); + mac_addr_lo = (((u32)(addr[3]) << 24) | ((u32)(addr[2]) << 16) | + ((u32)(addr[1]) << 8) | ((u32)(addr[0]) << 0)); writereg(pdata->pAdapter, mac_addr_hi, pdata->mac_regs + MAC_MACA0HR); writereg(pdata->pAdapter, mac_addr_lo, pdata->mac_regs + MAC_MACA0LR); @@ -56,9 +56,9 @@ static int fxgmac_set_mac_address(struct fxgmac_pdata *pdata, u8 *addr) #if !defined(DPDK) static void fxgmac_set_mac_reg(struct fxgmac_pdata *pdata, - struct netdev_hw_addr *ha, unsigned int *mac_reg) + struct netdev_hw_addr *ha, unsigned int __far *mac_reg) { - unsigned int mac_addr_hi, mac_addr_lo; + u32 mac_addr_hi, mac_addr_lo; u8 *mac_addr; mac_addr_lo = 0; @@ -75,8 +75,11 @@ static void fxgmac_set_mac_reg(struct fxgmac_pdata *pdata, mac_addr[1] = ha->addr[5]; netif_dbg(pdata, drv, pdata->netdev, - "adding mac address %pM at %#x\n", ha->addr, - *mac_reg); + "adding mac address %pM\n", + ha->addr); + netif_dbg(pdata, drv, pdata->netdev, + "adding mac addredd at %#x\n", + *mac_reg); mac_addr_hi = FXGMAC_SET_REG_BITS( mac_addr_hi, MAC_MACA1HR_AE_POS, MAC_MACA1HR_AE_LEN, 1); @@ -159,7 +162,7 @@ static int fxgmac_enable_rx_vlan_stripping(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MAC_VLANTR_EVLS_POS, MAC_VLANTR_EVLS_LEN, 0x3); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_VLANTR); - DPRINTK("fxgmac enable MAC rx vlan stripping.\n"); + DPRINTK("fxgmac enable MAC rx vlan stripping, set val = %x\n", regval); return 0; } @@ -172,7 +175,7 @@ static int fxgmac_disable_rx_vlan_stripping(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MAC_VLANTR_EVLS_POS, MAC_VLANTR_EVLS_LEN, 0); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_VLANTR); - DPRINTK("fxgmac disable MAC rx vlan stripping.\n"); + DPRINTK("fxgmac disable MAC rx vlan stripping, set val = %x\n", regval); return 0; } @@ -302,19 +305,15 @@ static int fxgmac_set_promiscuous_mode(struct fxgmac_pdata *pdata, val); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_PFR); - DbgPrintF(MP_TRACE, "" STR_FORMAT " - promiscuous mode=%d, reg=%x.", - __FUNCTION__, enable, regval); - DbgPrintF( - MP_TRACE, - "" STR_FORMAT - " - note, vlan filter is called when set promiscuous mode=%d.", - __FUNCTION__, enable); + DbgPrintF(MP_TRACE, "promiscuous mode=%d", enable); + DbgPrintF(MP_TRACE, "set val = %x", regval); + DbgPrintF(MP_TRACE, "note, vlan filter is called when set promiscuous mode=%d", enable); /* Hardware will still perform VLAN filtering in promiscuous mode */ if (enable) { fxgmac_disable_rx_vlan_filtering(pdata); } else { - if (FXGMAC_RX_VLAN_FILTERING) { + if (FXGMAC_RX_VLAN_FILTERING_ENABLED) { fxgmac_enable_rx_vlan_filtering(pdata); } } @@ -341,8 +340,9 @@ static int fxgmac_enable_rx_broadcast(struct fxgmac_pdata *pdata, val); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_PFR); - DbgPrintF(MP_TRACE, "%s - bcast en=%d, bit-val=%d, reg=%x.", - __FUNCTION__, enable, val, regval); + DbgPrintF(MP_TRACE, "bcast en=%d", enable); + DbgPrintF(MP_TRACE, "bit-val=%d", val); + DbgPrintF(MP_TRACE, "reg=%x", regval); return 0; } @@ -364,9 +364,8 @@ static int fxgmac_set_all_multicast_mode(struct fxgmac_pdata *pdata, val); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_PFR); - DbgPrintF(MP_TRACE, - "" STR_FORMAT " - Enable all Multicast=%d, regval=%#x.", - __FUNCTION__, enable, regval); + DbgPrintF(MP_TRACE, "Enable all Multicast=%d", enable); + DbgPrintF(MP_TRACE, "set val = %#x.", regval); return 0; } @@ -378,7 +377,7 @@ static void fxgmac_set_mac_addn_addrs(struct fxgmac_pdata *pdata) struct net_device *netdev = pdata->netdev; struct netdev_hw_addr *ha; #endif - unsigned int addn_macs; + u32 addn_macs; unsigned int mac_reg; mac_reg = MAC_MACA1HR; @@ -448,7 +447,7 @@ static void fxgmac_config_multicast_mac_hash_table(struct fxgmac_pdata *pdata, unsigned char *pmc_mac, int b_add) { - unsigned int hash_reg, reg_bit; + u32 hash_reg, reg_bit; unsigned int j; u32 crc, reversal_crc, regval; @@ -461,7 +460,7 @@ static void fxgmac_config_multicast_mac_hash_table(struct fxgmac_pdata *pdata, } DBGPRINT( MP_TRACE, - ("> 24), hash_reg, reg_bit); @@ -486,10 +485,11 @@ static void fxgmac_config_multicast_mac_hash_table(struct fxgmac_pdata *pdata, static void fxgmac_set_mac_hash_table(struct fxgmac_pdata *pdata) { #ifndef DPDK -#if FUXI_MAC_HASH_TABLE +#if FXGMAC_MAC_HASH_TABLE struct net_device *netdev = pdata->netdev; struct netdev_hw_addr *ha; + fxgmac_config_multicast_mac_hash_table(pdata, (unsigned char *)0, 1); netdev_for_each_mc_addr(ha, netdev) { fxgmac_config_multicast_mac_hash_table(pdata, ha->addr, 1); } @@ -501,7 +501,7 @@ static void fxgmac_set_mac_hash_table(struct fxgmac_pdata *pdata) #endif } -static int fxgmac_add_mac_addresses(struct fxgmac_pdata *pdata) +static int fxgmac_set_mc_addresses(struct fxgmac_pdata *pdata) { if (pdata->hw_feat.hash_table_size) fxgmac_set_mac_hash_table(pdata); @@ -511,6 +511,15 @@ static int fxgmac_add_mac_addresses(struct fxgmac_pdata *pdata) return 0; } +static void fxgmac_set_multicast_mode(struct fxgmac_pdata *pdata, + unsigned int enable) +{ + if (enable) + fxgmac_set_mc_addresses(pdata); + else + fxgmac_config_multicast_mac_hash_table(pdata, (unsigned char *)0, 1); +} + static void fxgmac_config_mac_address(struct fxgmac_pdata *pdata) { u32 regval; @@ -521,7 +530,7 @@ static void fxgmac_config_mac_address(struct fxgmac_pdata *pdata) regval = readreg(pdata->pAdapter, pdata->mac_regs + MAC_PFR); regval = FXGMAC_SET_REG_BITS(regval, MAC_PFR_HPF_POS, MAC_PFR_HPF_LEN, 1); -#if FUXI_MAC_HASH_TABLE +#if FXGMAC_MAC_HASH_TABLE regval = FXGMAC_SET_REG_BITS(regval, MAC_PFR_HUC_POS, MAC_PFR_HUC_LEN, 1); #endif @@ -557,7 +566,7 @@ static int fxgmac_config_jumbo(struct fxgmac_pdata *pdata) static void fxgmac_config_checksum_offload(struct fxgmac_pdata *pdata) { - if (FXGMAC_RX_CHECKSUM) + if (FXGMAC_RX_CHECKSUM_ENABLED) fxgmac_enable_rx_csum(pdata); else fxgmac_disable_rx_csum(pdata); @@ -584,15 +593,21 @@ static void fxgmac_config_vlan_support(struct fxgmac_pdata *pdata) static int fxgmac_config_rx_mode(struct fxgmac_pdata *pdata) { - unsigned int pr_mode, am_mode; + unsigned int pr_mode, am_mode, mu_mode, bd_mode; + +#ifndef FXGMAC_NETDEV_MU_MODE_ENABLED +#define FXGMAC_NETDEV_MU_MODE_ENABLED 0 +#endif - pr_mode = FXGMAC_NETDEV_PR_MODE; - am_mode = FXGMAC_NETDEV_AM_MODE; + pr_mode = FXGMAC_NETDEV_PR_MODE_ENABLED; + am_mode = FXGMAC_NETDEV_AM_MODE_ENABLED; + mu_mode = FXGMAC_NETDEV_MU_MODE_ENABLED; + bd_mode = FXGMAC_NETDEV_BD_MODE_ENABLED; + fxgmac_enable_rx_broadcast(pdata, bd_mode); fxgmac_set_promiscuous_mode(pdata, pr_mode); fxgmac_set_all_multicast_mode(pdata, am_mode); - - fxgmac_add_mac_addresses(pdata); + fxgmac_set_multicast_mode(pdata, mu_mode); return 0; } @@ -620,7 +635,7 @@ static void fxgmac_prepare_tx_stop(struct fxgmac_pdata *pdata, DMA_DSRX_TPS_START; } -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED tx_timeout = jiffies + msecs_to_jiffies(100); /* 100ms */ #else tx_timeout = jiffies + (FXGMAC_DMA_STOP_TIMEOUT * HZ); @@ -654,7 +669,7 @@ static void fxgmac_enable_tx(struct fxgmac_pdata *pdata) unsigned int i; u32 regval; -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED pdata->tx_hang_restart_queuing = 0; #endif @@ -676,6 +691,11 @@ static void fxgmac_enable_tx(struct fxgmac_pdata *pdata) for (i = 0; i < dev->data->nb_tx_queues; i++) { txq = dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return; + } /* Enable Tx DMA channel */ FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, ST, 1); } @@ -683,6 +703,12 @@ static void fxgmac_enable_tx(struct fxgmac_pdata *pdata) /* Enable each Tx queue */ for (i = 0; i < pdata->tx_q_count; i++) { + +#if FXGMAC_FAKE_4_TX_QUEUE_ENABLED + if (i > 0) + break; +#endif + regval = readreg(pdata->pAdapter, FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR)); regval = FXGMAC_SET_REG_BITS(regval, MTL_Q_TQOMR_TXQEN_POS, @@ -716,7 +742,7 @@ static void fxgmac_disable_tx(struct fxgmac_pdata *pdata) fxgmac_prepare_tx_stop(pdata, channel); -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED pdata->tx_hang_restart_queuing = 0; #endif } @@ -729,6 +755,11 @@ static void fxgmac_disable_tx(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->tx_q_count; i++) { txq = dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + dev->data->port_id); + return; + } fxgmac_txq_prepare_tx_stop(pdata, i); } #endif @@ -767,6 +798,11 @@ static void fxgmac_disable_tx(struct fxgmac_pdata *pdata) #else for (i = 0; i < dev->data->nb_tx_queues; i++) { txq = dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + dev->data->port_id); + return; + } FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, ST, 0); } #endif @@ -775,7 +811,7 @@ static void fxgmac_disable_tx(struct fxgmac_pdata *pdata) static void fxgmac_prepare_rx_stop(struct fxgmac_pdata *pdata, unsigned int queue) { - unsigned int rx_status, prxq; + u32 rx_status, prxq; #if defined(FXGMAC_WAIT_RX_STOP_BY_PRXQ_RXQSTS) unsigned int rxqsts; unsigned long rx_timeout; @@ -783,7 +819,7 @@ static void fxgmac_prepare_rx_stop(struct fxgmac_pdata *pdata, * packets. Wait for the Rx queue to empty the Rx fifo. Don't * wait forever though... */ -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED rx_timeout = jiffies + msecs_to_jiffies(500); /* 500ms, larger is better */ #else @@ -826,7 +862,8 @@ static void fxgmac_enable_rx(struct fxgmac_pdata *pdata) #ifndef DPDK struct fxgmac_channel *channel; #endif - unsigned int regval, i; + unsigned int i; + u32 regval; /* Enable each Rx DMA channel */ #ifndef DPDK @@ -847,6 +884,11 @@ static void fxgmac_enable_rx(struct fxgmac_pdata *pdata) for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + dev->data->port_id); + return; + } /* Enable Rx DMA channel */ FXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, SR, 1); } @@ -881,7 +923,7 @@ static void fxgmac_enable_channel_rx(struct fxgmac_pdata *pdata, unsigned int queue) { struct fxgmac_channel *channel; - unsigned int regval; + u32 regval; /* Enable Rx DMA channel */ channel = pdata->channel_head + queue; @@ -937,6 +979,11 @@ static void fxgmac_disable_rx(struct fxgmac_pdata *pdata) for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + dev->data->port_id); + return; + } fxgmac_prepare_rx_stop(pdata, i); } #endif @@ -963,6 +1010,11 @@ static void fxgmac_disable_rx(struct fxgmac_pdata *pdata) #else for (i = 0; i < dev->data->nb_rx_queues; i++) { rxq = dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + dev->data->port_id); + return; + } FXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, SR, 0); } #endif @@ -971,22 +1023,29 @@ static void fxgmac_disable_rx(struct fxgmac_pdata *pdata) static int fxgmac_is_context_desc(struct fxgmac_dma_desc *dma_desc) { /* Rx and Tx share CTXT bit, so check TDES3.CTXT bit */ - return FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, TX_NORMAL_DESC3_CTXT_POS, - TX_NORMAL_DESC3_CTXT_LEN); + int regval; + regval = (int)FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, + TX_NORMAL_DESC3_CTXT_POS, + TX_NORMAL_DESC3_CTXT_LEN); + return regval; } static int fxgmac_is_last_desc(struct fxgmac_dma_desc *dma_desc) { /* Rx and Tx share LD bit, so check TDES3.LD bit */ - return FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, TX_NORMAL_DESC3_LD_POS, - TX_NORMAL_DESC3_LD_LEN); + int regval; + regval = (int)FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, + TX_NORMAL_DESC3_LD_POS, + TX_NORMAL_DESC3_LD_LEN); + return regval; } static int fxgmac_disable_tx_flow_control(struct fxgmac_pdata *pdata) { unsigned int max_q_count, q_count; - unsigned int reg, regval; + unsigned int reg; unsigned int i; + u32 regval; /* Clear MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) { @@ -1017,8 +1076,9 @@ static int fxgmac_disable_tx_flow_control(struct fxgmac_pdata *pdata) static int fxgmac_enable_tx_flow_control(struct fxgmac_pdata *pdata) { unsigned int max_q_count, q_count; - unsigned int reg, regval; + unsigned int reg; unsigned int i; + u32 regval; /* Set MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) { @@ -1122,6 +1182,10 @@ static int fxgmac_config_rx_coalesce(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_rx_queues; i++) { rxq = pdata->expansion.eth_dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return -1; FXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RIWT, RWT, pdata->rx_riwt); } #endif @@ -1195,6 +1259,11 @@ static void fxgmac_config_rx_buffer_size(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_rx_queues; i++) { rxq = pdata->expansion.eth_dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return; + } rxq->buf_size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM; @@ -1234,6 +1303,11 @@ static void fxgmac_config_tso_mode(struct fxgmac_pdata *pdata) tso = pdata->hw_feat.tso; for (i = 0; i < pdata->expansion.eth_dev->data->nb_tx_queues; i++) { txq = pdata->expansion.eth_dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return; + } FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, TSE, tso); } #endif @@ -1263,6 +1337,11 @@ static void fxgmac_config_sph_mode(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_rx_queues; i++) { rxq = pdata->expansion.eth_dev->data->rx_queues[i]; + if (!rxq) { + DPRINTK("Rx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return; + } FXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_CR, SPH, 0); } #endif @@ -1273,11 +1352,11 @@ static void fxgmac_config_sph_mode(struct fxgmac_pdata *pdata) writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_ECR); } -static unsigned int fxgmac_usec_to_riwt(struct fxgmac_pdata *pdata, +static unsigned long fxgmac_usec_to_riwt(struct fxgmac_pdata *pdata, unsigned int usec) { unsigned long rate; - unsigned int ret; + unsigned long ret; rate = pdata->sysclk_rate; @@ -1291,11 +1370,11 @@ static unsigned int fxgmac_usec_to_riwt(struct fxgmac_pdata *pdata, return ret; } -static unsigned int fxgmac_riwt_to_usec(struct fxgmac_pdata *pdata, +static unsigned long fxgmac_riwt_to_usec(struct fxgmac_pdata *pdata, unsigned int riwt) { unsigned long rate; - unsigned int ret; + unsigned long ret; rate = pdata->sysclk_rate; @@ -1358,9 +1437,10 @@ static void fxgmac_config_mtl_mode(struct fxgmac_pdata *pdata) static void fxgmac_config_queue_mapping(struct fxgmac_pdata *pdata) { unsigned int ppq, ppq_extra, prio, prio_queues; - unsigned int reg, regval; + unsigned int reg; unsigned int mask; unsigned int i, j; + u32 regval; /* Map the MTL Tx Queues to Traffic Classes * Note: Tx Queues >= Traffic Classes @@ -1380,14 +1460,18 @@ static void fxgmac_config_queue_mapping(struct fxgmac_pdata *pdata) mask = 0; for (j = 0; j < ppq; j++) { netif_dbg(pdata, drv, pdata->netdev, - "PRIO%u mapped to RXq%u\n", prio, i); + "PRIO%u,", prio); + netif_dbg(pdata, drv, pdata->netdev, + " mapped to RXq%u\n", i); mask |= (1 << prio); prio++; } if (i < ppq_extra) { netif_dbg(pdata, drv, pdata->netdev, - "PRIO%u mapped to RXq%u\n", prio, i); + "PRIO%u.", i); + netif_dbg(pdata, drv, pdata->netdev, + " mapped to Rxq%u", i); mask |= (1 << prio); prio++; } @@ -1427,11 +1511,11 @@ static void fxgmac_config_queue_mapping(struct fxgmac_pdata *pdata) writereg(pdata->pAdapter, regval, pdata->mac_regs + reg); } -static unsigned int fxgmac_calculate_per_queue_fifo(unsigned int fifo_size, +static u32 fxgmac_calculate_per_queue_fifo(unsigned long fifo_size, unsigned int queue_count) { - unsigned int q_fifo_size; - unsigned int p_fifo; + unsigned long q_fifo_size; + unsigned long p_fifo; /* Calculate the configured fifo size */ q_fifo_size = 1 << (fifo_size + 7); @@ -1452,16 +1536,51 @@ static unsigned int fxgmac_calculate_per_queue_fifo(unsigned int fifo_size, return p_fifo; } +static u32 fxgmac_calculate_max_checksum_size(struct fxgmac_pdata *pdata) +{ + u32 fifo_size; + + fifo_size = fxgmac_calculate_per_queue_fifo( + pdata->hw_feat.tx_fifo_size, + pdata->tx_q_count); + + /* Each increment in the queue fifo size represents 256 bytes of + * fifo, with 0 representing 256 bytes. Distribute the fifo equally + * between the queues. + */ + fifo_size = (fifo_size + 1) * 256; + + /* Packet size < TxQSize - (PBL + N)*(DATAWIDTH/8), + * Datawidth = 128 + * If Datawidth = 32, N = 7, elseif Datawidth != 32, N = 5. + * TxQSize is indicated by TQS field of MTL_TxQ#_Operation_Mode register + * PBL = TxPBL field in the DMA_CH#_TX_Control register in all DMA configurations. + */ + fifo_size -= (pdata->tx_pbl * (pdata->pblx8 ? 8 : 1) + 5) * (FXGMAC_DATA_WIDTH / 8); + fifo_size -= 256; + + return fifo_size; +} + static void fxgmac_config_tx_fifo_size(struct fxgmac_pdata *pdata) { - unsigned int fifo_size; + u32 fifo_size; unsigned int i; u32 regval; fifo_size = fxgmac_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size, - pdata->tx_q_count); +#if FXGMAC_FAKE_4_TX_QUEUE_ENABLED + 1);//force to 1 queue +#else + pdata->tx_q_count); +#endif for (i = 0; i < pdata->tx_q_count; i++) { +#if FXGMAC_FAKE_4_TX_QUEUE_ENABLED + //DPRINTK("Tx idx > 0,break\n"); + if (i > 0) + break; +#endif regval = readreg(pdata->pAdapter, FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR)); regval = FXGMAC_SET_REG_BITS(regval, MTL_Q_TQOMR_TQS_POS, @@ -1471,13 +1590,16 @@ static void fxgmac_config_tx_fifo_size(struct fxgmac_pdata *pdata) } netif_info(pdata, drv, pdata->netdev, - "%d Tx hardware queues, %d byte fifo per queue\n", - pdata->tx_q_count, ((fifo_size + 1) * 256)); + "%d Tx hardware queues,", + pdata->tx_q_count); + netif_info(pdata, drv, pdata->netdev, + " %d byte fifo per queue\n", + ((fifo_size + 1) * 256)); } static void fxgmac_config_rx_fifo_size(struct fxgmac_pdata *pdata) { - unsigned int fifo_size; + u32 fifo_size; unsigned int i; u32 regval; @@ -1494,8 +1616,11 @@ static void fxgmac_config_rx_fifo_size(struct fxgmac_pdata *pdata) } netif_info(pdata, drv, pdata->netdev, - "%d Rx hardware queues, %d byte fifo per queue\n", - pdata->rx_q_count, ((fifo_size + 1) * 256)); + "%d Rx hardware queues,", + pdata->rx_q_count); + netif_info(pdata, drv, pdata->netdev, + " %d byte fifo per queue\n", + ((fifo_size + 1) * 256)); } static void fxgmac_config_flow_control_threshold(struct fxgmac_pdata *pdata) @@ -1598,6 +1723,11 @@ static int fxgmac_config_osp_mode(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_tx_queues; i++) { txq = pdata->expansion.eth_dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return -1; + } FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, OSP, pdata->tx_osp_mode); } @@ -1627,6 +1757,11 @@ static int fxgmac_config_pblx8(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_tx_queues; i++) { txq = pdata->expansion.eth_dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return -1; + } FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_CR, PBLX8, pdata->pblx8); } #endif @@ -1634,7 +1769,7 @@ static int fxgmac_config_pblx8(struct fxgmac_pdata *pdata) return 0; } -static int fxgmac_get_tx_pbl_val(struct fxgmac_pdata *pdata) +static u32 fxgmac_get_tx_pbl_val(struct fxgmac_pdata *pdata) { u32 regval; @@ -1670,6 +1805,11 @@ static int fxgmac_config_tx_pbl_val(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_tx_queues; i++) { txq = pdata->expansion.eth_dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return -1; + } FXGMAC_DMA_IOWRITE_BITS(txq, DMA_CH_TCR, PBL, pdata->tx_pbl); } #endif @@ -1677,7 +1817,7 @@ static int fxgmac_config_tx_pbl_val(struct fxgmac_pdata *pdata) return 0; } -static int fxgmac_get_rx_pbl_val(struct fxgmac_pdata *pdata) +static u32 fxgmac_get_rx_pbl_val(struct fxgmac_pdata *pdata) { u32 regval; @@ -1713,6 +1853,11 @@ static int fxgmac_config_rx_pbl_val(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_rx_queues; i++) { rxq = pdata->expansion.eth_dev->data->rx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return -1; + } FXGMAC_DMA_IOWRITE_BITS(rxq, DMA_CH_RCR, PBL, pdata->rx_pbl); } #endif @@ -1731,7 +1876,7 @@ static u64 fxgmac_mmc_read(struct fxgmac_pdata *pdata, unsigned int reg_lo) static void fxgmac_tx_mmc_int(struct fxgmac_pdata *pdata) { - unsigned int mmc_isr = + u32 mmc_isr = readreg(pdata->pAdapter, pdata->mac_regs + MMC_TISR); struct fxgmac_stats *stats = &pdata->stats; @@ -1869,7 +2014,7 @@ static void fxgmac_tx_mmc_int(struct fxgmac_pdata *pdata) static void fxgmac_rx_mmc_int(struct fxgmac_pdata *pdata) { - unsigned int mmc_isr = + u32 mmc_isr = readreg(pdata->pAdapter, pdata->mac_regs + MMC_RISR); struct fxgmac_stats *stats = &pdata->stats; @@ -2163,14 +2308,14 @@ static void fxgmac_config_mmc(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MMC_CR_CR_POS, MMC_CR_CR_LEN, 1); writereg(pdata->pAdapter, regval, pdata->mac_regs + MMC_CR); -#if FUXI_MISC_INT_HANDLE_FEATURE_EN +#if FXGMAC_MISC_INT_HANDLE_FEATURE_ENABLED writereg(pdata->pAdapter, 0xffffffff, pdata->mac_regs + MMC_IPCRXINTMASK); #endif } static int fxgmac_write_rss_reg(struct fxgmac_pdata *pdata, unsigned int type, - unsigned int index, unsigned int val) + unsigned int index, u32 val) { int ret = 0; type = type; @@ -2238,10 +2383,9 @@ static int fxgmac_write_rss_hash_key(struct fxgmac_pdata *pdata) int ret; while (key_regs--) { - ret = fxgmac_write_rss_reg( - pdata, FXGMAC_RSS_HASH_KEY_TYPE, - MGMT_RSS_KEY0 + key_regs * MGMT_RSS_KEY_REG_INC, - cpu_to_be32(*key)); + ret = fxgmac_write_rss_reg(pdata, (unsigned int)FXGMAC_RSS_HASH_KEY_TYPE, + (unsigned int)(MGMT_RSS_KEY0 + key_regs * MGMT_RSS_KEY_REG_INC), + (unsigned int)(cpu_to_be32 (*key))); if (ret) return ret; key++; @@ -2289,7 +2433,7 @@ static int fxgmac_write_rss_lookup_table(struct fxgmac_pdata *pdata) static int fxgmac_set_rss_hash_key(struct fxgmac_pdata *pdata, const u8 *key) { - memcpy(pdata->rss_key, key, sizeof(pdata->rss_key)); + memcpy(pdata->rss_key, (void *)key, sizeof(pdata->rss_key)); return fxgmac_write_rss_hash_key(pdata); } @@ -2300,7 +2444,7 @@ static int fxgmac_set_rss_lookup_table(struct fxgmac_pdata *pdata, unsigned int i; u32 tval; -#if FXGMAC_MSIX_CH0RXDIS_EN +#if FXGMAC_MSIX_CH0RXDIS_ENABLED DPRINTK("Set_rss_table, rss ctrl eth=0x%08x\n", 0); return 0; @@ -2362,7 +2506,7 @@ static int fxgmac_enable_rss(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, MGMT_RSS_CTRL_TBL_SIZE_POS, MGMT_RSS_CTRL_TBL_SIZE_LEN, size); -#if FXGMAC_MSIX_CH0RXDIS_EN +#if FXGMAC_MSIX_CH0RXDIS_ENABLED /* set default cpu id to 1 */ regval = FXGMAC_SET_REG_BITS(regval, 8, 2, 1); #endif @@ -2375,7 +2519,7 @@ static int fxgmac_enable_rss(struct fxgmac_pdata *pdata) MGMT_RSS_CTRL_OPT_LEN, pdata->rss_options); writereg(pdata->pAdapter, regval, (pdata->base_mem + MGMT_RSS_CTRL)); - DPRINTK("enable_rss callout, rss ctrl reg=0x%08x\n", regval); + DPRINTK("enable_rss callout, set val = 0x%08x\n", regval); return 0; } @@ -2387,7 +2531,7 @@ static int fxgmac_disable_rss(struct fxgmac_pdata *pdata) if (!pdata->hw_feat.rss) return -EOPNOTSUPP; -#if FXGMAC_MSIX_CH0RXDIS_EN +#if FXGMAC_MSIX_CH0RXDIS_ENABLED DPRINTK("Disable_rss, rss ctrl eth=0x%08x\n", 0); return 0; @@ -2398,7 +2542,7 @@ static int fxgmac_disable_rss(struct fxgmac_pdata *pdata) MAC_RSSCR_RSSE_LEN, 0); writereg(pdata->pAdapter, regval, (pdata->base_mem + MGMT_RSS_CTRL)); - DPRINTK("disable_rss, rss ctrl reg=0x%08x\n", regval); + DPRINTK("disable_rss, set val = 0x%08x\n", regval); return 0; } @@ -2416,8 +2560,7 @@ static void fxgmac_config_rss(struct fxgmac_pdata *pdata) ret = fxgmac_disable_rss(pdata); if (ret) { - DBGPRINT(MP_ERROR, - ("fxgmac_config_rss: error configuring RSS\n")); + DPRINTK("fxgmac_config_rss: error configuring RSS\n"); } } @@ -3081,7 +3224,7 @@ static int fxgmac_disable_wake_magic_pattern(struct fxgmac_pdata *pdata) return 0; } -#if FUXI_PM_WPI_READ_FEATURE_EN +#if FXGMAC_PM_WPI_READ_FEATURE_ENABLED /* * enable Wake packet indication. called to enable before sleep/hibernation * and no needed to call disable for that, fxgmac_get_wake_packet_indication will clear to normal once done. @@ -3160,7 +3303,7 @@ static void fxgmac_get_wake_packet_indication(struct fxgmac_pdata *pdata, * wake_pattern_number, HW should tell, tbd */ for (i = 0; i < MAX_PATTERN_COUNT; i++) { - if (regval & (MGMT_WOL_CTRL_WPI_RWK_PKT_NUMBER << i)) { + if (regval & ((u32)MGMT_WOL_CTRL_WPI_RWK_PKT_NUMBER << i)) { *wake_pattern_number = i; break; } @@ -3298,7 +3441,7 @@ static u32 fxgmac_get_ephy_state(struct fxgmac_pdata *pdata) static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *pdata) { #ifndef DPDK - unsigned int dma_ch_isr, dma_ch_ier; + u32 dma_ch_isr, dma_ch_ier; struct fxgmac_channel *channel; unsigned int i; @@ -3380,6 +3523,11 @@ static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *pdata) for (i = 0; i < pdata->expansion.eth_dev->data->nb_tx_queues; i++) { txq = pdata->expansion.eth_dev->data->tx_queues[i]; + if (!txq) { + DPRINTK("Tx queue not setup for port %d\n", + pdata->expansion.eth_dev->data->port_id); + return; + } /* Clear all the interrupts which are set */ dma_ch_isr = FXGMAC_DMA_IOREAD(txq, DMA_CH_SR); @@ -3413,8 +3561,8 @@ static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *pdata) static void fxgmac_enable_mtl_interrupts(struct fxgmac_pdata *pdata) { - unsigned int q_count, i; - unsigned int mtl_q_isr; + unsigned int i; + u32 mtl_q_isr, q_count; q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt); for (i = 0; i < q_count; i++) { @@ -3432,7 +3580,7 @@ static void fxgmac_enable_mtl_interrupts(struct fxgmac_pdata *pdata) static void fxgmac_enable_mac_interrupts(struct fxgmac_pdata *pdata) { - unsigned int mac_ier = 0; + u32 mac_ier = 0; u32 regval; /* Enable Timestamp interrupt */ @@ -3549,11 +3697,11 @@ static int fxgmac_check_phy_link(struct fxgmac_pdata *pdata, u32 *speed, MGMT_EPHY_CTRL_STA_SPEED_MASK) >> MGMT_EPHY_CTRL_STA_SPEED_POS; } else { - DPRINTK("fxgmac_check_phy_link ethernet PHY not released.\n"); + DPRINTK("fxgmac_check_phy_link ethernet PHY not released link reg %d.\n", link_reg); return -1; } } else { - DPRINTK("fxgmac_check_phy_link null base addr err\n"); + DPRINTK("fxgmac_check_phy_link null base addr err link reg %d\n", link_reg); return -1; } @@ -3594,14 +3742,16 @@ static int fxgmac_write_ephy_reg(struct fxgmac_pdata *pdata, u32 reg_id, busy--; } while ((regval & MAC_MDIO_ADDRESS_BUSY) && (busy)); - DPRINTK("fxgmac_write_ephy_reg id %d %s, ctrl=0x%08x, data=0x%08x\n", - reg_id, (regval & 0x1) ? "err" : "ok", regval, data); + DPRINTK("fxgmac_write_ephy_reg id %d,", reg_id); + DPRINTK(" %s,", (regval & 0x1)?"err" : "ok"); + DPRINTK(" ctrl=0x%08x,", regval); + DPRINTK(" data=0x%08x\n", data); - return (regval & MAC_MDIO_ADDRESS_BUSY) ? -1 : 0; /* -1 indicates err */ + return (regval & MAC_MDIO_ADDRESS_BUSY) ? -ETIMEDOUT : 0; //-1 indicates err } static int fxgmac_read_ephy_reg(struct fxgmac_pdata *pdata, u32 reg_id, - u32 *data) + u32 __far *data) { u32 regval = 0, regret; u32 mdioctrl = reg_id * 0x10000 + 0x800020d; @@ -3617,14 +3767,20 @@ static int fxgmac_read_ephy_reg(struct fxgmac_pdata *pdata, u32 reg_id, if (0 == (regval & MAC_MDIO_ADDRESS_BUSY)) { regret = readreg(pdata->pAdapter, pdata->mac_regs + MAC_MDIO_DATA); - if (data) - *data = regret; - return regret; + if (data) { + *data = regret; + //DPRINTK("fxgmac_read_ephy_reg ok, reg=0x%02x, ctrl=0x%08x, data=0x%08x\n", reg_id, regval, *data); + return 0; + } else { + return -ENOBUFS; + } } - DPRINTK("fxgmac_read_ephy_reg id=0x%02x err, busy=%d, ctrl=0x%08x.\n", - reg_id, busy, regval); - return -1; + DPRINTK("fxgmac_read_ephy_reg id=0x%02x err,", reg_id); + DPRINTK(" busy=%d,", busy); + DPRINTK(" ctrl=0x%08x\n", regval); + + return -ETIMEDOUT; } static int fxgmac_write_ephy_mmd_reg(struct fxgmac_pdata *pdata, u32 reg_id, @@ -3644,22 +3800,25 @@ static int fxgmac_write_ephy_mmd_reg(struct fxgmac_pdata *pdata, u32 reg_id, busy--; } while ((regval & MAC_MDIO_ADDRESS_BUSY) && (busy)); - DPRINTK("fxgmac_write_ephy_mmd_reg id %d mmd %d %s, ctrl=0x%08x, data=0x%08x\n", - reg_id, mmd, (regval & 0x1) ? "err" : "ok", regval, data); + DPRINTK("fxgmac_write_ephy_mmd_reg id %d,", reg_id); + DPRINTK(" mmd %d,", mmd); + DPRINTK(" %s,", (regval & 0x1) ? "err" : "ok"); + DPRINTK(" ctrl=0x%08x,", regval); + DPRINTK(" data=0x%08x\n", data); return (regval & MAC_MDIO_ADDRESS_BUSY) ? -1 : 0; /* -1 indicates err */ } static void fxgmac_config_flow_control(struct fxgmac_pdata *pdata) { -#ifndef FXGMAC_NOT_REPORT_PHY_FC_CAPABILITY_ENABLED +#ifndef FXGMAC_NOT_REPORT_PHY_FC_CAPABILITY u32 regval = 0; #endif fxgmac_config_tx_flow_control(pdata); fxgmac_config_rx_flow_control(pdata); -#ifndef FXGMAC_NOT_REPORT_PHY_FC_CAPABILITY_ENABLED +#ifndef FXGMAC_NOT_REPORT_PHY_FC_CAPABILITY fxgmac_read_ephy_reg(pdata, REG_MII_ADVERTISE, ®val); /* set auto negotiation advertisement pause ability */ if (pdata->tx_pause || pdata->rx_pause) { @@ -3689,19 +3848,21 @@ static void fxgmac_config_flow_control(struct fxgmac_pdata *pdata) static int fxgmac_set_ephy_autoneg_advertise(struct fxgmac_pdata *pdata, struct fxphy_ag_adv phy_ag_adv) { - u32 regval = 0, ret = 0; + u32 regval = 0; + int ret = 0; if (phy_ag_adv.auto_neg_en) { fxgmac_read_ephy_reg(pdata, REG_MII_BMCR, ®val); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, 1); - ret |= fxgmac_write_ephy_reg(pdata, REG_MII_BMCR, regval); } else { fxgmac_read_ephy_reg(pdata, REG_MII_BMCR, ®val); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, 0); - ret |= fxgmac_write_ephy_reg(pdata, REG_MII_BMCR, regval); } + ret = fxgmac_write_ephy_reg(pdata, REG_MII_BMCR, regval); + if (ret < 0) + return ret; fxgmac_read_ephy_reg(pdata, REG_MII_CTRL1000, ®val); if (phy_ag_adv.full_1000m) { @@ -3722,7 +3883,9 @@ static int fxgmac_set_ephy_autoneg_advertise(struct fxgmac_pdata *pdata, PHY_MII_CTRL1000_1000HALF_POS, PHY_MII_CTRL1000_1000HALF_LEN, 0); } - ret |= fxgmac_write_ephy_reg(pdata, REG_MII_CTRL1000, regval); + ret = fxgmac_write_ephy_reg(pdata, REG_MII_CTRL1000, regval); + if (ret < 0) + return ret; fxgmac_read_ephy_reg(pdata, REG_MII_ADVERTISE, ®val); @@ -3763,12 +3926,15 @@ static int fxgmac_set_ephy_autoneg_advertise(struct fxgmac_pdata *pdata, PHY_MII_ADVERTISE_10HALF_LEN, 0); } - ret |= fxgmac_write_ephy_reg(pdata, REG_MII_ADVERTISE, regval); + ret = fxgmac_write_ephy_reg(pdata, REG_MII_ADVERTISE, regval); + if (ret < 0) + return ret; + /* after change the auto negotiation advertisement need to soft reset */ fxgmac_read_ephy_reg(pdata, REG_MII_BMCR, ®val); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_RESET_POS, PHY_CR_RESET_LEN, 1); - ret |= fxgmac_write_ephy_reg(pdata, REG_MII_BMCR, regval); + ret = fxgmac_write_ephy_reg(pdata, REG_MII_BMCR, regval); return ret; } @@ -3938,7 +4104,7 @@ void fxgmac_release_phy(struct fxgmac_pdata *pdata) fxgmac_write_ephy_reg(pdata, REG_MII_EXT_DATA, REG_MII_EXT_ANALOG_CFG2_VALUE); cfg_r32(pdata, REG_PCI_SUB_VENDOR_ID, &value); - if (TONGFANGID_137D1D05_ADJUST_SI == value) { + if (AISTONEID_137D1D05_ADJUST_SI == value) { fxgmac_write_ephy_reg(pdata, REG_MII_EXT_ADDR, REG_MII_EXT_ANALOG_CFG8); fxgmac_write_ephy_reg(pdata, REG_MII_EXT_DATA, REG_MII_EXT_ANALOG_CFG8_137D1D05_VALUE); } else { @@ -4271,7 +4437,7 @@ static void fxgmac_config_led_under_disable(struct fxgmac_pdata *pdata) static int fxgmac_enable_int(struct fxgmac_channel *channel, enum fxgmac_int int_id) { - unsigned int dma_ch_ier; + u32 dma_ch_ier; dma_ch_ier = readreg(channel->pdata->pAdapter, FXGMAC_DMA_REG(channel, DMA_CH_IER)); @@ -4333,7 +4499,7 @@ static int fxgmac_enable_int(struct fxgmac_channel *channel, static int fxgmac_disable_int(struct fxgmac_channel *channel, enum fxgmac_int int_id) { - unsigned int dma_ch_ier; + u32 dma_ch_ier; dma_ch_ier = readreg(channel->pdata->pAdapter, FXGMAC_DMA_REG(channel, DMA_CH_IER)); @@ -4395,7 +4561,7 @@ static int fxgmac_disable_int(struct fxgmac_channel *channel, static int fxgmac_dismiss_DMA_int(struct fxgmac_channel *channel, int int_id) { - unsigned int dma_ch_ier; + u32 dma_ch_ier; int_id = int_id; dma_ch_ier = readreg(channel->pdata->pAdapter, @@ -4408,8 +4574,8 @@ static int fxgmac_dismiss_DMA_int(struct fxgmac_channel *channel, int int_id) static void fxgmac_dismiss_MTL_Q_int(struct fxgmac_pdata *pdata) { - unsigned int q_count, i; - unsigned int mtl_q_isr; + unsigned int i; + u32 mtl_q_isr, q_count; q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt); for (i = 0; i < q_count; i++) { @@ -4468,10 +4634,6 @@ int fxgmac_dismiss_all_int(struct fxgmac_pdata *pdata) struct fxgmac_channel *channel; unsigned int i; - if (netif_msg_drv(pdata)) { - DPRINTK("fxgmac_dismiss_all_int callin\n"); - } - channel = pdata->channel_head; for (i = 0; i < pdata->channel_count; i++, channel++) { fxgmac_dismiss_DMA_int(channel, 0); @@ -4482,6 +4644,10 @@ int fxgmac_dismiss_all_int(struct fxgmac_pdata *pdata) fxgmac_dismiss_MAC_LPI_int(pdata); fxgmac_dismiss_MAC_DBG_int(pdata); + if (netif_msg_drv(pdata)) { + DPRINTK("fxgmac_dismiss_all_int callin %d\n", i); + } + return 0; } @@ -4525,10 +4691,11 @@ static void fxgmac_disable_msix_interrupt(struct fxgmac_pdata *pdata) MSIX_TBL_MASK_OFFSET + intid * 16); } } -static void fxgmac_enable_msix_rxtxphyinterrupt(struct fxgmac_pdata *pdata) +static int fxgmac_enable_msix_rxtxphyinterrupt(struct fxgmac_pdata *pdata) { u32 intid, regval = 0; -#if !(FUXI_EPHY_INTERRUPT_D0_OFF) + int ret = 0; +#if !(FXGMAC_EPHY_INTERRUPT_D0_OFF) struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; #endif @@ -4540,17 +4707,21 @@ static void fxgmac_enable_msix_rxtxphyinterrupt(struct fxgmac_pdata *pdata) writereg(pdata->pAdapter, 0, pdata->base_mem + MSIX_TBL_BASE_ADDR + MSIX_TBL_MASK_OFFSET + MSI_ID_PHY_OTHER * 16); -#if !(FUXI_EPHY_INTERRUPT_D0_OFF) +#if !(FXGMAC_EPHY_INTERRUPT_D0_OFF) hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); /* clear phy interrupt */ regval = FXGMAC_SET_REG_BITS(0, PHY_INT_MASK_LINK_UP_POS, PHY_INT_MASK_LINK_UP_LEN, 1); regval = FXGMAC_SET_REG_BITS(regval, PHY_INT_MASK_LINK_DOWN_POS, PHY_INT_MASK_LINK_DOWN_LEN, 1); - hw_ops->write_ephy_reg( + ret = hw_ops->write_ephy_reg( pdata, REG_MII_INT_MASK, regval); /* enable phy interrupt ASIC bit10 linkup bit11 linkdown */ + return ret; +#else + return 0; #endif + } static void fxgmac_enable_msix_one_interrupt(struct fxgmac_pdata *pdata, u32 intid) @@ -4592,8 +4763,8 @@ static int fxgmac_flush_tx_queues(struct fxgmac_pdata *pdata) MTL_Q_TQOMR_FTQ_LEN, 1); writereg(pdata->pAdapter, regval, FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR)); - DPRINTK("fxgmac_flush_tx_queues, reg=0x%p, val=0x%08x\n", - FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR), regval); + DPRINTK("fxgmac_flush_tx_queues, reg=0x%p,", FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR)); + DPRINTK(" val=0x%08x\n", regval); } for (i = 0; i < pdata->tx_q_count; i++) { @@ -4607,8 +4778,8 @@ static int fxgmac_flush_tx_queues(struct fxgmac_pdata *pdata) MTL_Q_TQOMR_FTQ_LEN); } while (--count && regval); - DPRINTK("fxgmac_flush_tx_queues wait... reg=0x%p, val=0x%08x\n", - FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR), regval); + DPRINTK("fxgmac_flush_tx_queues wait... reg=0x%p,", FXGMAC_MTL_REG(pdata, i, MTL_Q_TQOMR)); + DPRINTK(" ... val=0x%08x\n", regval); if (regval) { /*(!count)*/ return -EBUSY; } @@ -4649,7 +4820,8 @@ static void fxgmac_config_dma_bus(struct fxgmac_pdata *pdata) static void fxgmac_legacy_link_speed_setting(struct fxgmac_pdata *pdata) { - unsigned int i = 0, regval = 0; + unsigned int i = 0; + u32 regval = 0; fxgmac_phy_config(pdata); for (i = 0, regval = fxgmac_get_ephy_state(pdata); @@ -4710,12 +4882,15 @@ static void fxgmac_pre_powerdown(struct fxgmac_pdata *pdata, bool phyloopback) { u32 regval = 0; int speed = SPEED_10; +#ifdef FXGMAC_LINK_SPEED_CHECK_PHY_LINK + int link; +#endif speed = speed; fxgmac_disable_rx(pdata); /* HERE, WE NEED TO CONSIDER PHY CONFIG...TBD */ - DPRINTK("fxgmac_config_powerdown, phy and mac status update\n"); + DPRINTK("fxgmac_config_powerdown, phy and mac status update speed %d\n", speed); //2022-11-09 xiaojiang comment //for phy cable loopback,it can't configure phy speed, it will cause os resume again by link change although it has finished speed setting, if (!phyloopback) { @@ -4739,10 +4914,12 @@ static void fxgmac_pre_powerdown(struct fxgmac_pdata *pdata, bool phyloopback) The process of suspending again after resume is fast, and PHY auto-negotiation is not yet complete, so the auto-negotiation of PHY must be carried out again.Windows platforms and UEFI platforms do not need to auto-negotiate again, as they will not have such a process. - When the Linux platform enters the s4 state, force speed to 10M. */ - if (pdata->expansion.phy_link && (speed != pdata->phy_speed)) { + regval = fxgmac_get_ephy_state(pdata); + link = FXGMAC_GET_REG_BITS(regval, MGMT_EPHY_CTRL_STA_EPHY_LINKUP_POS, + MGMT_EPHY_CTRL_STA_EPHY_LINKUP_LEN); + if (link && (speed != pdata->phy_speed)) { pdata->phy_speed = speed; fxgmac_legacy_link_speed_setting(pdata); } @@ -4821,7 +4998,7 @@ static void fxgmac_config_powerdown(struct fxgmac_pdata *pdata, fxgmac_enable_ns_offload(pdata); #endif -#if FUXI_PM_WPI_READ_FEATURE_EN +#if FXGMAC_PM_WPI_READ_FEATURE_ENABLED fxgmac_enable_wake_packet_indication(pdata, 1); #endif @@ -4858,19 +5035,10 @@ static void fxgmac_config_powerdown(struct fxgmac_pdata *pdata, MAC_PMT_STA_PWRDWN_LEN, 1); writereg(pdata->pAdapter, regval, pdata->mac_regs + MAC_PMT_STA); -//#ifdef FXGMAC_FIX_FT_D2000_PLATFORM_WOL_ISSUE -#ifdef ARM64 - /* adjust sigdet threshold - * redmine.motor-comm.com/issues/5093 - * fix issue can not wake up os on some FT-D2000 platform, y - * this modification is only temporarif it is 55mv, wol maybe failed. - */ - regval = readreg(pdata->pAdapter, pdata->base_mem + MGMT_SIGDET); - regval = FXGMAC_SET_REG_BITS(regval, MGMT_SIGDET_POS, MGMT_SIGDET_LEN, - MGMT_SIGDET_40MV); + regval = FXGMAC_SET_REG_BITS(regval, MGMT_SIGDET_POS, MGMT_SIGDET_LEN, MGMT_SIGDET_55MV); writereg(pdata->pAdapter, regval, pdata->base_mem + MGMT_SIGDET); -#endif + DPRINTK("fxgmac_config_powerdown callout, reg=0x%08x\n", regval); } @@ -4985,7 +5153,7 @@ static unsigned char fxgmac_suspend_int(void *context) { /* ULONG_PTR addr; */ u32 intid; -#if FUXI_EPHY_INTERRUPT_D0_OFF +#if FXGMAC_EPHY_INTERRUPT_D0_OFF u32 regval = 0; #endif u32 val_mgmt_intcrtl0; @@ -5018,7 +5186,7 @@ static unsigned char fxgmac_suspend_int(void *context) /* since Msix interrupt masked now, enable EPHY interrupt for case of link change wakeup */ fxgmac_read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); /* clear phy interrupt */ -#if FUXI_EPHY_INTERRUPT_D0_OFF +#if FXGMAC_EPHY_INTERRUPT_D0_OFF regval = FXGMAC_SET_REG_BITS(0, PHY_INT_MASK_LINK_UP_POS, PHY_INT_MASK_LINK_UP_LEN, 1); regval = FXGMAC_SET_REG_BITS(regval, PHY_INT_MASK_LINK_DOWN_POS, @@ -5057,7 +5225,7 @@ static int fxgmac_suspend_txrx(struct fxgmac_pdata *pdata) DMA_CH_TCR_ST_LEN, 0); writereg(pdata->pAdapter, regval, FXGMAC_DMA_REG(channel, DMA_CH_TCR)); - DBGPRINT(MP_TRACE, (" %s disable tx dma", __FUNCTION__)); + DBGPRINT(MP_TRACE, (" disable channel %d tx dma", i)); } do { @@ -5069,8 +5237,7 @@ static int fxgmac_suspend_txrx(struct fxgmac_pdata *pdata) if (0 != (regval & MAC_DBG_STA_TX_BUSY)) { regval = readreg(pdata->pAdapter, pdata->mac_regs + MAC_DBG_STA); - DbgPrintF(MP_WARN, - "warning !!!timed out waiting for Tx MAC to stop\n"); + DbgPrintF(MP_WARN, "warning !!!timed out waiting for Tx MAC to stop regval %x\n", regval); return -1; } /* wait empty Tx queue */ @@ -5114,7 +5281,7 @@ static int fxgmac_suspend_txrx(struct fxgmac_pdata *pdata) DMA_CH_RCR_SR_LEN, 0); writereg(pdata->pAdapter, regval, FXGMAC_DMA_REG(channel, DMA_CH_RCR)); - DBGPRINT(MP_TRACE, (" %s disable rx dma", __FUNCTION__)); + DBGPRINT(MP_TRACE, (" disable channel %d rx dma", i)); } return 0; } @@ -5145,7 +5312,7 @@ static void fxgmac_resume_int(struct fxgmac_pdata *pdata) MSIX_TBL_MASK_OFFSET + intid * 16); } -#if FUXI_EPHY_INTERRUPT_D0_OFF +#if FXGMAC_EPHY_INTERRUPT_D0_OFF fxgmac_write_ephy_reg(pdata, REG_MII_INT_MASK, 0x0); /* disable phy interrupt */ fxgmac_read_ephy_reg(pdata, REG_MII_INT_STATUS, @@ -5160,6 +5327,16 @@ static void fxgmac_resume_int(struct fxgmac_pdata *pdata) #endif } +static void fxgmac_config_wol_wait_time(struct fxgmac_pdata *pdata) +{ + u32 regval; + + regval = readreg(pdata->pAdapter, pdata->base_mem + WOL_CTL); + regval = FXGMAC_SET_REG_BITS(regval, WOL_WAIT_TIME_POS, WOL_WAIT_TIME_LEN, + FXGMAC_WOL_WAIT_TIME); + writereg(pdata->pAdapter, regval, pdata->base_mem + WOL_CTL); +} + static int fxgmac_hw_init(struct fxgmac_pdata *pdata) { struct fxgmac_desc_ops *desc_ops = &pdata->desc_ops; @@ -5167,7 +5344,7 @@ static int fxgmac_hw_init(struct fxgmac_pdata *pdata) u32 regval = 0; if (netif_msg_drv(pdata)) { - DPRINTK("fxgmac hw init call in\n"); + DPRINTK("fxgmac hw init call in regval %x\n", regval); } /* Flush Tx queues */ @@ -5222,6 +5399,8 @@ static int fxgmac_hw_init(struct fxgmac_pdata *pdata) fxgmac_config_mmc(pdata); fxgmac_enable_mac_interrupts(pdata); + fxgmac_config_wol_wait_time(pdata); + /* enable EPhy link change interrupt */ fxgmac_read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); /* clear phy interrupt */ @@ -5233,7 +5412,7 @@ static int fxgmac_hw_init(struct fxgmac_pdata *pdata) regval); /* enable phy interrupt */ if (netif_msg_drv(pdata)) { - DPRINTK("fxgmac hw init callout\n"); + DPRINTK("fxgmac hw init callout %x\n", regval); } return 0; } @@ -5450,6 +5629,71 @@ static int fxgmac_pcie_init(struct fxgmac_pdata *pdata, bool ltr_en, return 0; } +static void fxgmac_clear_misc_int_status(struct fxgmac_pdata *pdata) +{ + struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; + u32 regval, i, q_count; + + /* clear phy interrupt status */ + hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); + hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); + /* clear other interrupt status of misc interrupt */ + regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_ISR); + if (regval) { + if (regval & (1 << MGMT_MAC_PHYIF_STA_POS)) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_PHYIF_STA); + + if ((regval & (1 << MGMT_MAC_AN_SR0_POS)) || + (regval & (1 << MGMT_MAC_AN_SR0_POS)) || + (regval & (1 << MGMT_MAC_AN_SR0_POS))) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_AN_SR); + + if (regval & (1 << MGMT_MAC_PMT_STA_POS)) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_PMT_STA); + + if (regval & (1 << MGMT_MAC_LPI_STA_POS)) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_LPI_STA); + + if (regval & (1 << MGMT_MAC_MMC_STA_POS)) { + if (regval & (1 << MGMT_MAC_RX_MMC_STA_POS)) + hw_ops->rx_mmc_int(pdata); + + if (regval & (1 << MGMT_MAC_TX_MMC_STA_POS)) + hw_ops->tx_mmc_int(pdata); + + if (regval & (1 << MGMT_MMC_IPCRXINT_POS)) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MMC_IPCRXINT); + + } + + if ((regval & (1 << MGMT_MAC_TX_RX_STA0_POS)) || (regval & (1 << MGMT_MAC_TX_RX_STA1_POS))) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_TX_RX_STA); + + if (regval & (1 << MGMT_MAC_GPIO_SR_POS)) + pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_GPIO_SR); + } + + /* MTL_Interrupt_Status, write 1 clear */ + regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_INT_SR); + pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_INT_SR, regval); + + /* MTL_Q(#i)_Interrupt_Control_Status, write 1 clear */ + q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt); + for (i = 0; i < q_count; i++) { + /* Clear all the interrupts which are set */ + regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_Q_INT_CTL_SR + i * MTL_Q_INC); + pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_Q_INT_CTL_SR + i * MTL_Q_INC, regval); + } + + /* MTL_ECC_Interrupt_Status, write 1 clear */ + regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_ECC_INT_SR); + pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_ECC_INT_SR, regval); + + /* DMA_ECC_Interrupt_Status, write 1 clear */ + regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + DMA_ECC_INT_SR); + pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + DMA_ECC_INT_SR, regval); +} + static void fxgmac_trigger_pcie(struct fxgmac_pdata *pdata, u32 code) { writereg(pdata->pAdapter, code, pdata->base_mem + REG_PCIE_TRIGGER); @@ -5486,9 +5730,10 @@ void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops) hw_ops->enable_mgm_interrupt = fxgmac_enable_mgm_interrupt; hw_ops->disable_mgm_interrupt = fxgmac_disable_mgm_interrupt; hw_ops->dismiss_all_int = fxgmac_dismiss_all_int; + hw_ops->clear_misc_int_status = fxgmac_clear_misc_int_status; hw_ops->set_mac_address = fxgmac_set_mac_address; - hw_ops->set_mac_hash = fxgmac_add_mac_addresses; + hw_ops->set_mac_hash = fxgmac_set_mc_addresses; hw_ops->config_rx_mode = fxgmac_config_rx_mode; hw_ops->enable_rx_csum = fxgmac_enable_rx_csum; hw_ops->disable_rx_csum = fxgmac_disable_rx_csum; @@ -5545,6 +5790,7 @@ void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops) hw_ops->config_tx_pbl_val = fxgmac_config_tx_pbl_val; hw_ops->get_tx_pbl_val = fxgmac_get_tx_pbl_val; hw_ops->config_pblx8 = fxgmac_config_pblx8; + hw_ops->calculate_max_checksum_size = fxgmac_calculate_max_checksum_size; /* For MMC statistics support */ hw_ops->tx_mmc_int = fxgmac_tx_mmc_int; @@ -5583,7 +5829,7 @@ void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops) hw_ops->enable_wake_pattern = fxgmac_enable_wake_pattern; hw_ops->disable_wake_pattern = fxgmac_disable_wake_pattern; hw_ops->set_wake_pattern_mask = fxgmac_set_wake_pattern_mask; -#if FUXI_PM_WPI_READ_FEATURE_EN +#if FXGMAC_PM_WPI_READ_FEATURE_ENABLED hw_ops->enable_wake_packet_indication = fxgmac_enable_wake_packet_indication; hw_ops->get_wake_packet_indication = fxgmac_get_wake_packet_indication; @@ -5629,6 +5875,10 @@ void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops) hw_ops->enable_rx_broadcast = fxgmac_enable_rx_broadcast; /* efuse relevant operation. */ + hw_ops->read_patch_from_efuse_per_index = fxgmac_read_patch_from_efuse_per_index; /* read patch per index. */ + hw_ops->read_mac_subsys_from_efuse = fxgmac_read_mac_subsys_from_efuse; + hw_ops->read_efuse_data = fxgmac_efuse_read_data; +#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE hw_ops->read_patch_from_efuse = fxgmac_read_patch_from_efuse; /* read patch per register. */ hw_ops->read_patch_from_efuse_per_index = @@ -5636,14 +5886,13 @@ void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops) hw_ops->write_patch_to_efuse = fxgmac_write_patch_to_efuse; hw_ops->write_patch_to_efuse_per_index = fxgmac_write_patch_to_efuse_per_index; - hw_ops->read_mac_subsys_from_efuse = fxgmac_read_mac_subsys_from_efuse; hw_ops->write_mac_subsys_to_efuse = fxgmac_write_mac_subsys_to_efuse; hw_ops->efuse_load = fxgmac_efuse_load; - hw_ops->read_efuse_data = fxgmac_efuse_read_data; hw_ops->write_oob = fxgmac_efuse_write_oob; hw_ops->write_led = fxgmac_efuse_write_led; hw_ops->write_led_config = fxgmac_write_led_setting_to_efuse; hw_ops->read_led_config = fxgmac_read_led_setting_from_efuse; +#endif /* */ hw_ops->pcie_init = fxgmac_pcie_init; diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ioctl.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ioctl.c new file mode 100644 index 0000000000000..e679d8abffbc3 --- /dev/null +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-ioctl.c @@ -0,0 +1,521 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2021 Motorcomm Corporation. */ + +#include "fuxi-gmac.h" +#include "fuxi-gmac-reg.h" + +static void fxgmac_dbg_tx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data) +{ + unsigned int pktLen = 0; + struct sk_buff *skb; + pfxgmac_test_packet pPkt; + u8 *pTx_data = NULL; + u8 *pSkb_data = NULL; + u32 offload_len = 0; + u8 ipHeadLen, tcpHeadLen, headTotalLen; + static u32 lastGsoSize = 806;//initial default value + //int i = 0; + + /* get fxgmac_test_packet */ + pPkt = (pfxgmac_test_packet)(pcmd_data + sizeof(struct ext_ioctl_data)); + pktLen = pPkt->length; + + /* get pkt data */ + pTx_data = (u8 *)pPkt + sizeof(fxgmac_test_packet); + + /* alloc sk_buff */ + skb = alloc_skb(pktLen, GFP_ATOMIC); + if (!skb) { + DPRINTK("alloc skb fail\n"); + return; + } + + /* copy data to skb */ + pSkb_data = skb_put(skb, pktLen); + memset(pSkb_data, 0, pktLen); + memcpy(pSkb_data, pTx_data, pktLen); + + /* set skb parameters */ + skb->dev = pdata->netdev; + skb->pkt_type = PACKET_OUTGOING; + skb->protocol = ntohs(ETH_P_IP); + skb->no_fcs = 1; + skb->ip_summed = CHECKSUM_PARTIAL; + if (skb->len > 1514) { + /* TSO packet */ + /* set tso test flag */ + pdata->expansion.fxgmac_test_tso_flag = true; + + /* get protocol head length */ + ipHeadLen = (pSkb_data[TEST_MAC_HEAD] & 0xF) * 4; + tcpHeadLen = (pSkb_data[TEST_MAC_HEAD + ipHeadLen + TEST_TCP_HEAD_LEN_OFFSET] >> 4 & 0xF) * 4; + headTotalLen = TEST_MAC_HEAD + ipHeadLen + tcpHeadLen; + offload_len = (pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET] << 8 | + pSkb_data[TEST_TCP_OFFLOAD_LEN_OFFSET + 1]) & 0xFFFF; + /* set tso skb parameters */ + //skb->ip_summed = CHECKSUM_PARTIAL; + skb->transport_header = ipHeadLen + TEST_MAC_HEAD; + skb->network_header = TEST_MAC_HEAD; + skb->inner_network_header = TEST_MAC_HEAD; + skb->mac_len = TEST_MAC_HEAD; + + /* set skb_shinfo parameters */ + if (tcpHeadLen > TEST_TCP_FIX_HEAD_LEN) { + skb_shinfo(skb)->gso_size = (pSkb_data[TEST_TCP_MSS_OFFSET] << 8 | + pSkb_data[TEST_TCP_MSS_OFFSET + 1]) & 0xFFFF; + } else { + skb_shinfo(skb)->gso_size = 0; + } + if (skb_shinfo(skb)->gso_size != 0) { + lastGsoSize = skb_shinfo(skb)->gso_size; + } else { + skb_shinfo(skb)->gso_size = lastGsoSize; + } + //DPRINTK("offload_len is %d, skb_shinfo(skb)->gso_size is %d", offload_len, skb_shinfo(skb)->gso_size); + /* get segment size */ + if (offload_len % skb_shinfo(skb)->gso_size == 0) { + skb_shinfo(skb)->gso_segs = offload_len / skb_shinfo(skb)->gso_size; + pdata->expansion.fxgmac_test_last_tso_len = skb_shinfo(skb)->gso_size + headTotalLen; + } else { + skb_shinfo(skb)->gso_segs = offload_len / skb_shinfo(skb)->gso_size + 1; + pdata->expansion.fxgmac_test_last_tso_len = offload_len % skb_shinfo(skb)->gso_size + headTotalLen; + } + pdata->expansion.fxgmac_test_tso_seg_num = skb_shinfo(skb)->gso_segs; + + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + skb_shinfo(skb)->frag_list = NULL; + skb->csum_start = skb_headroom(skb) + TEST_MAC_HEAD + ipHeadLen; + skb->csum_offset = skb->len - TEST_MAC_HEAD - ipHeadLen; + + pdata->expansion.fxgmac_test_packet_len = skb_shinfo(skb)->gso_size + headTotalLen; + } else { + /* set non-TSO packet parameters */ + pdata->expansion.fxgmac_test_packet_len = skb->len; + } + + /* send data */ + if (dev_queue_xmit(skb) != NET_XMIT_SUCCESS) + DPRINTK("xmit data fail \n"); +} + +static void fxgmac_dbg_rx_pkt(struct fxgmac_pdata *pdata, u8 *pcmd_data) +{ + unsigned int totalLen = 0; + struct sk_buff *rx_skb; + struct ext_ioctl_data *pcmd; + fxgmac_test_packet pkt; + void *addr = 0; + u8 *rx_data = (u8 *)kzalloc(FXGMAC_MAX_DBG_RX_DATA, GFP_KERNEL); + if (!rx_data) + return; + + /* initial dest data region */ + pcmd = (struct ext_ioctl_data *)pcmd_data; + addr = pcmd->cmd_buf.buf; + while (pdata->expansion.fxgmac_test_skb_arr_in_index != pdata->expansion.fxgmac_test_skb_arr_out_index) { + /* get received skb data */ + rx_skb = pdata->expansion.fxgmac_test_skb_array[pdata->expansion.fxgmac_test_skb_arr_out_index]; + + if (rx_skb->len + sizeof(fxgmac_test_packet) + totalLen < 64000) { + pkt.length = rx_skb->len; + pkt.type = 0x80; + pkt.buf[0].offset = totalLen + sizeof(fxgmac_test_packet); + pkt.buf[0].length = rx_skb->len; + + /* get data from skb */ + //DPRINTK("FXG:rx_skb->len=%d", rx_skb->len); + memcpy(rx_data, rx_skb->data, rx_skb->len); + + /* update next pointer */ + if ((pdata->expansion.fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT == pdata->expansion.fxgmac_test_skb_arr_in_index) { + pkt.next = NULL; + } else { + pkt.next = (pfxgmac_test_packet)(addr + totalLen + sizeof(fxgmac_test_packet) + pkt.length); + } + + /* copy data to user space */ + if (copy_to_user((void *)(addr + totalLen), (void *)(&pkt), sizeof(fxgmac_test_packet))) { + DPRINTK("cppy pkt data to user fail..."); + } + //FXGMAC_PR("FXG:rx_skb->len=%d", rx_skb->len); + if (copy_to_user((void *)(addr + totalLen + sizeof(fxgmac_test_packet)), (void *)rx_data, rx_skb->len)) { + DPRINTK("cppy data to user fail..."); + } + + /* update total length */ + totalLen += (sizeof(fxgmac_test_packet) + rx_skb->len); + + /* free skb */ + kfree_skb(rx_skb); + pdata->expansion.fxgmac_test_skb_array[pdata->expansion.fxgmac_test_skb_arr_out_index] = NULL; + + /* update gCurSkbOutIndex */ + pdata->expansion.fxgmac_test_skb_arr_out_index = (pdata->expansion.fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT; + } else { + DPRINTK("receive data more receive buffer... \n"); + break; + } + } + + if (rx_data) + kfree(rx_data); +} + +// Based on the current application scenario,we only use CMD_DATA for data. +// if you use other struct, you should recalculate in_total_size +long fxgmac_netdev_ops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + bool ret = true; + int regval = 0; + struct fxgmac_pdata *pdata = file->private_data; + struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; + FXGMAC_PDATA_OF_PLATFORM *ex = &pdata->expansion; + CMD_DATA ex_data; + struct ext_ioctl_data pcmd; + u8 *data = NULL; + u8 *buf = NULL; + int in_total_size, in_data_size, out_total_size; + int ioctl_cmd_size = sizeof(struct ext_ioctl_data); + u8 mac[ETH_ALEN] = {0}; + struct sk_buff *tmpskb; + + if (!arg) { + DPRINTK("[%s] command arg is %lx !\n", __func__, arg); + goto err; + } + + /* check device type */ + if (_IOC_TYPE(cmd) != IOC_MAGIC) { + DPRINTK("[%s] command type [%c] error!\n", __func__, _IOC_TYPE(cmd)); + goto err; + } + + /* check command number*/ + if (_IOC_NR(cmd) > IOC_MAXNR) { + DPRINTK("[%s] command number [%d] exceeded!\n", __func__, _IOC_NR(cmd)); + goto err; + } + + //buf = (u8*)kzalloc(FXGMAC_MAX_DBG_BUF_LEN, GFP_KERNEL); + if (copy_from_user(&pcmd, (void *)arg, ioctl_cmd_size)) { + DPRINTK("copy data from user fail... \n"); + goto err; + } + + in_total_size = pcmd.cmd_buf.size_in; + in_data_size = in_total_size - ioctl_cmd_size; + out_total_size = pcmd.cmd_buf.size_out; + + buf = (u8 *)kzalloc(in_total_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, (void *)arg, in_total_size)) { + DPRINTK("copy data from user fail... \n"); + goto err; + } + data = buf + ioctl_cmd_size; + + if (arg != 0) { + switch (pcmd.cmd_type) { + /* ioctl diag begin */ + case FXGMAC_DFS_IOCTL_DIAG_BEGIN: + DPRINTK("Debugfs received diag begin command.\n"); + if (netif_running(pdata->netdev)) + fxgmac_restart_dev(pdata); + + /* release last loopback test abnormal exit buffer */ + while (ex->fxgmac_test_skb_arr_in_index != + ex->fxgmac_test_skb_arr_out_index) { + tmpskb = ex->fxgmac_test_skb_array[ex->fxgmac_test_skb_arr_out_index]; + if (tmpskb) { + kfree_skb(tmpskb); + ex->fxgmac_test_skb_array[ex->fxgmac_test_skb_arr_out_index] = NULL; + } + + ex->fxgmac_test_skb_arr_out_index = (ex->fxgmac_test_skb_arr_out_index + 1) % FXGMAC_MAX_DBG_TEST_PKT; + } + + /* init loopback test parameters */ + ex->fxgmac_test_skb_arr_in_index = 0; + ex->fxgmac_test_skb_arr_out_index = 0; + ex->fxgmac_test_tso_flag = false; + ex->fxgmac_test_tso_seg_num = 0; + ex->fxgmac_test_last_tso_len = 0; + ex->fxgmac_test_packet_len = 0; + break; + + /* ioctl diag end */ + case FXGMAC_DFS_IOCTL_DIAG_END: + DPRINTK("Debugfs received diag end command.\n"); + if (netif_running(pdata->netdev)) + fxgmac_restart_dev(pdata); + + break; + + /* ioctl diag tx pkt */ + case FXGMAC_DFS_IOCTL_DIAG_TX_PKT: + fxgmac_dbg_tx_pkt(pdata, buf); + break; + + /* ioctl diag rx pkt */ + case FXGMAC_DFS_IOCTL_DIAG_RX_PKT: + fxgmac_dbg_rx_pkt(pdata, buf); + break; + + /* ioctl device reset */ + case FXGMAC_DFS_IOCTL_DEVICE_RESET: + DPRINTK("Debugfs received device reset command.\n"); + if (netif_running(pdata->netdev)) + fxgmac_restart_dev(pdata); + + break; + + case FXGMAC_EFUSE_LED_TEST: + DPRINTK("Debugfs received device led test command.\n"); + memcpy(&pdata->led, data, sizeof(struct led_setting)); + fxgmac_restart_dev(pdata); + break; + + case FXGMAC_EFUSE_UPDATE_LED_CFG: + DPRINTK("Debugfs received device led update command.\n"); + memcpy(&pdata->ledconfig, data, sizeof(struct led_setting)); + ret = hw_ops->write_led_config(pdata); + hw_ops->read_led_config(pdata); + hw_ops->led_under_active(pdata); + break; + + case FXGMAC_EFUSE_WRITE_LED: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + DPRINTK("FXGMAC_EFUSE_WRITE_LED, val = 0x%x\n", ex_data.val0); + ret = hw_ops->write_led(pdata, ex_data.val0); + break; + + case FXGMAC_EFUSE_WRITE_OOB: + DPRINTK("FXGMAC_EFUSE_WRITE_OOB.\n"); + ret = hw_ops->write_oob(pdata); + break; + + case FXGMAC_EFUSE_READ_REGIONABC: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->read_efuse_data(pdata, ex_data.val0, &ex_data.val1); + /* + * DPRINTK("FXGMAC_EFUSE_READ_REGIONABC, address = 0x%x, val = 0x%x\n", + * ex_data.val0, + * ex_data.val1); + */ + if (ret) { + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + break; + + case FXGMAC_EFUSE_WRITE_PATCH_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + /* + * DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_REG, address = 0x%x, val = 0x%x\n", + * ex_data.val0, + * ex_data.val1); + */ + ret = hw_ops->write_patch_to_efuse(pdata, ex_data.val0, ex_data.val1); + break; + + case FXGMAC_EFUSE_READ_PATCH_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->read_patch_from_efuse(pdata, ex_data.val0, &ex_data.val1); + /* + * DPRINTK("FXGMAC_EFUSE_READ_PATCH_REG, address = 0x%x, val = 0x%x\n", + * ex_data.val0, ex_data.val1); + */ + if (ret) { + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + break; + + case FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->write_patch_to_efuse_per_index(pdata, ex_data.val0, + ex_data.val1, + ex_data.val2); + /* DPRINTK("FXGMAC_EFUSE_WRITE_PATCH_PER_INDEX, index = %d, address = 0x%x, val = 0x%x\n", + * ex_data.val0, ex_data.val1, ex_data.val2); + */ + break; + + case FXGMAC_EFUSE_READ_PATCH_PER_INDEX: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->read_patch_from_efuse_per_index(pdata, ex_data.val0, + &ex_data.val1, + &ex_data.val2); + /* DPRINTK("FXGMAC_EFUSE_READ_PATCH_PER_INDEX, address = 0x%x, val = 0x%x\n", + * ex_data.val1, ex_data.val2); + */ + if (ret) { + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + break; + + case FXGMAC_EFUSE_LOAD: + DPRINTK("FXGMAC_EFUSE_LOAD.\n"); + ret = hw_ops->efuse_load(pdata); + break; + + case FXGMAC_GET_MAC_DATA: + ret = hw_ops->read_mac_subsys_from_efuse(pdata, mac, NULL, NULL); + if (ret) { + memcpy(data, mac, ETH_ALEN); + out_total_size = ioctl_cmd_size + ETH_ALEN; + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + break; + + case FXGMAC_SET_MAC_DATA: + if (in_data_size != ETH_ALEN) + goto err; + memcpy(mac, data, ETH_ALEN); + ret = hw_ops->write_mac_subsys_to_efuse(pdata, mac, NULL, NULL); + if (ret) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)) + eth_hw_addr_set(pdata->netdev, mac); +#else + memcpy(pdata->netdev->dev_addr, mac, ETH_ALEN); +#endif + + memcpy(pdata->mac_addr, mac, ETH_ALEN); + + hw_ops->set_mac_address(pdata, mac); + hw_ops->set_mac_hash(pdata); + } + break; + + case FXGMAC_GET_SUBSYS_ID: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->read_mac_subsys_from_efuse(pdata, + NULL, + &ex_data.val0, + NULL); + if (ret) { + ex_data.val1 = 0xFFFF; // invalid value + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + break; + + case FXGMAC_SET_SUBSYS_ID: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ret = hw_ops->write_mac_subsys_to_efuse(pdata, + NULL, + &ex_data.val0, + NULL); + break; + + case FXGMAC_GET_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + ex_data.val1 = hw_ops->get_gmac_register(pdata, + (u8 *)(pdata->base_mem + ex_data.val0)); + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + break; + + case FXGMAC_SET_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + regval = hw_ops->set_gmac_register(pdata, + (u8 *)(pdata->base_mem + ex_data.val0), + ex_data.val1); + ret = (regval == 0 ? true : false); + break; + + case FXGMAC_GET_PHY_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + regval = hw_ops->read_ephy_reg(pdata, ex_data.val0, &ex_data.val1); + if (regval != -1) { + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + } + ret = (regval == -1 ? false : true); + break; + + case FXGMAC_SET_PHY_REG: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + regval = hw_ops->write_ephy_reg(pdata, ex_data.val0, ex_data.val1); + ret = (regval == 0 ? true : false); + break; + + case FXGMAC_GET_PCIE_LOCATION: + ex_data.val0 = pdata->pdev->bus->number; + ex_data.val1 = PCI_SLOT(pdata->pdev->devfn); + ex_data.val2 = PCI_FUNC(pdata->pdev->devfn); + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + break; + + case FXGMAC_GET_GSO_SIZE: + ex_data.val0 = pdata->netdev->gso_max_size; + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + break; + + case FXGMAC_SET_GSO_SIZE: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + pdata->netdev->gso_max_size = ex_data.val0; + break; + + case FXGMAC_SET_RX_MODERATION: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD); + regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_RX_POS, INT_MOD_RX_LEN, ex_data.val0); + writereg(pdata->pAdapter, regval, pdata->base_mem + INT_MOD); + break; + + case FXGMAC_SET_TX_MODERATION: + memcpy(&ex_data, data, sizeof(CMD_DATA)); + regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD); + regval = FXGMAC_SET_REG_BITS(regval, INT_MOD_TX_POS, INT_MOD_TX_LEN, ex_data.val0); + writereg(pdata->pAdapter, regval, pdata->base_mem + INT_MOD); + break; + + case FXGMAC_GET_TXRX_MODERATION: + regval = readreg(pdata->pAdapter, pdata->base_mem + INT_MOD); + ex_data.val0 = FXGMAC_GET_REG_BITS(regval, INT_MOD_RX_POS, INT_MOD_RX_LEN); + ex_data.val1 = FXGMAC_GET_REG_BITS(regval, INT_MOD_TX_POS, INT_MOD_TX_LEN); + memcpy(data, &ex_data, sizeof(CMD_DATA)); + out_total_size = ioctl_cmd_size + sizeof(CMD_DATA); + if (copy_to_user((void *)arg, (void *)buf, out_total_size)) + goto err; + break; + + default: + DPRINTK("Debugfs received invalid command: %x.\n", pcmd.cmd_type); + ret = false; + break; + } + } + + if (buf) + kfree(buf); + return ret ? FXGMAC_SUCCESS : FXGMAC_FAIL; + +err: + if (buf) + kfree(buf); + return FXGMAC_FAIL; +} diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-net.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-net.c index 305a46a0afaf1..3fc29f1b40bc4 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-net.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-net.c @@ -1,13 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#include -#include -#include -#include -#include -#include - #include "fuxi-os.h" #include "fuxi-gmac.h" #include "fuxi-gmac-reg.h" @@ -15,6 +8,8 @@ static int fxgmac_one_poll_rx(struct napi_struct *, int); static int fxgmac_one_poll_tx(struct napi_struct *, int); static int fxgmac_all_poll(struct napi_struct *, int); +static int fxgmac_dev_read(struct fxgmac_channel *channel); + void fxgmac_lock(struct fxgmac_pdata *pdata) { @@ -460,8 +455,13 @@ static void fxgmac_prep_tx_pkt(struct fxgmac_pdata *pdata, static int fxgmac_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu) { unsigned int rx_buf_size; + unsigned int max_mtu; - if (mtu > FXGMAC_JUMBO_PACKET_MTU) { + /* On the Linux platform, the MTU size does not include the length + * of the MAC address and the length of the Type, but FXGMAC_JUMBO_PACKET_MTU include them. + */ + max_mtu = FXGMAC_JUMBO_PACKET_MTU - ETH_HLEN; + if (mtu > max_mtu) { netdev_alert(netdev, "MTU exceeds maximum supported value\n"); return -EINVAL; } @@ -499,66 +499,12 @@ static void fxgmac_enable_rx_tx_ints(struct fxgmac_pdata *pdata) } } -static void fxgmac_phy_process(struct fxgmac_pdata *pdata) -{ - int cur_link = 0; - int regval = 0; - int cur_speed = 0; - struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; - - regval = hw_ops->get_ephy_state(pdata); - - /* We should make sure that PHY is done with the reset */ - if (regval & MGMT_EPHY_CTRL_STA_EPHY_RESET) { - pdata->expansion.phy_link = false; - return; - } - - cur_link = FXGMAC_GET_REG_BITS(regval, - MGMT_EPHY_CTRL_STA_EPHY_LINKUP_POS, - MGMT_EPHY_CTRL_STA_EPHY_LINKUP_LEN); - if (pdata->expansion.phy_link != cur_link) { - pdata->expansion.phy_link = cur_link; - if (pdata->expansion.phy_link) { - cur_speed = FXGMAC_GET_REG_BITS( - regval, MGMT_EPHY_CTRL_STA_SPEED_POS, - MGMT_EPHY_CTRL_STA_SPEED_LEN); - pdata->phy_speed = (cur_speed == 2) ? SPEED_1000 : - (cur_speed == 1) ? SPEED_100 : - SPEED_10; - pdata->phy_duplex = FXGMAC_GET_REG_BITS( - regval, MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_POS, - MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_LEN); - hw_ops->config_mac_speed(pdata); - - hw_ops->enable_rx(pdata); - hw_ops->enable_tx(pdata); - netif_carrier_on(pdata->netdev); - if (netif_running(pdata->netdev)) { - netif_tx_wake_all_queues(pdata->netdev); - dev_info(pdata->dev, "%s now is link up, mac_speed=%d.\n", - netdev_name(pdata->netdev), - pdata->phy_speed); - } - } else { - netif_carrier_off(pdata->netdev); - netif_tx_stop_all_queues(pdata->netdev); - pdata->phy_speed = SPEED_UNKNOWN; - pdata->phy_duplex = DUPLEX_UNKNOWN; - hw_ops->disable_rx(pdata); - hw_ops->disable_tx(pdata); - dev_info(pdata->dev, "%s now is link down\n", netdev_name(pdata->netdev)); - } - } -} - static int fxgmac_misc_poll(struct napi_struct *napi, int budget) { struct fxgmac_pdata *pdata = container_of(napi, struct fxgmac_pdata, expansion.napi_misc); struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; - fxgmac_phy_process(pdata); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) if (napi_complete_done(napi, 0)) hw_ops->enable_msix_one_interrupt(pdata, MSI_ID_PHY_OTHER); @@ -570,71 +516,6 @@ static int fxgmac_misc_poll(struct napi_struct *napi, int budget) return 0; } -static void fxgmac_clear_misc_int_status(struct fxgmac_pdata *pdata) -{ - struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; - u32 regval, i, q_count; - - /* clear phy interrupt status */ - hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); - /* clear other interrupt status of misc interrupt */ - regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_ISR); - if (regval) { - if (regval & (1 << 0)) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_PHYIF_STA); - } - if ((regval & (1 << 1)) || (regval & (1 << 2)) || (regval & (1 << 3))) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_AN_SR); - } - if (regval & (1 << 4)) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_PMT_STA); - } - if (regval & (1 << 5)) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_LPI_STA); - } - if (regval & (1 << 8)) { - if (regval & (1 << 9)) { - hw_ops->rx_mmc_int(pdata); - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MMC_RISR); - } - if (regval & (1 << 10)) { - hw_ops->tx_mmc_int(pdata); - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MMC_TISR); - } - if (regval & (1 << 11)) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MMC_IPCRXINT); - } - } - if ((regval & (1 << 13)) || (regval & (1 << 14))) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_TX_RX_STA); - } - - if (regval & (1 << 15)) { - pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MAC_GPIO_SR); - } - } - - /* MTL_Interrupt_Status, write 1 clear */ - regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_INT_SR); - pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_INT_SR, regval); - - /* MTL_Q(#i)_Interrupt_Control_Status, write 1 clear */ - q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt); - for (i = 0; i < q_count; i++) { - /* Clear all the interrupts which are set */ - regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_Q_INT_CTL_SR + i * MTL_Q_INC); - pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_Q_INT_CTL_SR + i * MTL_Q_INC, regval); - } - - /* MTL_ECC_Interrupt_Status, write 1 clear */ - regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + MTL_ECC_INT_SR); - pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + MTL_ECC_INT_SR, regval); - - /* DMA_ECC_Interrupt_Status, write 1 clear */ - regval = pdata->hw_ops.get_gmac_register(pdata, pdata->mac_regs + DMA_ECC_INT_SR); - pdata->hw_ops.set_gmac_register(pdata, pdata->mac_regs + DMA_ECC_INT_SR, regval); -} - static irqreturn_t fxgmac_misc_isr(int irq, void *data) { struct fxgmac_pdata *pdata = data; @@ -642,32 +523,28 @@ static irqreturn_t fxgmac_misc_isr(int irq, void *data) u32 regval; regval = readreg(pdata->pAdapter, pdata->base_mem + MGMT_INT_CTRL0); - if (!(regval & MGMT_INT_CTRL0_INT_STATUS_PHY)) + if (!(regval & MGMT_INT_CTRL0_INT_STATUS_MISC)) return IRQ_HANDLED; hw_ops->disable_msix_one_interrupt(pdata, MSI_ID_PHY_OTHER); - fxgmac_clear_misc_int_status(pdata); + hw_ops->clear_misc_int_status(pdata); - if (napi_schedule_prep(&pdata->expansion.napi_misc)) { - __napi_schedule_irqoff(&pdata->expansion.napi_misc); - } + napi_schedule_irqoff(&pdata->expansion.napi_misc); return IRQ_HANDLED; } static irqreturn_t fxgmac_isr(int irq, void *data) { - unsigned int dma_isr, dma_ch_isr, mac_isr; + unsigned int dma_ch_isr; struct fxgmac_pdata *pdata = data; struct fxgmac_channel *channel; struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; unsigned int i; u32 val; - dma_isr = readreg(pdata->pAdapter, pdata->mac_regs + DMA_ISR); - val = readreg(pdata->pAdapter, pdata->base_mem + MGMT_INT_CTRL0); - if (!(val & MGMT_INT_CTRL0_INT_STATUS_RXTXPHY_MASK)) + if (!(val & MGMT_INT_CTRL0_INT_STATUS_RXTXMISC_MASK)) return IRQ_HANDLED; hw_ops->disable_mgm_interrupt(pdata); @@ -707,25 +584,9 @@ static irqreturn_t fxgmac_isr(int irq, void *data) writel(dma_ch_isr, FXGMAC_DMA_REG(channel, DMA_CH_SR)); } - if (FXGMAC_GET_REG_BITS(dma_isr, DMA_ISR_MACIS_POS, - DMA_ISR_MACIS_LEN)) { - mac_isr = readl(pdata->mac_regs + MAC_ISR); - - if (FXGMAC_GET_REG_BITS(mac_isr, MAC_ISR_MMCTXIS_POS, - MAC_ISR_MMCTXIS_LEN)) - hw_ops->tx_mmc_int(pdata); - - if (FXGMAC_GET_REG_BITS(mac_isr, MAC_ISR_MMCRXIS_POS, - MAC_ISR_MMCRXIS_LEN)) - hw_ops->rx_mmc_int(pdata); - - /* Clear all interrupt signals */ - writel(mac_isr, (pdata->mac_regs + MAC_ISR)); - } + if (pdata->expansion.mgm_intctrl_val & MGMT_INT_CTRL0_INT_STATUS_MISC) + hw_ops->clear_misc_int_status(pdata); - if (pdata->expansion.mgm_intctrl_val & MGMT_INT_CTRL0_INT_STATUS_PHY) { - fxgmac_clear_misc_int_status(pdata); - } if (napi_schedule_prep(&pdata->expansion.napi)) { pdata->stats.napi_poll_isr++; @@ -745,35 +606,31 @@ static irqreturn_t fxgmac_dma_isr(int irq, void *data) int message_id; if (irq == channel->expansion.dma_irq_tx) { - if (napi_schedule_prep(&channel->expansion.napi_tx)) { - message_id = MSI_ID_TXQ0; - hw_ops->disable_msix_one_interrupt(pdata, message_id); - regval = 0; - regval = FXGMAC_SET_REG_BITS(regval, DMA_CH_SR_TI_POS, - DMA_CH_SR_TI_LEN, 1); - writereg(pdata->pAdapter, regval, - FXGMAC_DMA_REG(channel, DMA_CH_SR)); - __napi_schedule_irqoff(&channel->expansion.napi_tx); - } + message_id = MSI_ID_TXQ0; + hw_ops->disable_msix_one_interrupt(pdata, message_id); + regval = 0; + regval = FXGMAC_SET_REG_BITS(regval, DMA_CH_SR_TI_POS, + DMA_CH_SR_TI_LEN, 1); + writereg(pdata->pAdapter, regval, + FXGMAC_DMA_REG(channel, DMA_CH_SR)); + napi_schedule_irqoff(&channel->expansion.napi_tx); } else { - if (napi_schedule_prep(&channel->expansion.napi_rx)) { - message_id = channel->queue_index; - hw_ops->disable_msix_one_interrupt(pdata, message_id); - regval = 0; - regval = readreg(pdata->pAdapter, - FXGMAC_DMA_REG(channel, DMA_CH_SR)); - regval = FXGMAC_SET_REG_BITS(regval, DMA_CH_SR_RI_POS, - DMA_CH_SR_RI_LEN, 1); - writereg(pdata->pAdapter, regval, + message_id = channel->queue_index; + hw_ops->disable_msix_one_interrupt(pdata, message_id); + regval = 0; + regval = readreg(pdata->pAdapter, FXGMAC_DMA_REG(channel, DMA_CH_SR)); - __napi_schedule_irqoff(&channel->expansion.napi_rx); - } + regval = FXGMAC_SET_REG_BITS(regval, DMA_CH_SR_RI_POS, + DMA_CH_SR_RI_LEN, 1); + writereg(pdata->pAdapter, regval, + FXGMAC_DMA_REG(channel, DMA_CH_SR)); + napi_schedule_irqoff(&channel->expansion.napi_rx); } return IRQ_HANDLED; } -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) static void fxgmac_tx_hang_timer_handler(struct timer_list *t) #else @@ -865,7 +722,7 @@ static void fxgmac_napi_enable(struct fxgmac_pdata *pdata, unsigned int add) for (i = 0; i < pdata->channel_count; i++, channel++) { if (!FXGMAC_GET_REG_BITS(rx_napi, i, FXGMAC_FLAG_PER_CHAN_RX_NAPI_FREE_LEN)) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) netif_napi_add_weight( pdata->netdev, &channel->expansion.napi_rx, @@ -885,7 +742,7 @@ static void fxgmac_napi_enable(struct fxgmac_pdata *pdata, unsigned int add) FXGMAC_NAPI_ENABLE); if (FXGMAC_IS_CHANNEL_WITH_TX_IRQ(i) && !tx_napi) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) netif_napi_add_weight( pdata->netdev, &channel->expansion.napi_tx, @@ -910,7 +767,7 @@ static void fxgmac_napi_enable(struct fxgmac_pdata *pdata, unsigned int add) /* for misc */ if (!misc_napi) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) netif_napi_add_weight(pdata->netdev, &pdata->expansion.napi_misc, fxgmac_misc_poll, NAPI_POLL_WEIGHT); #else @@ -930,7 +787,7 @@ static void fxgmac_napi_enable(struct fxgmac_pdata *pdata, unsigned int add) FXGMAC_FLAG_LEGACY_NAPI_FREE_LEN); if (!i) { if (add) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) netif_napi_add_weight(pdata->netdev, &pdata->expansion.napi, fxgmac_all_poll, @@ -1467,21 +1324,28 @@ int fxgmac_start(struct fxgmac_pdata *pdata) writel(0xF0000000, (volatile void *)(netdev->base_addr + MGMT_INT_CTRL0)); +#if FXGMAC_INT_MODERATION_ENABLED hw_ops->set_interrupt_moderation(pdata); +#endif if (pdata->per_channel_irq) hw_ops->enable_msix_rxtxphyinterrupt(pdata); fxgmac_enable_rx_tx_ints(pdata); + #ifdef FXGMAC_ESD_CHECK_ENABLED fxgmac_schedule_esd_work(pdata); #endif + fxgmac_set_phy_link_ksettings(pdata); hw_ops->led_under_active(pdata); pdata->expansion.dev_state = FXGMAC_DEV_START; + + fxgmac_phy_timer_init(pdata); return 0; err_napi: + fxgmac_phy_timer_destroy(pdata); fxgmac_napi_disable(pdata, 1); hw_ops->exit(pdata); dev_err(pdata->dev, "fxgmac start callout with irq err.\n"); @@ -1527,6 +1391,8 @@ void fxgmac_stop(struct fxgmac_pdata *pdata) netdev_tx_reset_queue(txq); } } + + fxgmac_phy_timer_destroy(pdata); } void fxgmac_restart_dev(struct fxgmac_pdata *pdata) @@ -1745,7 +1611,7 @@ static void fxgmac_tx_timeout(struct net_device *netdev, unsigned int unused) struct fxgmac_pdata *pdata = netdev_priv(netdev); netdev_warn(netdev, "tx timeout, device restarting\n"); -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED if (!pdata->tx_hang_restart_queuing) schedule_work(&pdata->expansion.restart_work); #else @@ -1759,13 +1625,11 @@ static netdev_tx_t fxgmac_xmit(struct sk_buff *skb, struct net_device *netdev) struct fxgmac_pkt_info *tx_pkt_info; struct fxgmac_desc_ops *desc_ops; struct fxgmac_channel *channel; - struct fxgmac_hw_ops *hw_ops; struct netdev_queue *txq; struct fxgmac_ring *ring; int ret; desc_ops = &pdata->desc_ops; - hw_ops = &pdata->hw_ops; if (netif_msg_tx_done(pdata)) DPRINTK("xmit callin, skb->len=%d, q=%d\n", skb->len, @@ -1908,7 +1772,7 @@ static int fxgmac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) switch (cmd) { case FXGMAC_DEV_CMD: - ret = fxgmac_dbg_netdev_ops_ioctl( + ret = fxgmac_netdev_ops_ioctl( &f, FXGMAC_IOCTL_DFS_COMMAND, (unsigned long)(ifr->ifr_data)); break; @@ -1931,12 +1795,16 @@ static int fxgmac_siocdevprivate(struct net_device *dev, struct ifreq *ifr, static int fxgmac_change_mtu(struct net_device *netdev, int mtu) { struct fxgmac_pdata *pdata = netdev_priv(netdev); - int ret; + int ret, max_mtu; #ifdef FXGMAC_DEBUG int old_mtu = netdev->mtu; #endif - if (mtu > FXGMAC_JUMBO_PACKET_MTU) { + /* On the Linux platform, the MTU size does not include the length + * of the MAC address and the length of the Type, but FXGMAC_JUMBO_PACKET_MTU include them. + */ + max_mtu = FXGMAC_JUMBO_PACKET_MTU - ETH_HLEN; + if (mtu > max_mtu) { netdev_alert(netdev, "MTU exceeds maximum supported value\n"); return -EINVAL; } @@ -1961,6 +1829,8 @@ static int fxgmac_change_mtu(struct net_device *netdev, int mtu) if (netif_running(netdev)) fxgmac_start(pdata); + netdev_update_features(netdev); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) DPRINTK("fxgmac, set MTU from %d to %d. min, max=(%d,%d)\n", old_mtu, netdev->mtu, netdev->min_mtu, netdev->max_mtu); @@ -2027,8 +1897,25 @@ static void fxgmac_poll_controller(struct net_device *netdev) } #endif /* CONFIG_NET_POLL_CONTROLLER */ +static netdev_features_t fxgmac_fix_features(struct net_device *netdev, + netdev_features_t features) +{ + u32 fifo_size; + struct fxgmac_pdata *pdata = netdev_priv(netdev); + struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; + + fifo_size = hw_ops->calculate_max_checksum_size(pdata); + + if (netdev->mtu > fifo_size) { + features &= ~NETIF_F_IP_CSUM; + features &= ~NETIF_F_IPV6_CSUM; + } + + return features; +} + static int fxgmac_set_features(struct net_device *netdev, - netdev_features_t features) + netdev_features_t features) { netdev_features_t rxhash, rxcsum, rxvlan, rxvlan_filter, tso; struct fxgmac_pdata *pdata = netdev_priv(netdev); @@ -2107,6 +1994,7 @@ static const struct net_device_ops fxgmac_netdev_ops = { .ndo_poll_controller = fxgmac_poll_controller, #endif .ndo_set_features = fxgmac_set_features, + .ndo_fix_features = fxgmac_fix_features, .ndo_set_rx_mode = fxgmac_set_rx_mode, }; @@ -2124,6 +2012,11 @@ static void fxgmac_rx_refresh(struct fxgmac_channel *channel) while (ring->dirty != ring->cur) { desc_data = FXGMAC_GET_DESC_DATA(ring, ring->dirty); + /* Reset desc_data values */ + desc_ops->unmap_desc_data(pdata, desc_data); + + if (desc_ops->map_rx_buffer(pdata, ring, desc_data)) + break; desc_ops->rx_desc_reset(pdata, desc_data, ring->dirty); ring->dirty = FXGMAC_GET_ENTRY(ring->dirty, ring->dma_desc_count); @@ -2147,19 +2040,27 @@ static struct sk_buff *fxgmac_create_skb(struct fxgmac_pdata *pdata, unsigned int len) { struct sk_buff *skb; - skb = __netdev_alloc_skb_ip_align(pdata->netdev, len, GFP_ATOMIC); - if (!skb) { - netdev_err(pdata->netdev, "%s: Rx init fails; skb is NULL\n", - __func__); + unsigned int copy_len; + u8 *packet; + + skb = napi_alloc_skb(napi, desc_data->rx.hdr.dma_len); + if (!skb) return NULL; - } - dma_sync_single_for_cpu(pdata->dev, desc_data->rx.buf.dma_base, len, - DMA_FROM_DEVICE); - skb_copy_to_linear_data(skb, desc_data->skb->data, len); - skb_put(skb, len); - dma_sync_single_for_device(pdata->dev, desc_data->rx.buf.dma_base, len, - DMA_FROM_DEVICE); + /* Start with the header buffer which may contain just the header + * or the header plus data + */ + dma_sync_single_range_for_cpu(pdata->dev, desc_data->rx.hdr.dma_base, + desc_data->rx.hdr.dma_off, + desc_data->rx.hdr.dma_len, + DMA_FROM_DEVICE); + + packet = page_address(desc_data->rx.hdr.pa.pages) + + desc_data->rx.hdr.pa.pages_offset; + copy_len = len; + copy_len = min(desc_data->rx.hdr.dma_len, copy_len); + skb_copy_to_linear_data(skb, packet, copy_len); + skb_put(skb, copy_len); return skb; } @@ -2181,8 +2082,11 @@ static int fxgmac_tx_poll(struct fxgmac_channel *channel) static int fxgmac_restart_need; static u32 change_cnt; static u32 reg_cur_pre = 0xffffffff; + (void) reg_cur_pre; + (void) change_cnt; + (void) fxgmac_restart_need; -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED static u32 reg_cur; #endif @@ -2268,7 +2172,7 @@ static int fxgmac_tx_poll(struct fxgmac_channel *channel) } } #endif -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED if ((!pdata->tx_hang_restart_queuing) && (!channel->expansion.tx_hang_timer_active)) { reg_cur = ring->dirty; @@ -2359,18 +2263,14 @@ static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget) struct fxgmac_pdata *pdata = channel->pdata; struct fxgmac_ring *ring = channel->rx_ring; struct net_device *netdev = pdata->netdev; - unsigned int len; + unsigned int len, max_len; unsigned int context_next, context; struct fxgmac_desc_data *desc_data; struct fxgmac_pkt_info *pkt_info; unsigned int incomplete; - struct fxgmac_hw_ops *hw_ops; struct napi_struct *napi; struct sk_buff *skb; int packet_count = 0; - u32 ipce, iphe; - - hw_ops = &pdata->hw_ops; /* Nothing to do if there isn't a Rx ring for this channel */ if (!ring) @@ -2426,15 +2326,6 @@ static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget) if (!context) { len = desc_data->rx.len; - if (len > pdata->rx_buf_size) { - if (net_ratelimit()) - netif_err(pdata, rx_err, netdev, - "len %d larger than size (%d)\n", - len, pdata->rx_buf_size); - pdata->netdev->stats.rx_length_errors++; - pdata->netdev->stats.rx_dropped++; - goto next_packet; - } if (len == 0) { if (net_ratelimit()) @@ -2455,6 +2346,21 @@ static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget) goto next_packet; } } + + max_len = netdev->mtu + ETH_HLEN; + if (!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX) && + skb->protocol == htons(ETH_P_8021Q)) + max_len += VLAN_HLEN; + if (len > max_len) { + if (net_ratelimit()) + netif_err(pdata, rx_err, netdev, + "len %d larger than max size %d\n", + len, max_len); + pdata->netdev->stats.rx_length_errors++; + pdata->netdev->stats.rx_dropped++; + dev_kfree_skb(skb); + goto next_packet; + } } if (!skb) { @@ -2466,23 +2372,8 @@ static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget) fxgmac_print_pkt(netdev, skb, false); skb_checksum_none_assert(skb); - if (netdev->features & NETIF_F_RXCSUM) { - ipce = FXGMAC_GET_REG_BITS_LE( - desc_data->dma_desc->desc1, - RX_NORMAL_DESC1_WB_IPCE_POS, - RX_NORMAL_DESC1_WB_IPCE_LEN); - iphe = FXGMAC_GET_REG_BITS_LE( - desc_data->dma_desc->desc1, - RX_NORMAL_DESC1_WB_IPHE_POS, - RX_NORMAL_DESC1_WB_IPHE_LEN); - /* if csum error, let the stack verify checksum errors.otherwise don't verify */ - if (!ipce && !iphe && - FXGMAC_GET_REG_BITS( - pkt_info->attributes, - RX_PACKET_ATTRIBUTES_CSUM_DONE_POS, - RX_PACKET_ATTRIBUTES_CSUM_DONE_LEN)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - } + if (netdev->features & NETIF_F_RXCSUM) + skb->ip_summed = CHECKSUM_UNNECESSARY; if (FXGMAC_GET_REG_BITS(pkt_info->attributes, RX_PACKET_ATTRIBUTES_VLAN_CTAG_POS, @@ -2621,8 +2512,6 @@ static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget) pdata->netdev->stats.rx_bytes += len; } - fxgmac_rx_refresh(channel); - return packet_count; } @@ -2630,11 +2519,10 @@ static int fxgmac_one_poll_tx(struct napi_struct *napi, int budget) { struct fxgmac_channel *channel = container_of(napi, struct fxgmac_channel, expansion.napi_tx); - int ret = 0; struct fxgmac_pdata *pdata = channel->pdata; struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; - ret = fxgmac_tx_poll(channel); + fxgmac_tx_poll(channel); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) if (napi_complete_done(napi, 0)) { hw_ops->enable_msix_one_interrupt(pdata, MSI_ID_TXQ0); @@ -2700,13 +2588,6 @@ static int fxgmac_all_poll(struct napi_struct *napi, int budget) } } while (false); - /* for phy, we needn't to process any packet, so processed will be 0 */ - if (pdata->expansion.mgm_intctrl_val & MGMT_INT_CTRL0_INT_STATUS_PHY) { - fxgmac_phy_process(pdata); - pdata->expansion.mgm_intctrl_val &= - ~MGMT_INT_CTRL0_INT_STATUS_PHY; - } - /* If we processed everything, we are done */ if (processed < budget) { /* Turn off polling */ @@ -3052,7 +2933,7 @@ static void fxgmac_get_rx_tstamp(struct fxgmac_pkt_info *pkt_info, } } -int fxgmac_dev_read(struct fxgmac_channel *channel) +static int fxgmac_dev_read(struct fxgmac_channel *channel) { struct fxgmac_pdata *pdata = channel->pdata; struct fxgmac_ring *ring = channel->rx_ring; @@ -3060,7 +2941,8 @@ int fxgmac_dev_read(struct fxgmac_channel *channel) struct fxgmac_desc_data *desc_data; struct fxgmac_dma_desc *dma_desc; struct fxgmac_pkt_info *pkt_info; - unsigned int err, etlt, l34t; + u32 ipce, iphe, rxparser; + unsigned int err, etlt; static unsigned int cnt_incomplete; @@ -3070,9 +2952,8 @@ int fxgmac_dev_read(struct fxgmac_channel *channel) /* Check for data availability */ if (FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, RX_NORMAL_DESC3_OWN_POS, - RX_NORMAL_DESC3_OWN_LEN)) { + RX_NORMAL_DESC3_OWN_LEN)) return 1; - } /* Make sure descriptor fields are read after reading the OWN bit */ dma_rmb(); @@ -3113,7 +2994,6 @@ int fxgmac_dev_read(struct fxgmac_channel *channel) if (desc_data->rx.hdr_len) pdata->stats.rx_split_header_packets++; } - l34t = 0; /* Get the pkt_info length */ desc_data->rx.len = FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, @@ -3145,47 +3025,52 @@ int fxgmac_dev_read(struct fxgmac_channel *channel) RX_PACKET_ATTRIBUTES_INCOMPLETE_LEN, 0); /* Set checksum done indicator as appropriate */ - if (netdev->features & NETIF_F_RXCSUM) - pkt_info->attributes = FXGMAC_SET_REG_BITS( - pkt_info->attributes, - RX_PACKET_ATTRIBUTES_CSUM_DONE_POS, - RX_PACKET_ATTRIBUTES_CSUM_DONE_LEN, 1); + if (netdev->features & NETIF_F_RXCSUM) { + ipce = FXGMAC_GET_REG_BITS_LE(desc_data->dma_desc->desc1, + RX_NORMAL_DESC1_WB_IPCE_POS, + RX_NORMAL_DESC1_WB_IPCE_LEN); + iphe = FXGMAC_GET_REG_BITS_LE(desc_data->dma_desc->desc1, + RX_NORMAL_DESC1_WB_IPHE_POS, + RX_NORMAL_DESC1_WB_IPHE_LEN); + if (!ipce && !iphe) + pkt_info->attributes = FXGMAC_SET_REG_BITS( + pkt_info->attributes, + RX_PACKET_ATTRIBUTES_CSUM_DONE_POS, + RX_PACKET_ATTRIBUTES_CSUM_DONE_LEN, + 1); + else + return 0; + } /* Check for errors (only valid in last descriptor) */ err = FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, RX_NORMAL_DESC3_ES_POS, RX_NORMAL_DESC3_ES_LEN); + /* b111: Incomplete parsing due to ECC error */ + rxparser = FXGMAC_GET_REG_BITS_LE(desc_data->dma_desc->desc2, + RX_NORMAL_DESC2_WB_RAPARSER_POS, + RX_NORMAL_DESC2_WB_RAPARSER_LEN); + if (err || rxparser == 0x7) { + pkt_info->errors = FXGMAC_SET_REG_BITS(pkt_info->errors, + RX_PACKET_ERRORS_FRAME_POS, + RX_PACKET_ERRORS_FRAME_LEN, 1); + return 0; + } + etlt = FXGMAC_GET_REG_BITS_LE(dma_desc->desc3, RX_NORMAL_DESC3_ETLT_POS, RX_NORMAL_DESC3_ETLT_LEN); - if ((err) && netif_msg_rx_status(pdata)) { - DPRINTK("dev_read:head_len=%u, pkt_len=%u, err=%u, etlt=%#x, desc2=0x%08x, desc3=0x%08x\n", - desc_data->rx.hdr_len, desc_data->rx.len, err, etlt, - dma_desc->desc2, dma_desc->desc3); - } - if (!err || !etlt) { - /* No error if err is 0 or etlt is 0 */ - if ((etlt == 0x4 /*yzhang changed to 0x4, 0x09*/) && - (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) { - pkt_info->attributes = FXGMAC_SET_REG_BITS( - pkt_info->attributes, - RX_PACKET_ATTRIBUTES_VLAN_CTAG_POS, - RX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN, 1); - pkt_info->vlan_ctag = FXGMAC_GET_REG_BITS_LE( - dma_desc->desc0, RX_NORMAL_DESC0_OVT_POS, - RX_NORMAL_DESC0_OVT_LEN); - netif_dbg(pdata, rx_status, netdev, "vlan-ctag=%#06x\n", - pkt_info->vlan_ctag); - } - } else { - if (etlt == 0x05 || etlt == 0x06) - pkt_info->attributes = FXGMAC_SET_REG_BITS( - pkt_info->attributes, - RX_PACKET_ATTRIBUTES_CSUM_DONE_POS, - RX_PACKET_ATTRIBUTES_CSUM_DONE_LEN, 0); - else - pkt_info->errors = FXGMAC_SET_REG_BITS( - pkt_info->errors, RX_PACKET_ERRORS_FRAME_POS, - RX_PACKET_ERRORS_FRAME_LEN, 1); + /* No error if err is 0 or etlt is 0 */ + if ((etlt == 0x4 /*yzhang changed to 0x4, 0x09*/) && + (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) { + pkt_info->attributes = FXGMAC_SET_REG_BITS( + pkt_info->attributes, + RX_PACKET_ATTRIBUTES_VLAN_CTAG_POS, + RX_PACKET_ATTRIBUTES_VLAN_CTAG_LEN, 1); + pkt_info->vlan_ctag = FXGMAC_GET_REG_BITS_LE( + dma_desc->desc0, RX_NORMAL_DESC0_OVT_POS, + RX_NORMAL_DESC0_OVT_LEN); + netif_dbg(pdata, rx_status, netdev, "vlan-ctag=%#06x\n", + pkt_info->vlan_ctag); } return 0; diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-pci.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-pci.c index 7899f36c17bd9..d1d008396a71f 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-pci.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-pci.c @@ -1,13 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#include -#include -#include - -/* for file operation */ -#include - #include "fuxi-gmac.h" #include "fuxi-gmac-reg.h" @@ -75,9 +68,7 @@ static void fxgmac_remove(struct pci_dev *pcidev) } #endif -#ifdef HAVE_FXGMAC_DEBUG_FS - fxgmac_dbg_exit(pdata); -#endif /* HAVE_FXGMAC_DEBUG_FS */ + DPRINTK("%s has been removed\n", netdev->name); } /* for Power management, 20210628 */ @@ -190,7 +181,7 @@ static int fxgmac_resume(struct pci_dev *pdev) { struct net_device *netdev = dev_get_drvdata(&pdev->dev); struct fxgmac_pdata *pdata = netdev_priv(netdev); - u32 err; + u32 err = 0; DPRINTK("fxpm, fxgmac_resume callin\n"); @@ -258,5 +249,5 @@ module_pci_driver(fxgmac_pci_driver); MODULE_DESCRIPTION(FXGMAC_DRV_DESC); MODULE_VERSION(FXGMAC_DRV_VERSION); -MODULE_AUTHOR("Frank "); -MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Motorcomm Electronic Tech. Co., Ltd."); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-phy.c b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-phy.c index 50d523caa06c8..7419f6207c8ec 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-phy.c +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-phy.c @@ -1,9 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#include -#include - #include "fuxi-gmac.h" #include "fuxi-gmac-reg.h" @@ -12,11 +9,12 @@ * all at once to avoid the problems caused by individual settings * on some machines */ -void fxgmac_phy_force_mode(struct fxgmac_pdata *pdata) +int fxgmac_phy_force_mode(struct fxgmac_pdata *pdata) { struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 regval = 0; unsigned int high_bit = 0, low_bit = 0; + int ret = 0; switch (pdata->phy_speed) { case SPEED_1000: @@ -37,14 +35,16 @@ void fxgmac_phy_force_mode(struct fxgmac_pdata *pdata) regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_H_POS, PHY_CR_SPEED_SEL_H_LEN, high_bit); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_L_POS, PHY_CR_SPEED_SEL_L_LEN, low_bit); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_DUPLEX_POS, PHY_CR_DUPLEX_LEN, pdata->phy_duplex); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + return ret; } -void fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed) +int fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed) { struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 regval = 0; unsigned int high_bit = 0, low_bit = 0; + int ret = 0; switch (speed) { case SPEED_1000: @@ -65,27 +65,50 @@ void fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed) PHY_CR_SPEED_SEL_H_LEN, high_bit); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_SPEED_SEL_L_POS, PHY_CR_SPEED_SEL_L_LEN, low_bit); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + return ret; } -void fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex) +int fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex) { struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 regval = 0; + int ret = 0; + hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, ®val); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_DUPLEX_POS, PHY_CR_DUPLEX_LEN, (duplex ? 1 : 0)); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + + return ret; } -void fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg) +int fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg) { struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; u32 regval = 0; + int ret = 0; + hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, ®val); regval = FXGMAC_SET_REG_BITS(regval, PHY_CR_AUTOENG_POS, PHY_CR_AUTOENG_LEN, (autoneg ? 1 : 0)); - hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + ret = hw_ops->write_ephy_reg(pdata, REG_MII_BMCR, regval); + + return ret; +} + +void fxgmac_set_phy_link_ksettings(struct fxgmac_pdata *pdata) +{ + struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; + + pdata->phy_speed = pdata->expansion.pre_phy_speed; + pdata->phy_duplex = pdata->expansion.pre_phy_duplex; + pdata->phy_autoeng = pdata->expansion.pre_phy_autoneg; + + if (pdata->phy_autoeng) + hw_ops->phy_config(pdata); + else + fxgmac_phy_force_mode(pdata); } /* @@ -188,7 +211,7 @@ int fxgmac_ephy_soft_reset(struct fxgmac_pdata *pdata) ret = hw_ops->read_ephy_reg(pdata, REG_MII_BMCR, (unsigned int *)&val); busy--; - } while ((ret >= 0) && (0 != (val & 0x8000)) && (busy)); + } while ((ret == 0) && (0 != (val & 0x8000)) && (busy)); if (0 == (val & 0x8000)) return 0; @@ -209,8 +232,8 @@ static int fxgmac_ephy_adjust_status(u32 lport, int val, int is_utp, int *speed, int speed_mode; *speed = -1; - *duplex = (val & BIT(FUXI_EPHY_DUPLEX_BIT)) >> FUXI_EPHY_DUPLEX_BIT; - speed_mode = (val & FUXI_EPHY_SPEED_MODE) >> FUXI_EPHY_SPEED_MODE_BIT; + *duplex = (val & BIT(FXGMAC_EPHY_DUPLEX_BIT)) >> FXGMAC_EPHY_DUPLEX_BIT; + speed_mode = (val & FXGMAC_EPHY_SPEED_MODE) >> FXGMAC_EPHY_SPEED_MODE_BIT; switch (speed_mode) { case 0: if (is_utp) @@ -254,7 +277,7 @@ int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int *speed, int *duplex, if (0 > ret) goto busy_exit; - link = val & (BIT(FUXI_EPHY_LINK_STATUS_BIT)); + link = val & (BIT(FXGMAC_EPHY_LINK_STATUS_BIT)); if (link) { link_utp = 1; fxgmac_ephy_adjust_status(0, val, 1, speed, duplex); @@ -265,9 +288,9 @@ int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int *speed, int *duplex, if (link_utp || link_fiber) { /* case of fiber of priority */ if (link_utp) - *media = (FUXI_EPHY_SMI_SEL_PHY + 1); + *media = (FXGMAC_EPHY_SMI_SEL_PHY + 1); if (link_fiber) - *media = (FUXI_EPHY_SMI_SEL_SDS_SGMII + 1); + *media = (FXGMAC_EPHY_SMI_SEL_SDS_SGMII + 1); *ret_link = 1; } else { @@ -284,3 +307,99 @@ int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int *speed, int *duplex, return ret; } + +/* + * fxgmac_phy_update_link - update the phy link status + * @adapter: pointer to the device adapter structure + */ +static void fxgmac_phy_update_link(struct net_device *netdev) +{ + struct fxgmac_pdata *pdata = netdev_priv(netdev); + struct fxgmac_hw_ops *hw_ops = &pdata->hw_ops; + u32 regval, cur_link, cur_speed; + + regval = hw_ops->get_ephy_state(pdata); + // We should make sure that PHY is done with the reset + if (regval & MGMT_EPHY_CTRL_STA_EPHY_RESET) { + pdata->expansion.phy_link = false; + return; + } + + cur_link = FXGMAC_GET_REG_BITS(regval, + MGMT_EPHY_CTRL_STA_EPHY_LINKUP_POS, + MGMT_EPHY_CTRL_STA_EPHY_LINKUP_LEN); + if (pdata->expansion.phy_link != cur_link) { + hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); + hw_ops->read_ephy_reg(pdata, REG_MII_INT_STATUS, NULL); + + pdata->expansion.phy_link = cur_link; + if (pdata->expansion.phy_link) { + cur_speed = FXGMAC_GET_REG_BITS(regval, + MGMT_EPHY_CTRL_STA_SPEED_POS, + MGMT_EPHY_CTRL_STA_SPEED_LEN); + pdata->phy_speed = (cur_speed == 2) ? SPEED_1000 : + (cur_speed == 1) ? SPEED_100 : SPEED_10; + pdata->phy_duplex = FXGMAC_GET_REG_BITS(regval, + MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_POS, + MGMT_EPHY_CTRL_STA_EPHY_DUPLEX_LEN); + hw_ops->config_mac_speed(pdata); + + hw_ops->enable_rx(pdata); + hw_ops->enable_tx(pdata); + netif_carrier_on(pdata->netdev); + if (netif_running(pdata->netdev)) { + netif_tx_wake_all_queues(pdata->netdev); + dev_info(pdata->dev, "%s now is link up, mac_speed=%d.\n", + netdev_name(pdata->netdev), + pdata->phy_speed); + } + } else { + netif_carrier_off(pdata->netdev); + netif_tx_stop_all_queues(pdata->netdev); + pdata->phy_speed = SPEED_UNKNOWN; + pdata->phy_duplex = DUPLEX_UNKNOWN; + hw_ops->disable_rx(pdata); + hw_ops->disable_tx(pdata); + dev_info(pdata->dev, "%s now is link down\n", netdev_name(pdata->netdev)); + } + } +} + +static void fxgmac_phy_link_poll(struct timer_list *t) +{ + struct fxgmac_pdata *pdata = from_timer(pdata, t, expansion.phy_poll_tm); + + if (NULL == pdata->netdev) { + DPRINTK("fxgmac_phy_timer polling with NULL netdev %lx\n", (unsigned long)(pdata->netdev)); + return; + } + + pdata->stats.ephy_poll_timer_cnt++; + +#if FXGMAC_PM_FEATURE_ENABLED + if (!test_bit(FXGMAC_POWER_STATE_DOWN, &pdata->expansion.powerstate)) +#endif + { + mod_timer(&pdata->expansion.phy_poll_tm, jiffies + HZ / 2); + fxgmac_phy_update_link(pdata->netdev); + } else { + DPRINTK("fxgmac_phy_timer polling, powerstate changed, %ld, netdev=%lx, tm=%lx\n", pdata->expansion.powerstate, (unsigned long)(pdata->netdev), (unsigned long)&pdata->expansion.phy_poll_tm); + } +} + +int fxgmac_phy_timer_init(struct fxgmac_pdata *pdata) +{ + init_timer_key(&pdata->expansion.phy_poll_tm, NULL, 0, "fuxi_phy_link_update_timer", NULL); + pdata->expansion.phy_poll_tm.expires = jiffies + HZ / 2; + pdata->expansion.phy_poll_tm.function = (void *)(fxgmac_phy_link_poll); + add_timer(&pdata->expansion.phy_poll_tm); + + DPRINTK("fxgmac_phy_timer started, %lx\n", jiffies); + return 0; +} + +void fxgmac_phy_timer_destroy(struct fxgmac_pdata *pdata) +{ + del_timer_sync(&pdata->expansion.phy_poll_tm); + DPRINTK("fxgmac_phy_timer removed\n"); +} diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-reg.h b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-reg.h index e0a6dbe8aa95c..26dbe9b2e2352 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-reg.h +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac-reg.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#ifndef __FUXI_GMAC_REG_H__ -#define __FUXI_GMAC_REG_H__ +#ifndef __FXGMAC_GMAC_REG_H__ +#define __FXGMAC_GMAC_REG_H__ #define AISC_MODE @@ -14,10 +14,12 @@ #define MAC_CR 0x0000 /* The MAC Configuration Register */ #define MAC_ECR 0x0004 #define MAC_PFR 0x0008 +#define MAC_WTR 0x000c #define MAC_HTR0 0x0010 #define MAC_VLANTR 0x0050 #define MAC_VLANHTR 0x0058 #define MAC_VLANIR 0x0060 +#define MAC_IVLANIR 0x0064 #define MAC_Q0TFCR 0x0070 #define MAC_RFCR 0x0090 #define MAC_RQC0R 0x00a0 @@ -36,8 +38,12 @@ #define MAC_LPI_CONTROL 0x00d4 #define MAC_LPI_TIMER 0x00d8 #define MAC_MS_TIC_COUNTER 0x00dc -#define MAC_AN_SR 0x00E4 -#define MAC_PHYIF_STA 0x00F8 +#define MAC_AN_CR 0x00e0 +#define MAC_AN_SR 0x00e4 +#define MAC_AN_ADV 0x00e8 +#define MAC_AN_LPA 0x00ec +#define MAC_AN_EXP 0x00f0 +#define MAC_PHYIF_STA 0x00f8 #define MAC_VR 0x0110 #define MAC_DBG_STA 0x0114 #define MAC_HWF0R 0x011c @@ -46,6 +52,7 @@ #define MAC_HWF3R 0x0128 #define MAC_MDIO_ADDRESS 0x0200 #define MAC_MDIO_DATA 0x0204 +#define MAC_GPIOCR 0x0208 #define MAC_GPIO_SR 0x020c #define MAC_ARP_PROTO_ADDR 0x0210 #define MAC_CSR_SW_CTRL 0x0230 @@ -525,6 +532,8 @@ /* MTL register offsets */ #define MTL_OMR 0x0c00 +#define MTL_FDCR 0x0c08 +#define MTL_FDSR 0x0c0c #define MTL_FDDR 0x0c10 #define MTL_INT_SR 0x0c20 #define MTL_RQDCM0R 0x0c30 @@ -549,8 +558,11 @@ #define MTL_Q_INT_CTL_SR 0x0d2c #define MTL_Q_TQOMR 0x00 +#define MTL_Q_TQUR 0x04 #define MTL_Q_RQOMR 0x30 +#define MTL_Q_RQMPOCR 0x34 #define MTL_Q_RQDR 0x38 +#define MTL_Q_RQCR 0x3c #define MTL_Q_IER 0x2c #define MTL_Q_ISR 0x2c /* no isr register */ #define MTL_TXQ_DEG 0x08 /* transmit debug */ @@ -652,10 +664,19 @@ #define MTL_TC_BASE MTL_Q_BASE #define MTL_TC_INC MTL_Q_INC +#define MTL_TC_TQDR 0x08 #define MTL_TC_ETSCR 0x10 #define MTL_TC_ETSSR 0x14 #define MTL_TC_QWR 0x18 +/* The Queue 0 Transmit Debug register gives the debug status of various blocks + * related to the Transmit queue + */ +#define MTL_TC_TQDR_TRCSTS_POS 1 +#define MTL_TC_TQDR_TRCSTS_LEN 2 +#define MTL_TC_TQDR_TXQSTS_POS 4 +#define MTL_TC_TQDR_TXQSTS_LEN 1 + /* MTL traffic class register entry bit positions and sizes */ #define MTL_TC_ETSCR_TSA_POS 0 #define MTL_TC_ETSCR_TSA_LEN 2 @@ -673,6 +694,11 @@ #define DMA_DSR0 0x100c #define DMA_DSR1 0x1010 #define DMA_DSR2 0x1014 +#define DMA_AXIARCR 0x1020 +#define DMA_AXIAWCR 0x1024 +#define DMA_AXIAWRCR 0x1028 +#define DMA_SAFE_ISR 0x1080 +#define DMA_ECC_IE 0x1084 #define DMA_ECC_INT_SR 0x1088 /* DMA register entry bit positions and sizes */ @@ -682,10 +708,16 @@ #define DMA_ISR_MTLIS_LEN 1 #define DMA_MR_SWR_POS 0 #define DMA_MR_SWR_LEN 1 +#define DMA_MR_TXPR_POS 11 +#define DMA_MR_TXPR_LEN 1 #define DMA_MR_INTM_POS 16 #define DMA_MR_INTM_LEN 2 -#define DMA_MR_QUREAD_POS 19 -#define DMA_MR_QUREAD_LEN 1 +#define DMA_MR_QUREAD_POS 19 +#define DMA_MR_QUREAD_LEN 1 +#define DMA_MR_TNDF_POS 20 +#define DMA_MR_TNDF_LEN 2 +#define DMA_MR_RNDF_POS 22 +#define DMA_MR_RNDF_LEN 2 #define DMA_SBMR_EN_LPI_POS 31 #define DMA_SBMR_EN_LPI_LEN 1 @@ -695,6 +727,8 @@ #define DMA_SBMR_WR_OSR_LMT_LEN 6 #define DMA_SBMR_RD_OSR_LMT_POS 16 #define DMA_SBMR_RD_OSR_LMT_LEN 8 +#define DMA_SBMR_AAL_POS 12 +#define DMA_SBMR_AAL_LEN 1 #define DMA_SBMR_EAME_POS 11 #define DMA_SBMR_EAME_LEN 1 #define DMA_SBMR_AALE_POS 10 @@ -749,6 +783,12 @@ #define DMA_CH_RDRLR 0x30 #define DMA_CH_IER 0x34 #define DMA_CH_RIWT 0x38 +#define DMA_CH_CATDR_LO 0x44 +#define DMA_CH_CARDR_LO 0x4c +#define DMA_CH_CATBR_HI 0x50 +#define DMA_CH_CATBR_LO 0x54 +#define DMA_CH_CARBR_HI 0x58 +#define DMA_CH_CARBR_LO 0x5c #define DMA_CH_SR 0x60 /* DMA channel register entry bit positions and sizes */ @@ -861,6 +901,8 @@ #define RX_NORMAL_DESC3_INTE_POS 30 #define RX_NORMAL_DESC3_INTE_LEN 1 #define RX_NORMAL_DESC3_L34T_LEN 4 +#define RX_NORMAL_DESC3_RSV_POS 26 +#define RX_NORMAL_DESC3_RSV_LEN 1 #define RX_NORMAL_DESC3_LD_POS 28 #define RX_NORMAL_DESC3_LD_LEN 1 #define RX_NORMAL_DESC3_OWN_POS 31 @@ -871,7 +913,6 @@ #define RX_NORMAL_DESC3_BUF1V_LEN 1 #define RX_NORMAL_DESC3_PL_POS 0 #define RX_NORMAL_DESC3_PL_LEN 15 -#define RX_NORMAL_DESC3_RSV_LEN 1 /* Inner VLAN Tag. Valid only when Double VLAN tag processing * and VLAN tag stripping are enabled. @@ -909,6 +950,8 @@ */ #define RX_NORMAL_DESC2_WB_DAF_POS 17 #define RX_NORMAL_DESC2_WB_DAF_LEN 1 +#define RX_NORMAL_DESC2_WB_RAPARSER_POS 11 +#define RX_NORMAL_DESC2_WB_RAPARSER_LEN 3 #define RX_NORMAL_DESC3_WB_LD_POS 28 #define RX_NORMAL_DESC3_WB_LD_LEN 1 @@ -1074,14 +1117,14 @@ #define PHY_MII_CTRL1000_1000FULL_LEN 1 #define PHY_MII_CTRL1000_1000HALF_POS 8 #define PHY_MII_CTRL1000_1000HALF_LEN 1 -#define REG_MII_STAT1000 0x0A /* 1000BASE-T status */ +#define REG_MII_STAT1000 0x0a /* 1000BASE-T status */ #define PHY_MII_STAT1000_CFG_ERROR_POS 15 #define PHY_MII_STAT1000_CFG_ERROR_LEN 1 -#define REG_MII_MMD_CTRL 0x0D /* MMD access control register */ -#define REG_MII_MMD_DATA 0x0E /* MMD access data register */ +#define REG_MII_MMD_CTRL 0x0d /* MMD access control register */ +#define REG_MII_MMD_DATA 0x0e /* MMD access data register */ -#define REG_MII_ESTATUS 0x0F /* Extended Status */ +#define REG_MII_ESTATUS 0x0f /* Extended Status */ #define REG_MII_SPEC_CTRL 0x10 /* PHY specific func control */ #define PHY_MII_SPEC_CTRL_CRS_ON_POS 3 @@ -1110,8 +1153,8 @@ #define REG_MII_DOWNG_CTRL 0x14 /* Speed auto downgrade control*/ #define REG_MII_RERRCOUNTER 0x15 /* Receive error counter */ -#define REG_MII_EXT_ADDR 0x1E /* Extended reg's address */ -#define REG_MII_EXT_DATA 0x1F /* Extended reg's date */ +#define REG_MII_EXT_ADDR 0x1e /* Extended reg's address */ +#define REG_MII_EXT_DATA 0x1f /* Extended reg's date */ #define FXGMAC_EPHY_ID_MASK 0x0000ffff @@ -1167,18 +1210,18 @@ #define BIT(n) (0x1<<(n)) #endif -#ifndef FUXI_EPHY_SPEED_MODE_BIT -#define FUXI_EPHY_SPEED_MODE 0xc000 -#define FUXI_EPHY_DUPLEX 0x2000 -#define FUXI_EPHY_SPEED_MODE_BIT 14 -#define FUXI_EPHY_DUPLEX_BIT 13 -#define FUXI_EPHY_LINK_STATUS_BIT 10 +#ifndef FXGMAC_EPHY_SPEED_MODE_BIT +#define FXGMAC_EPHY_SPEED_MODE 0xc000 +#define FXGMAC_EPHY_DUPLEX 0x2000 +#define FXGMAC_EPHY_SPEED_MODE_BIT 14 +#define FXGMAC_EPHY_DUPLEX_BIT 13 +#define FXGMAC_EPHY_LINK_STATUS_BIT 10 #endif -#define FUXI_EPHY_SMI_SEL_PHY 0x0 -#define FUXI_EPHY_SMI_SEL_SDS_QSGMII 0x02 -#define FUXI_EPHY_SMI_SEL_SDS_SGMII 0x03 +#define FXGMAC_EPHY_SMI_SEL_PHY 0x0 +#define FXGMAC_EPHY_SMI_SEL_SDS_QSGMII 0x02 +#define FXGMAC_EPHY_SMI_SEL_SDS_SGMII 0x03 #define REG_MII_EXT_ANALOG_CFG3 0x52 #define MII_EXT_ANALOG_CFG3_ADC_START_CFG_POS 14 @@ -1221,27 +1264,27 @@ #define REG_MII_EXT_ANALOG_CFG8_VALUE 0x274c #define REG_MII_EXT_ANALOG_CFG8_137D1D05_VALUE 0x264c -#define REG_MII_EXT_COMMON_LED_CFG 0xA00B -#define REG_MII_EXT_COMMON_LED0_CFG 0xA00C +#define REG_MII_EXT_COMMON_LED_CFG 0xa00b +#define REG_MII_EXT_COMMON_LED0_CFG 0xa00c #define REG_MII_EXT_COMMON_LED0_CFG_VALUE_SOLUTION0 0x2600 #define REG_MII_EXT_COMMON_LED0_CFG_VALUE_SOLUTION1 0x00 #define REG_MII_EXT_COMMON_LED0_CFG_VALUE_SOLUTION2 0x20 #define REG_MII_EXT_COMMON_LED0_CFG_VALUE_SOLUTION3 0x2600 -#define REG_MII_EXT_COMMON_LED1_CFG 0xA00D +#define REG_MII_EXT_COMMON_LED1_CFG 0xa00d #define REG_MII_EXT_COMMON_LED1_CFG_VALUE_SOLUTION0 0x1800 #define REG_MII_EXT_COMMON_LED1_CFG_VALUE_SOLUTION1 0x00 #define REG_MII_EXT_COMMON_LED1_CFG_VALUE_SOLUTION2 0x40 -#define REG_MII_EXT_COMMON_LED2_CFG 0xA00E +#define REG_MII_EXT_COMMON_LED2_CFG 0xa00e #define REG_MII_EXT_COMMON_LED2_CFG_VALUE_SOLUTION0 0x00 #define REG_MII_EXT_COMMON_LED2_CFG_VALUE_SOLUTION2 0x07 #define REG_MII_EXT_COMMON_LED2_CFG_VALUE_SOLUTION3 0x20 #define REG_MII_EXT_COMMON_LED2_CFG_VALUE_SOLUTION4 0x1800 -#define REG_MII_EXT_COMMON_LED_BLINK_CFG 0xA00F -#define REG_MII_EXT_COMMON_LED_BLINK_CFG_SOLUTION2 0x0F +#define REG_MII_EXT_COMMON_LED_BLINK_CFG 0xa00f +#define REG_MII_EXT_COMMON_LED_BLINK_CFG_SOLUTION2 0x0f #define REG_MII_EXT_COMMON_LED0_CFG_VALUE_SLEEP_SOLUTION3 0x2600 -#define REG_MII_EXT_PKG_CFG0 0xA0 +#define REG_MII_EXT_PKG_CFG0 0xa0 #define REG_MII_EXT_PKG_CHECK_POS 14 #define REG_MII_EXT_PKG_CHECK_LEN 2 #define REG_MII_EXT_PKG_ENABLE_CHECK 0x2 @@ -1251,33 +1294,33 @@ #define MII_EXT_SLEEP_CONTROL1_EN_LEN 1 #define MII_EXT_SLEEP_CONTROL1_PLLON_IN_SLP_POS 14 #define MII_EXT_SLEEP_CONTROL1_PLLON_IN_SLP_LEN 1 -#define REG_MII_EXT_PKG_RX_VALID0 0xA3 -#define REG_MII_EXT_REG_RX_VALID1 0xA4 -#define REG_MII_EXT_REG_RX_OS0 0xA5 -#define REG_MII_EXT_REG_RX_OS1 0xA6 -#define REG_MII_EXT_REG_RX_US0 0xA7 -#define REG_MII_EXT_REG_RX_US1 0xA8 -#define REG_MII_EXT_REG_RX_ERR 0xA9 -#define REG_MII_EXT_REG_RX_0S_BAD 0xAA -#define REG_MII_EXT_REG_RX_FRAGMENT 0xAB -#define REG_MII_EXT_REG_RX_NOSFD 0xAC -#define REG_MII_EXT_REG_TX_VALID0 0xAD -#define REG_MII_EXT_REG_TX_VALID1 0xAE -#define REG_MII_EXT_REG_TX_OS0 0xAF -#define REG_MII_EXT_REG_TX_OS1 0xB0 -#define REG_MII_EXT_REG_TX_US0 0xB1 -#define REG_MII_EXT_REG_TX_US1 0xB2 -#define REG_MII_EXT_REG_TX_ERR 0xB3 -#define REG_MII_EXT_REG_TX_OS_BAD 0xB4 -#define REG_MII_EXT_REG_TX_FRAGMENT 0xB5 -#define REG_MII_EXT_REG_TX_NOSFD 0xB6 +#define REG_MII_EXT_PKG_RX_VALID0 0xa3 +#define REG_MII_EXT_REG_RX_VALID1 0xa4 +#define REG_MII_EXT_REG_RX_OS0 0xa5 +#define REG_MII_EXT_REG_RX_OS1 0xa6 +#define REG_MII_EXT_REG_RX_US0 0xa7 +#define REG_MII_EXT_REG_RX_US1 0xa8 +#define REG_MII_EXT_REG_RX_ERR 0xa9 +#define REG_MII_EXT_REG_RX_0S_BAD 0xaa +#define REG_MII_EXT_REG_RX_FRAGMENT 0xab +#define REG_MII_EXT_REG_RX_NOSFD 0xac +#define REG_MII_EXT_REG_TX_VALID0 0xad +#define REG_MII_EXT_REG_TX_VALID1 0xae +#define REG_MII_EXT_REG_TX_OS0 0xaf +#define REG_MII_EXT_REG_TX_OS1 0xb0 +#define REG_MII_EXT_REG_TX_US0 0xb1 +#define REG_MII_EXT_REG_TX_US1 0xb2 +#define REG_MII_EXT_REG_TX_ERR 0xb3 +#define REG_MII_EXT_REG_TX_OS_BAD 0xb4 +#define REG_MII_EXT_REG_TX_FRAGMENT 0xb5 +#define REG_MII_EXT_REG_TX_NOSFD 0xb6 #define REG_MII_EXT_REG_PMA_DBG0_ADC 0x13 #define REG_MII_EXT_ENABLE_GIGA_POWER_SAVING_FOR_SHORT_CABLE 0x3538 -#define REG_MII_EXT_REG_CLD_REG0 0x3A0 -#define REG_MII_EXT_ENABLE_CLD_NP_WP 0xEB24 -#define REG_MII_EXT_REG_CLD_REG1 0x3CC +#define REG_MII_EXT_REG_CLD_REG0 0x3a0 +#define REG_MII_EXT_ENABLE_CLD_NP_WP 0xeb24 +#define REG_MII_EXT_REG_CLD_REG1 0x3cc #define REG_MII_EXT_ENABLE_CLD_GT_HT_BT 0x7001 -#define REG_MMD_EEE_ABILITY_REG 0x3C +#define REG_MMD_EEE_ABILITY_REG 0x3c #define REG_MMD_EEE_ABILITY_VALUE 0x06 /* Below registers don't belong to GMAC, it has zero offset, not 0x2000 offset. mem_base + REG_XXX. */ @@ -1309,27 +1352,29 @@ #define MGMT_EPHY_CTRL_STA_SPEED_LEN 2 #define MGMT_EPHY_CTRL_STA_SPEED_MASK 0x18 -#define MGMT_EPHY_CTRL_ERROR_VALUE 0xFFFFFFFF +#define MGMT_EPHY_CTRL_ERROR_VALUE 0xffffffff #define MGMT_PCIE_EP_CTRL 0x1008 #define MGMT_PCIE_EP_CTRL_DBI_CS_EN_POS 0 #define MGMT_PCIE_EP_CTRL_DBI_CS_EN_LEN 1 -#define MGMT_PCIE_CFG_CTRL 0x8BC +#define MGMT_PCIE_CFG_CTRL 0x8bc #define PCIE_CFG_CTRL_DEFAULT_VAL 0x7ff40 #define MGMT_PCIE_CFG_CTRL_CS_EN_POS 0 #define MGMT_PCIE_CFG_CTRL_CS_EN_LEN 1 /***power management ***/ -#define WOL_CTL 0x100C +#define WOL_CTL 0x100c /* set means magic and remote packet wakeup enable */ #define WOL_PKT_EN_POS 1 #define WOL_PKT_EN_LEN 1 /* set means link change wakeup enable */ #define WOL_LINKCHG_EN_POS 0 #define WOL_LINKCHG_EN_LEN 1 +#define WOL_WAIT_TIME_POS 2 +#define WOL_WAIT_TIME_LEN 13 #define OOB_WOL_CTRL 0x1010 #define OOB_WOL_CTRL_DIS_POS 0 @@ -1348,34 +1393,47 @@ /* MAC management registers bit positions and sizes */ #define MGMT_INT_CTRL0_INT_MASK_POS 16 #define MGMT_INT_CTRL0_INT_MASK_LEN 16 -#define MGMT_INT_CTRL0_INT_MASK_MASK 0xFFFF -#define MGMT_INT_CTRL0_INT_MASK_RXCH 0xF +#define MGMT_INT_CTRL0_INT_MASK_MASK 0xffff +#define MGMT_INT_CTRL0_INT_MASK_RXCH 0xf #define MGMT_INT_CTRL0_INT_MASK_TXCH 0x10 -#define MGMT_INT_CTRL0_INT_MASK_EX_PMT 0xF7FF -#define MGMT_INT_CTRL0_INT_MASK_DISABLE 0xF000 +#define MGMT_INT_CTRL0_INT_MASK_EX_PMT 0xf7ff +#define MGMT_INT_CTRL0_INT_MASK_DISABLE 0xf000 #define MGMT_INT_CTRL0_INT_STATUS_POS 0 #define MGMT_INT_CTRL0_INT_STATUS_LEN 16 -#define MGMT_INT_CTRL0_INT_STATUS_MASK 0xFFFF +#define MGMT_INT_CTRL0_INT_STATUS_MASK 0xffff #define MGMT_INT_CTRL0_INT_STATUS_RX 0x0001 #define MGMT_INT_CTRL0_INT_STATUS_TX 0x0010 -#define MGMT_INI_CTRL0_INT_STATUS_TX_INVERSE 0xFFEF -#define MGMG_INT_CTRL0_INT_STATUS_PHY_INVERSE 0xFFDF -#define MGMT_INT_CTRL0_INT_STATUS_PHY 0x0020 +#define MGMT_INI_CTRL0_INT_STATUS_TX_INVERSE 0xffff +#define MGMT_INT_CTRL0_INT_STATUS_MISC_INVERSE 0xffdf +#define MGMT_INT_CTRL0_INT_STATUS_MISC 0x0020 #define MGMT_INT_CTRL0_INT_MASK_RXCH_POS 16 #define MGMT_INT_CTRL0_INT_STATUS_RXCH_POS 0 #define MGMT_INT_CTRL0_INT_STATUS_RXCH_LEN 4 -#define MGMT_INT_CTRL0_INT_STATUS_RXCH_MASK 0xF +#define MGMT_INT_CTRL0_INT_STATUS_RXCH_MASK 0xf #define MGMT_INT_CTRL0_INT_STATUS_RXTX_LEN 5 -#define MGMT_INT_CTRL0_INT_STATUS_RXTX_MASK 0x1F -#define MGMT_INT_CTRL0_INT_STATUS_RXTXPHY_MASK 0x3F +#define MGMT_INT_CTRL0_INT_STATUS_RXTX_MASK 0x1f +#define MGMT_INT_CTRL0_INT_STATUS_RXTXMISC_MASK 0x3f #define MGMT_INT_CTRL0_INT_MASK_TXCH_POS 20 #define MGMT_INT_CTRL0_INT_STATUS_TXCH_POS 4 #define MGMT_INT_CTRL0_INT_STATUS_TXCH_LEN 1 #define MGMT_INT_CTRL0_INT_STATUS_TXCH_MASK 0x1 +#define MGMT_MAC_PHYIF_STA_POS 0 +#define MGMT_MAC_AN_SR0_POS 1 +#define MGMT_MAC_AN_SR1_POS 2 +#define MGMT_MAC_AN_SR2_POS 3 +#define MGMT_MAC_PMT_STA_POS 4 +#define MGMT_MAC_LPI_STA_POS 5 +#define MGMT_MAC_MMC_STA_POS 8 +#define MGMT_MAC_RX_MMC_STA_POS 9 +#define MGMT_MAC_TX_MMC_STA_POS 10 +#define MGMT_MMC_IPCRXINT_POS 11 +#define MGMT_MAC_TX_RX_STA0_POS 13 +#define MGMT_MAC_TX_RX_STA1_POS 14 +#define MGMT_MAC_GPIO_SR_POS 15 /* Interrupt Ctrl1 */ #define INT_CTRL1 0x1104 @@ -1394,19 +1452,19 @@ #define INT_MOD_IN_US 200 /*in us*/ /* PCIE LTR 2 working modes: -Two working mode: -1. SW trigger -LTR idle threshold timer set as 0, enable LTR enable will trigger one LTR message -Note : PCIe cfg enable should set in initialization before enable LTR. -2. HW auto trigger -LTR idle threshold timer set as one non-zero value, HW monitor system status, -when system idle timer over threshold, HW send out LTR message -system exit idle state, send out one LTR exit message. + * Two working mode: + * 1. SW trigger + * LTR idle threshold timer set as 0, enable LTR enable will trigger one LTR message + * Note : PCIe cfg enable should set in initialization before enable LTR. + * 2. HW auto trigger + * LTR idle threshold timer set as one non-zero value, HW monitor system status, + * when system idle timer over threshold, HW send out LTR message + * system exit idle state, send out one LTR exit message. */ #define LTR_CTRL 0x1130 #define LTR_CTRL_IDLE_THRE_TIMER_POS 16 #define LTR_CTRL_IDLE_THRE_TIMER_LEN 14 /* in 8ns units*/ -#define LTR_CTRL_IDLE_THRE_TIMER_VAL 0x3FFF +#define LTR_CTRL_IDLE_THRE_TIMER_VAL 0x3fff #define LTR_CTRL_EN_POS 0 #define LTR_CTRL_EN_LEN 1 @@ -1418,7 +1476,7 @@ system exit idle state, send out one LTR exit message. #define LTR_CTRL2_DBG_DATA_POS 0 #define LTR_CTRL2_DBG_DATA_LEN 32 -#define LTR_IDLE_ENTER 0x113C /* LTR_CTRL3, LTR latency message, only for System IDLE Start. */ +#define LTR_IDLE_ENTER 0x113c /* LTR_CTRL3, LTR latency message, only for System IDLE Start. */ #define LTR_IDLE_ENTER_POS 0 #define LTR_IDLE_ENTER_LEN 10 #define LTR_IDLE_ENTER_USVAL 900 @@ -1470,7 +1528,7 @@ system exit idle state, send out one LTR exit message. #define LPW_CTRL_OTP_CLK_ON_LEN 1 #define MSI_PBA_REG 0x1300 -#define SYS_RESET_REG 0x152C +#define SYS_RESET_REG 0x152c #define SYS_RESET_POS 31 #define SYS_RESET_LEN 1 @@ -1511,7 +1569,7 @@ system exit idle state, send out one LTR exit message. #define PCIE_SERDES_STATUS_HW_BIAS_ON_POS 0 #define PCIE_SERDES_STATUS_HW_BIAS_ON_LEN 1 -#define REG_PCIE_SERDES_PLL 0x199C +#define REG_PCIE_SERDES_PLL 0x199c #define PCIE_SERDES_PLL_AUTOOFF_POS 0 #define PCIE_SERDES_PLL_AUTOOFF_LEN 1 @@ -1602,6 +1660,8 @@ system exit idle state, send out one LTR exit message. #define MGMT_RSS_CTRL_TBL_SIZE_LEN 3 #define MGMT_RSS_CTRL_TBL_SIZE_MASK 0x7 +#define MAC_RSSCR_IP2TE_POS 1 +#define MAC_RSSCR_IP2TE_LEN 1 #define MAC_RSSCR_RSSE_POS 31 #define MAC_RSSCR_RSSE_LEN 1 @@ -1660,7 +1720,17 @@ system exit idle state, send out one LTR exit message. #define MGMT_RMK_CTRL 0x1400 -#define MGMT_SIGDET 0x17F8 +#define MGMT_SIGDET_DEGLITCH 0x17f0 +#define MGMT_SIGDET_DEGLITCH_DISABLE_POS 2 //sigdet deglitch disable ,active low +#define MGMT_SIGDET_DEGLITCH_DISABLE_LEN 1 +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_POS 3 //sigdet deglitch time windows filter seltion +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_LEN 2 +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_10ns 0 +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_20ns 1 +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_30ns 2 +#define MGMT_SIGDET_DEGLITCH_TIME_WIN_40ns 3 + +#define MGMT_SIGDET 0x17f8 #define MGMT_SIGDET_POS 13 #define MGMT_SIGDET_LEN 3 #define MGMT_SIGDET_55MV 7 @@ -1703,7 +1773,7 @@ system exit idle state, send out one LTR exit message. #define MSIX_TBL_RXTX_NUM 8 #endif #define MSIX_TBL_BASE_ADDR 0x1200 -#define MSIX_TBL_MASK_OFFSET 0xC +#define MSIX_TBL_MASK_OFFSET 0xc #define MSIX_TBL_DATA_OFFSET 0x8 #define MSIX_TBL_ADDR_OFFSET 0x0 @@ -1745,15 +1815,15 @@ system exit idle state, send out one LTR exit message. /* efuse layout refer to http://redmine.motor-comm.com/issues/3856 */ #define EFUSE_FISRT_UPDATE_ADDR 255 #define EFUSE_SECOND_UPDATE_ADDR 209 -#define FUXI_EFUSE_MAX_ENTRY 39 -#define FUXI_EFUSE_MAX_ENTRY_UNDER_LED_COMMON 24 +#define FXGMAC_EFUSE_MAX_ENTRY 39 +#define FXGMAC_EFUSE_MAX_ENTRY_UNDER_LED_COMMON 24 #define EFUSE_PATCH_ADDR_START_BYTE 0 #define EFUSE_PATCH_DATA_START_BYTE 2 #define EFUSE_REGION_A_B_LENGTH 18 #define EFUSE_EACH_PATH_SIZE 6 #define EFUSE_REVID_REGISTER 0x0008 -#define EFUSE_SUBSYS_REGISTER 0x002C +#define EFUSE_SUBSYS_REGISTER 0x002c /* mac[5]->bit7:0, mac[4]->bit15:8, mac[3]->bit23:16, mac[2]->bit31:24. */ #define MACA0LR_FROM_EFUSE 0x1520 /* mac[1]->bit7:0, mac[0]->bit15:8. mac[6] = @@ -1772,7 +1842,7 @@ system exit idle state, send out one LTR exit message. #define EFUSE_LED_SOLUTION2 2 #define EFUSE_LED_SOLUTION3 3 #define EFUSE_LED_SOLUTION4 4 -#define EFUSE_LED_COMMON_SOLUTION 0x1F +#define EFUSE_LED_COMMON_SOLUTION 0x1f /******************** Below for pcie configuration register. *********************/ #define REG_PCI_VENDOR_ID 0x0 /* WORD reg */ @@ -1793,9 +1863,9 @@ system exit idle state, send out one LTR exit message. #define REG_PCI_REVID 0x8 /* BYTE reg */ #define REG_PCI_PROGRAM_INTF 0x9 /* BYTE reg */ /* PCI Class Program Interface */ -#define REG_PCI_SUB_CLASS 0xA /* BYTE reg */ -#define REG_PCI_BASE_CLASS 0xB /* BYTE reg */ -#define REG_CACHE_LINE_SIZE 0xC +#define REG_PCI_SUB_CLASS 0xa /* BYTE reg */ +#define REG_PCI_BASE_CLASS 0xb /* BYTE reg */ +#define REG_CACHE_LINE_SIZE 0xc #define REG_MEM_BASE 0x10 /* DWORD or QWORD reg */ @@ -1803,10 +1873,10 @@ system exit idle state, send out one LTR exit message. #define REG_IO_BASE 0x20 /* DWORD reg */ -#define REG_PCI_SUB_VENDOR_ID 0x2C /* WORD reg */ -#define REG_PCI_SUB_DEVICE_ID 0x2E /* WORD reg */ +#define REG_PCI_SUB_VENDOR_ID 0x2c /* WORD reg */ +#define REG_PCI_SUB_DEVICE_ID 0x2e /* WORD reg */ -#define REG_INT_LINE 0x3C /* BYTE reg */ +#define REG_INT_LINE 0x3c /* BYTE reg */ #define REG_PM_STATCTRL 0x44 /* WORD reg */ #define PM_STATCTRL_PWR_STAT_POS 0 @@ -1843,7 +1913,7 @@ system exit idle state, send out one LTR exit message. #define DEVICE_CTRL2_LTR_EN_POS 10 /* Enable from BIOS side. */ #define DEVICE_CTRL2_LTR_EN_LEN 1 -#define REG_MSIX_CAPABILITY 0xB0 +#define REG_MSIX_CAPABILITY 0xb0 /* ASPM L1ss PM Substates */ #define REG_ASPM_L1SS_CAP 0x154 /* Capabilities Register */ @@ -1883,7 +1953,7 @@ system exit idle state, send out one LTR exit message. #define REG_ASPM_L1SS_CTL2 0x15c /* Control 2 Register */ -#define REG_ASPM_CONTROL 0x70C +#define REG_ASPM_CONTROL 0x70c #define ASPM_L1_IDLE_THRESHOLD_POS 27 #define ASPM_L1_IDLE_THRESHOLD_LEN 3 #define ASPM_L1_IDLE_THRESHOLD_1US 0 @@ -1898,6 +1968,6 @@ system exit idle state, send out one LTR exit message. #define POWER_EIOS_POS 7 #define POWER_EIOS_LEN 1 -#define TONGFANGID_137D1D05_ADJUST_SI 0x137D1D05 +#define AISTONEID_137D1D05_ADJUST_SI 0x137d1d05 #endif /* __FUXI_GMAC_REG_H__ */ diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac.h b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac.h index c95caca0433d8..32b4fc0f0c429 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac.h +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-gmac.h @@ -1,9 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2021 Motorcomm Corporation. */ -#ifndef __FUXI_GMAC_H__ -#define __FUXI_GMAC_H__ +#ifndef __FXGMAC_GMAC_H__ +#define __FXGMAC_GMAC_H__ +#include "fuxi-errno.h" #include "fuxi-os.h" /* For fpga before 20210507 */ @@ -12,17 +13,17 @@ #define FXGMAC_DRV_NAME "yt6801" -#define FXGMAC_DRV_DESC "Motorcomm FUXI GMAC Driver" +#define FXGMAC_DRV_DESC "Motorcomm YT6801 Gigabit Ethernet Driver" -#define FUXI_MAC_REGS_OFFSET 0x2000 +#define FXGMAC_MAC_REGS_OFFSET 0x2000 /* 1: in normal D0 state, turn off ephy link change interrupt. */ -#define FUXI_EPHY_INTERRUPT_D0_OFF 0 +#define FXGMAC_EPHY_INTERRUPT_D0_OFF 0 /* 1:when rec buffer is not enough, to create rbd and rec buffer, * but the rdb need to be continus with the intialized rdb, so * close the feature */ -#define FUXI_ALLOC_NEW_RECBUFFER 0 +#define FXGMAC_ALLOC_NEW_RECBUFFER 0 #define RESUME_MAX_TIME 3000000 #define PHY_LINK_TIMEOUT 3000 @@ -41,11 +42,11 @@ #define FXGMAX_ASPM_WAR_EN /* Descriptor related parameters */ -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED #define FXGMAC_TX_DESC_CNT 1024 #else /* 256 to make sure the tx ring is in the 4k range when - * FXGMAC_TX_HANG_TIMER_EN is 0 + * FXGMAC_TX_HANG_TIMER_ENABLED is 0 */ #define FXGMAC_TX_DESC_CNT 256 #endif @@ -73,9 +74,6 @@ #define FXGMAC_SPH_HDSMS_SIZE 3 #define FXGMAC_SKB_ALLOC_SIZE 512 -/* In Linux Driver, it set MAX_FIFO size 131072, here it uses - * the same value as windows driver - */ #define FXGMAC_MAX_FIFO 81920 #define FXGMAC_MAX_DMA_CHANNELS FXGMAC_MSIX_Q_VECTORS @@ -126,6 +124,10 @@ #define FXGMAC_POWER_STATE_DOWN 0 #define FXGMAC_POWER_STATE_UP 1 +#define FXGMAC_DATA_WIDTH 128 + +#define FXGMAC_WOL_WAIT_TIME 2 // unit 1ms + struct wol_bitmap_pattern { u32 flags; u32 pattern_size; @@ -419,7 +421,7 @@ struct fxgmac_channel { u32 dma_irq; FXGMAC_CHANNEL_OF_PLATFORM expansion; - unsigned int saved_ier; + u32 saved_ier; unsigned int tx_timer_active; @@ -483,7 +485,7 @@ struct fxgmac_hw_ops { void (*set_interrupt_moderation)(struct fxgmac_pdata *pdata); void (*enable_msix_rxtxinterrupt)(struct fxgmac_pdata *pdata); void (*disable_msix_interrupt)(struct fxgmac_pdata *pdata); - void (*enable_msix_rxtxphyinterrupt)(struct fxgmac_pdata *pdata); + int (*enable_msix_rxtxphyinterrupt)(struct fxgmac_pdata *pdata); void (*enable_msix_one_interrupt)(struct fxgmac_pdata *pdata, u32 intid); void (*disable_msix_one_interrupt)(struct fxgmac_pdata *pdata, @@ -491,6 +493,7 @@ struct fxgmac_hw_ops { bool (*enable_mgm_interrupt)(struct fxgmac_pdata *pdata); bool (*disable_mgm_interrupt)(struct fxgmac_pdata *pdata); int (*dismiss_all_int)(struct fxgmac_pdata *pdata); + void (*clear_misc_int_status)(struct fxgmac_pdata *pdata); void (*dev_xmit)(struct fxgmac_channel *channel); int (*dev_read)(struct fxgmac_channel *channel); @@ -504,9 +507,6 @@ struct fxgmac_hw_ops { /* For MII speed configuration */ int (*config_mac_speed)(struct fxgmac_pdata *pdata); - int (*set_xlgmii_2500_speed)(struct fxgmac_pdata *pdata); - int (*set_xlgmii_1000_speed)(struct fxgmac_pdata *pdata); - int (*set_xlgmii_100_speed)(struct fxgmac_pdata *pdata); int (*get_xlgmii_phy_status)(struct fxgmac_pdata *pdata, u32 *speed, bool *link_up, bool link_up_wait_to_complete); @@ -541,9 +541,9 @@ struct fxgmac_hw_ops { /* For RX coalescing */ int (*config_rx_coalesce)(struct fxgmac_pdata *pdata); int (*config_tx_coalesce)(struct fxgmac_pdata *pdata); - unsigned int (*usec_to_riwt)(struct fxgmac_pdata *pdata, + unsigned long (*usec_to_riwt)(struct fxgmac_pdata *pdata, unsigned int usec); - unsigned int (*riwt_to_usec)(struct fxgmac_pdata *pdata, + unsigned long (*riwt_to_usec)(struct fxgmac_pdata *pdata, unsigned int riwt); /* For RX and TX threshold config */ @@ -560,10 +560,11 @@ struct fxgmac_hw_ops { int (*config_osp_mode)(struct fxgmac_pdata *pdata); /* For RX and TX PBL config */ + u32 (*calculate_max_checksum_size)(struct fxgmac_pdata *pdata); int (*config_rx_pbl_val)(struct fxgmac_pdata *pdata); - int (*get_rx_pbl_val)(struct fxgmac_pdata *pdata); + u32 (*get_rx_pbl_val)(struct fxgmac_pdata *pdata); int (*config_tx_pbl_val)(struct fxgmac_pdata *pdata); - int (*get_tx_pbl_val)(struct fxgmac_pdata *pdata); + u32 (*get_tx_pbl_val)(struct fxgmac_pdata *pdata); int (*config_pblx8)(struct fxgmac_pdata *pdata); /* For MMC statistics */ @@ -614,7 +615,7 @@ struct fxgmac_hw_ops { int (*set_wake_pattern_mask)(struct fxgmac_pdata *pdata, u32 filter_index, u8 register_index, u32 Data); -#if FUXI_PM_WPI_READ_FEATURE_EN +#if FXGMAC_PM_WPI_READ_FEATURE_ENABLED void (*get_wake_packet_indication)(struct fxgmac_pdata *pdata, int *wake_reason, u32 *wake_pattern_number, @@ -638,7 +639,7 @@ struct fxgmac_hw_ops { void (*phy_eee_feature)(struct fxgmac_pdata *pdata); u32 (*get_ephy_state)(struct fxgmac_pdata *pdata); int (*write_ephy_reg)(struct fxgmac_pdata *pdata, u32 val, u32 data); - int (*read_ephy_reg)(struct fxgmac_pdata *pdata, u32 val, u32 *data); + int (*read_ephy_reg)(struct fxgmac_pdata *pdata, u32 val, u32 __far *data); int (*set_ephy_autoneg_advertise)(struct fxgmac_pdata *pdata, struct fxphy_ag_adv phy_ag_adv); int (*phy_config)(struct fxgmac_pdata *pdata); @@ -675,18 +676,21 @@ struct fxgmac_hw_ops { unsigned int enable); /* efuse relevant operation. */ + bool (*read_patch_from_efuse_per_index)( + struct fxgmac_pdata *pdata, u8 index, u32 __far *offset, + u32 __far *value); /* read patch per index. */ + bool (*read_mac_subsys_from_efuse)(struct fxgmac_pdata *pdata, + u8 *mac_addr, u32 *subsys, + u32 *revid); + bool (*read_efuse_data)(struct fxgmac_pdata *pdata, u32 offset, + u32 __far *value); +#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE bool (*read_patch_from_efuse)(struct fxgmac_pdata *pdata, u32 offset, u32 *value); /* read patch per index. */ - bool (*read_patch_from_efuse_per_index)( - struct fxgmac_pdata *pdata, u8 index, u32 *offset, - u32 *value); /* read patch per index. */ bool (*write_patch_to_efuse)(struct fxgmac_pdata *pdata, u32 offset, u32 value); bool (*write_patch_to_efuse_per_index)(struct fxgmac_pdata *pdata, u8 index, u32 offset, u32 value); - bool (*read_mac_subsys_from_efuse)(struct fxgmac_pdata *pdata, - u8 *mac_addr, u32 *subsys, - u32 *revid); bool (*write_mac_subsys_to_efuse)(struct fxgmac_pdata *pdata, u8 *mac_addr, u32 *subsys, u32 *revid); @@ -695,12 +699,11 @@ struct fxgmac_hw_ops { bool (*write_mac_addr_to_efuse)(struct fxgmac_pdata *pdata, u8 *mac_addr); bool (*efuse_load)(struct fxgmac_pdata *pdata); - bool (*read_efuse_data)(struct fxgmac_pdata *pdata, u32 offset, - u32 *value); bool (*write_oob)(struct fxgmac_pdata *pdata); bool (*write_led)(struct fxgmac_pdata *pdata, u32 value); bool (*read_led_config)(struct fxgmac_pdata *pdata); bool (*write_led_config)(struct fxgmac_pdata *pdata); +#endif int (*pcie_init)(struct fxgmac_pdata *pdata, bool ltr_en, bool aspm_l1ss_en, bool aspm_l1_en, bool aspm_l0s_en); @@ -714,47 +717,47 @@ struct fxgmac_hw_ops { */ struct fxgmac_hw_features { /* HW Version */ - unsigned int version; + u32 version; /* HW Feature Register0 */ - unsigned int phyifsel; /* PHY interface support */ - unsigned int vlhash; /* VLAN Hash Filter */ - unsigned int sma; /* SMA(MDIO) Interface */ - unsigned int rwk; /* PMT remote wake-up packet */ - unsigned int mgk; /* PMT magic packet */ - unsigned int mmc; /* RMON module */ - unsigned int aoe; /* ARP Offload */ - unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ - unsigned int eee; /* Energy Efficient Ethernet */ - unsigned int tx_coe; /* Tx Checksum Offload */ - unsigned int rx_coe; /* Rx Checksum Offload */ - unsigned int addn_mac; /* Additional MAC Addresses */ - unsigned int ts_src; /* Timestamp Source */ - unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */ + u32 phyifsel; /* PHY interface support */ + u32 vlhash; /* VLAN Hash Filter */ + u32 sma; /* SMA(MDIO) Interface */ + u32 rwk; /* PMT remote wake-up packet */ + u32 mgk; /* PMT magic packet */ + u32 mmc; /* RMON module */ + u32 aoe; /* ARP Offload */ + u32 ts; /* IEEE 1588-2008 Advanced Timestamp */ + u32 eee; /* Energy Efficient Ethernet */ + u32 tx_coe; /* Tx Checksum Offload */ + u32 rx_coe; /* Rx Checksum Offload */ + u32 addn_mac; /* Additional MAC Addresses */ + u32 ts_src; /* Timestamp Source */ + u32 sa_vlan_ins; /* Source Address or VLAN Insertion */ /* HW Feature Register1 */ - unsigned int rx_fifo_size; /* MTL Receive FIFO Size */ - unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */ - unsigned int adv_ts_hi; /* Advance Timestamping High Word */ - unsigned int dma_width; /* DMA width */ - unsigned int dcb; /* DCB Feature */ - unsigned int sph; /* Split Header Feature */ - unsigned int tso; /* TCP Segmentation Offload */ - unsigned int dma_debug; /* DMA Debug Registers */ - unsigned int rss; /* Receive Side Scaling */ - unsigned int tc_cnt; /* Number of Traffic Classes */ - unsigned int avsel; /* AV Feature Enable */ - unsigned int ravsel; /* Rx Side Only AV Feature Enable */ - unsigned int hash_table_size; /* Hash Table Size */ - unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */ + u32 rx_fifo_size; /* MTL Receive FIFO Size */ + u32 tx_fifo_size; /* MTL Transmit FIFO Size */ + u32 adv_ts_hi; /* Advance Timestamping High Word */ + u32 dma_width; /* DMA width */ + u32 dcb; /* DCB Feature */ + u32 sph; /* Split Header Feature */ + u32 tso; /* TCP Segmentation Offload */ + u32 dma_debug; /* DMA Debug Registers */ + u32 rss; /* Receive Side Scaling */ + u32 tc_cnt; /* Number of Traffic Classes */ + u32 avsel; /* AV Feature Enable */ + u32 ravsel; /* Rx Side Only AV Feature Enable */ + u32 hash_table_size; /* Hash Table Size */ + u32 l3l4_filter_num; /* Number of L3-L4 Filters */ /* HW Feature Register2 */ - unsigned int rx_q_cnt; /* Number of MTL Receive Queues */ - unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */ - unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */ - unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */ - unsigned int pps_out_num; /* Number of PPS outputs */ - unsigned int aux_snap_num; /* Number of Aux snapshot inputs */ + u32 rx_q_cnt; /* Number of MTL Receive Queues */ + u32 tx_q_cnt; /* Number of MTL Transmit Queues */ + u32 rx_ch_cnt; /* Number of DMA Receive Channels */ + u32 tx_ch_cnt; /* Number of DMA Transmit Channels */ + u32 pps_out_num; /* Number of PPS outputs */ + u32 aux_snap_num; /* Number of Aux snapshot inputs */ /* HW Feature Register3 */ u32 hwfr3; @@ -805,7 +808,7 @@ struct fxgmac_pdata { unsigned int tx_threshold; unsigned int tx_pbl; unsigned int tx_osp_mode; -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED /* for tx hang checking. 20211227 */ unsigned int tx_hang_restart_queuing; #endif @@ -820,7 +823,7 @@ struct fxgmac_pdata { unsigned int tx_frames; /* Rx coalescing settings */ - unsigned int rx_riwt; + unsigned long rx_riwt; unsigned int rx_usecs; unsigned int rx_frames; @@ -880,8 +883,10 @@ struct fxgmac_pdata { int phy_duplex; int phy_autoeng; +#ifndef COMMENT_UNUSED_CODE_TO_REDUCE_SIZE char drv_name[32]; char drv_ver[32]; +#endif struct wol_bitmap_pattern pattern[MAX_PATTERN_COUNT]; @@ -927,6 +932,10 @@ struct fxgmac_pdata { #define FXGMAC_FLAG_RX_NAPI_FREE_LEN 4 #define FXGMAC_FLAG_PER_CHAN_RX_NAPI_FREE_LEN 1 +#ifndef FXGMAC_FAKE_4_TX_QUEUE_ENABLED +#define FXGMAC_FAKE_4_TX_QUEUE_ENABLED 0 +#endif + void fxgmac_init_desc_ops(struct fxgmac_desc_ops *desc_ops); void fxgmac_init_hw_ops(struct fxgmac_hw_ops *hw_ops); const struct net_device_ops *fxgmac_get_netdev_ops(void); diff --git a/drivers/net/ethernet/motorcomm/yt6801/fuxi-os.h b/drivers/net/ethernet/motorcomm/yt6801/fuxi-os.h index 38c27a9d45973..0e2ca78ae063f 100644 --- a/drivers/net/ethernet/motorcomm/yt6801/fuxi-os.h +++ b/drivers/net/ethernet/motorcomm/yt6801/fuxi-os.h @@ -2,28 +2,48 @@ /* Copyright (c) 2021 Motorcomm Corporation. */ -#ifndef __FUXI_OS_H__ -#define __FUXI_OS_H__ +#ifndef __FXGMAC_OS_H__ +#define __FXGMAC_OS_H__ #include +//#include +#include +#include +#include #include #include -#include +#include +#include #include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef CONFIG_PCI_MSI #include #endif -#include -#include -#include -#include -#include -#include -#include #include #include #include "fuxi-dbg.h" @@ -32,7 +52,9 @@ struct fxgmac_ring; struct fxgmac_pdata; struct fxgmac_channel; -#define FXGMAC_DRV_VERSION "1.0.28" +#define FXGMAC_DRV_VERSION "1.0.29" + +#define FXGMAC_INT_MODERATION_ENABLED 1 #define PCIE_LP_ASPM_L0S 1 #define PCIE_LP_ASPM_L1 2 @@ -51,16 +73,16 @@ struct fxgmac_channel; #define FXGMAC_TEST_MAC_HEAD_LEN 14 -#define FUXI_PM_WPI_READ_FEATURE_EN 1 +#define FXGMAC_PM_WPI_READ_FEATURE_ENABLED 1 #define RSS_Q_COUNT 4 -#define FXGMAC_TX_HANG_TIMER_EN 0 +#define FXGMAC_TX_HANG_TIMER_ENABLED 0 /* 1 to trigger(write reg 0x1000) for sniffer stop */ #define FXGMAC_TRIGGER_TX_HANG 0 /* driver feature configuration */ -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED /* 0: check hw current desc; 1: check software dirty */ #define FXGMAC_TX_HANG_CHECH_DIRTY 0 #endif @@ -69,20 +91,20 @@ struct fxgmac_channel; /* when you want to run this driver on 64bit arm, you should open this, * otherwise dma's mask cannot be set successfully. */ -#define FUXI_DMA_BIT_MASK 64 +#define FXGMAC_DMA_BIT_MASK 64 #endif #ifdef CONFIG_PCI_MSI /* should be same as FXGMAC_MAX_DMA_CHANNELS + 1 tx_irq */ #define FXGMAC_MAX_MSIX_Q_VECTORS (FXGMAC_MSIX_Q_VECTORS + 1) -#define FXGMAC_MSIX_CH0RXDIS_EN 0 /* set to 1 for ch0 unbalance fix; */ +#define FXGMAC_MSIX_CH0RXDIS_ENABLED 0 /* set to 1 for ch0 unbalance fix; */ #define FXGMAC_MSIX_INTCTRL_EN 1 #define FXGMAC_PHY_INT_NUM 1 #define FXGMAC_MSIX_INT_NUMS (FXGMAC_MAX_MSIX_Q_VECTORS + FXGMAC_PHY_INT_NUM) #else /* for case of no CONFIG_PCI_MSI */ /* NO modification needed! for non-MSI, set to 0 always */ -#define FXGMAC_MSIX_CH0RXDIS_EN 0 +#define FXGMAC_MSIX_CH0RXDIS_ENABLED 0 #define FXGMAC_MSIX_INTCTRL_EN 0 #endif @@ -120,14 +142,12 @@ struct fxgmac_channel; /*vlan id filter*/ #define FXGMAC_FILTER_SINGLE_VLAN_ENABLED 1 /* 1:enable health checking; */ #define FXGMAC_FILTER_MULTIPLE_VLAN_ENABLED 1 -#define FUXI_MAC_HASH_TABLE 1 +#define FXGMAC_MAC_HASH_TABLE 1 #define FXGMAC_FILTER_MULTIPLE_MAC_ADDR_ENABLED 1 -#define FUXI_MISC_INT_HANDLE_FEATURE_EN 1 +#define FXGMAC_MISC_INT_HANDLE_FEATURE_ENABLED 1 #define FXGMAC_ESD_RESTORE_PCIE_CFG -#define FXGMAC_FIX_FT_D2000_PLATFORM_WOL_ISSUE 1 - #define FXGMAC_WOL_INTEGRATED_WOL_PARAMETER #define FXGMAC_LINK_SPEED_CHECK_PHY_LINK @@ -146,13 +166,22 @@ struct fxgmac_channel; #define FXGMAC_USE_DEFAULT_RSS_KEY_TBALE -#define FXGMAC_RX_VLAN_FILTERING (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) +#define FXGMAC_RX_VLAN_FILTERING_ENABLED (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) + +#define FXGMAC_NETDEV_PR_MODE_ENABLED ((pdata->netdev->flags & IFF_PROMISC) != 0) +#define FXGMAC_NETDEV_AM_MODE_ENABLED ((pdata->netdev->flags & IFF_ALLMULTI) != 0) +#define FXGMAC_NETDEV_MU_MODE_ENABLED ((pdata->netdev->flags & IFF_MULTICAST) != 0) +#define FXGMAC_NETDEV_BD_MODE_ENABLED ((pdata->netdev->flags & IFF_BROADCAST) != 0) -#define FXGMAC_NETDEV_PR_MODE ((pdata->netdev->flags & IFF_PROMISC) != 0) +#define FXGMAC_RX_CHECKSUM_ENABLED (pdata->netdev->features & NETIF_F_RXCSUM) -#define FXGMAC_NETDEV_AM_MODE ((pdata->netdev->flags & IFF_ALLMULTI) != 0) +#define TEST_MAC_HEAD 14 +#define TEST_TCP_HEAD_LEN_OFFSET 12 +#define TEST_TCP_OFFLOAD_LEN_OFFSET 48 +#define TEST_TCP_FIX_HEAD_LEN 24 +#define TEST_TCP_MSS_OFFSET 56 -#define FXGMAC_RX_CHECKSUM (pdata->netdev->features & NETIF_F_RXCSUM) +#define DF_MAX_NIC_NUM 16 /* #define HAVE_FXGMAC_DEBUG_FS */ @@ -241,6 +270,10 @@ struct fxgmac_channel; #define fxgmac_dump_buffer(_skb, _len, _tx_rx) #define DumpLine(_p, _cbLine, _fAddress, _ulGroup) +#ifndef __far +#define __far +#endif + #ifndef FXGMAC_DEBUG /* #define FXGMAC_DEBUG */ #endif @@ -250,7 +283,18 @@ struct fxgmac_channel; #define FXGMAC_PR(fmt, args...) \ pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) +/* + * If you want to continue a line, you NEED to use KERN_CONT. + * That has always been true. It hasn't always been enforced, though. + * If you do two printk's and the second one doesn't say "I'm a continuation", + * the printk logic assumes you're just confused and wanted two lines. + */ +#define DPRINTK(fmt, args...) \ + printk(KERN_CONT fmt, ## args) +#else #define DPRINTK printk +#endif #else #define FXGMAC_PR(x...) do { } while (0) #define DPRINTK(x...) @@ -259,12 +303,12 @@ struct fxgmac_channel; #define IOC_MAGIC 'M' #define IOC_MAXNR (0x80 + 5) -#define FUXI_DFS_IOCTL_DEVICE_INACTIVE 0x10001 -#define FUXI_DFS_IOCTL_DEVICE_RESET 0x10002 -#define FUXI_DFS_IOCTL_DIAG_BEGIN 0x10003 -#define FUXI_DFS_IOCTL_DIAG_END 0x10004 -#define FUXI_DFS_IOCTL_DIAG_TX_PKT 0x10005 -#define FUXI_DFS_IOCTL_DIAG_RX_PKT 0x10006 +#define FXGMAC_DFS_IOCTL_DEVICE_INACTIVE 0x10001 +#define FXGMAC_DFS_IOCTL_DEVICE_RESET 0x10002 +#define FXGMAC_DFS_IOCTL_DIAG_BEGIN 0x10003 +#define FXGMAC_DFS_IOCTL_DIAG_END 0x10004 +#define FXGMAC_DFS_IOCTL_DIAG_TX_PKT 0x10005 +#define FXGMAC_DFS_IOCTL_DIAG_RX_PKT 0x10006 #define FXGMAC_EFUSE_UPDATE_LED_CFG 0x10007 #define FXGMAC_EFUSE_WRITE_LED 0x10008 @@ -285,7 +329,7 @@ struct fxgmac_channel; #define FXGMAC_SET_REG 0x10016 #define FXGMAC_GET_PHY_REG 0x10017 #define FXGMAC_SET_PHY_REG 0x10018 -#define FXGMAC_EPHYSTATISTICS 0x10019 +#define FXGMAC_EPHY_STATISTICS 0x10019 #define FXGMAC_GET_STATISTICS 0x1001A #define FXGMAC_GET_PCIE_LOCATION 0x1001B @@ -317,11 +361,18 @@ struct fxgmac_channel; #define FXGMAC_NAPI_DISABLE 0x0 #ifndef fallthrough + +#ifdef __has_attribute #if __has_attribute(__fallthrough__) # define fallthrough __attribute__((__fallthrough__)) #else # define fallthrough do {} while (0) /* fallthrough */ #endif + +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif + #endif #define PHY_POWER_DOWN 1 @@ -338,6 +389,16 @@ struct fxgmac_channel; #define FXGMAC_PCIE_IO_MEM_MASTER_ENABLE 0x7 #endif +#ifndef BIT +#define BIT(n) (0x1<<(n)) +#endif + +#define UDP_RSS_FLAGS (BIT(MAC_RSSCR_UDP4TE_POS) | \ + BIT(MAC_RSSCR_UDP6TE_POS)) + +#define MF90_SUB_VENTOR_ID 0x17aa +#define MF90_SUB_DEVICE_ID 0x3509 + #pragma pack(1) /* it's better to make this struct's size to 128byte. */ struct pattern_packet{ @@ -428,7 +489,7 @@ typedef struct fxgmac_channel_of_platform { struct napi_struct napi_rx; struct timer_list tx_timer; -#if FXGMAC_TX_HANG_TIMER_EN +#if FXGMAC_TX_HANG_TIMER_ENABLED unsigned int tx_hang_timer_active; struct timer_list tx_hang_timer; unsigned int tx_hang_hw_cur; @@ -493,6 +554,10 @@ typedef struct fxgmac_pdata_of_platform { u32 cfg_device_ctrl2; u32 cfg_msix_capability; + int pre_phy_speed; + int pre_phy_duplex; + int pre_phy_autoneg; + struct work_struct restart_work; #ifdef FXGMAC_ESD_CHECK_ENABLED struct delayed_work esd_work; @@ -523,28 +588,17 @@ typedef struct fxgmac_pdata_of_platform { volatile u32 fxgmac_test_skb_arr_in_index; volatile u32 fxgmac_test_skb_arr_out_index; struct sk_buff *fxgmac_test_skb_array[FXGMAC_MAX_DBG_TEST_PKT]; -#ifdef HAVE_FXGMAC_DEBUG_FS - struct dentry *dbg_adapter; - struct dentry *fxgmac_dbg_root; - char fxgmac_dbg_netdev_ops_buf[FXGMAC_NETDEV_OPS_BUF_LEN]; -#endif DEV_STATE dev_state; struct mutex mutex; + struct timer_list phy_poll_tm; } FXGMAC_PDATA_OF_PLATFORM; void fxgmac_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx); int fxgmac_dismiss_all_int(struct fxgmac_pdata *pdata); -#ifdef HAVE_FXGMAC_DEBUG_FS -void fxgmac_dbg_adapter_init(struct fxgmac_pdata *pdata); -void fxgmac_dbg_adapter_exit(struct fxgmac_pdata *pdata); -void fxgmac_dbg_init(struct fxgmac_pdata *pdata); -void fxgmac_dbg_exit(struct fxgmac_pdata *pdata); -#endif /* HAVE_FXGMAC_DEBUG_FS */ - void fxgmac_restart_dev(struct fxgmac_pdata *pdata); -long fxgmac_dbg_netdev_ops_ioctl(struct file *file, unsigned int cmd, +long fxgmac_netdev_ops_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int fxgmac_init(struct fxgmac_pdata *pdata, bool save_private_reg); @@ -554,10 +608,13 @@ int fxgmac_ephy_autoneg_ability_get(struct fxgmac_pdata *pdata, int fxgmac_ephy_status_get(struct fxgmac_pdata *pdata, int *speed, int *duplex, int *ret_link, int *media); int fxgmac_ephy_soft_reset(struct fxgmac_pdata *pdata); -void fxgmac_phy_force_mode(struct fxgmac_pdata *pdata); -void fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed); -void fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex); -void fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg); +int fxgmac_phy_force_mode(struct fxgmac_pdata *pdata); +int fxgmac_phy_force_speed(struct fxgmac_pdata *pdata, int speed); +int fxgmac_phy_force_duplex(struct fxgmac_pdata *pdata, int duplex); +int fxgmac_phy_force_autoneg(struct fxgmac_pdata *pdata, int autoneg); +//void fxgmac_act_phy_link(struct fxgmac_pdata *pdata); +int fxgmac_phy_timer_init(struct fxgmac_pdata *pdata); +void fxgmac_phy_timer_destroy(struct fxgmac_pdata *pdata); unsigned int fxgmac_get_netdev_ip4addr(struct fxgmac_pdata *pdata); unsigned char *fxgmac_get_netdev_ip6addr(struct fxgmac_pdata *pdata, @@ -579,7 +636,6 @@ void fxgmac_free_tx_data(struct fxgmac_pdata *pdata); void fxgmac_tx_start_xmit(struct fxgmac_channel *channel, struct fxgmac_ring *ring); void fxgmac_dev_xmit(struct fxgmac_channel *channel); -int fxgmac_dev_read(struct fxgmac_channel *channel); void fxgmac_config_wol(struct fxgmac_pdata *pdata, int en); void fxgmac_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx); @@ -587,4 +643,6 @@ void fxgmac_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx void fxgmac_lock(struct fxgmac_pdata *pdata); void fxgmac_unlock(struct fxgmac_pdata *pdata); +void fxgmac_set_phy_link_ksettings(struct fxgmac_pdata *pdata); + #endif /* __FUXI_OS_H__ */