r8126: bump to 10.014.01
Signed-off-by: sbwml <admin@cooluc.com>
This commit is contained in:
parent
a8acee1c01
commit
da6e994d80
14
Makefile
14
Makefile
@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
PKG_NAME:=r8126
|
PKG_NAME:=r8126
|
||||||
PKG_VERSION:=10.013.00
|
PKG_VERSION:=10.014.01
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
@ -15,10 +15,11 @@ PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
|||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define KernelPackage/r8126
|
define KernelPackage/r8126
|
||||||
TITLE:=Driver for Realtek r8126 chipsets
|
TITLE:=Realtek RTL8126 PCI 5 Gigabit Ethernet driver
|
||||||
SUBMENU:=Network Devices
|
SUBMENU:=Network Devices
|
||||||
DEPENDS:=@PCI_SUPPORT
|
DEPENDS:=@PCI_SUPPORT +kmod-libphy
|
||||||
FILES:= $(PKG_BUILD_DIR)/r8126.ko
|
FILES:= $(PKG_BUILD_DIR)/r8126.ko
|
||||||
|
PROVIDES:=kmod-r8169
|
||||||
AUTOLOAD:=$(call AutoProbe,r8126)
|
AUTOLOAD:=$(call AutoProbe,r8126)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@ -26,8 +27,13 @@ define Package/r8126/description
|
|||||||
This package contains a driver for Realtek r8126 chipsets.
|
This package contains a driver for Realtek r8126 chipsets.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
PKG_MAKE_FLAGS += ENABLE_RSS_SUPPORT=y
|
||||||
|
|
||||||
define Build/Compile
|
define Build/Compile
|
||||||
+$(KERNEL_MAKE) M=$(PKG_BUILD_DIR) modules
|
+$(KERNEL_MAKE) $(PKG_JOBS) \
|
||||||
|
$(PKG_MAKE_FLAGS) \
|
||||||
|
M="$(PKG_BUILD_DIR)" \
|
||||||
|
modules
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call KernelPackage,r8126))
|
$(eval $(call KernelPackage,r8126))
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
--- a/Makefile
|
|
||||||
+++ b/Makefile
|
|
||||||
@@ -44,7 +44,7 @@ ENABLE_TX_NO_CLOSE = y
|
|
||||||
ENABLE_MULTIPLE_TX_QUEUE = y
|
|
||||||
ENABLE_PTP_SUPPORT = n
|
|
||||||
ENABLE_PTP_MASTER_MODE = n
|
|
||||||
-ENABLE_RSS_SUPPORT = n
|
|
||||||
+ENABLE_RSS_SUPPORT = y
|
|
||||||
ENABLE_LIB_SUPPORT = n
|
|
||||||
ENABLE_USE_FIRMWARE_FILE = n
|
|
||||||
DISABLE_WOL_SUPPORT = n
|
|
@ -1,116 +0,0 @@
|
|||||||
--- a/r8126_n.c
|
|
||||||
+++ b/r8126_n.c
|
|
||||||
@@ -6929,7 +6929,11 @@ rtl8126_device_lpi_t_to_ethtool_lpi_t(st
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+rtl_ethtool_get_eee(struct net_device *net, struct ethtool_keee *edata)
|
|
||||||
+#else
|
|
||||||
rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata)
|
|
||||||
+#endif
|
|
||||||
{
|
|
||||||
struct rtl8126_private *tp = netdev_priv(net);
|
|
||||||
struct ethtool_eee *eee = &tp->eee;
|
|
||||||
@@ -6962,9 +6966,15 @@ rtl_ethtool_get_eee(struct net_device *n
|
|
||||||
|
|
||||||
edata->eee_enabled = !!val;
|
|
||||||
edata->eee_active = !!(supported & adv & lp);
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+ ethtool_convert_legacy_u32_to_link_mode(edata->supported, supported);
|
|
||||||
+ ethtool_convert_legacy_u32_to_link_mode(edata->advertised, adv);
|
|
||||||
+ ethtool_convert_legacy_u32_to_link_mode(edata->lp_advertised, lp);
|
|
||||||
+#else
|
|
||||||
edata->supported = supported;
|
|
||||||
edata->advertised = adv;
|
|
||||||
edata->lp_advertised = lp;
|
|
||||||
+#endif
|
|
||||||
edata->tx_lpi_enabled = edata->eee_enabled;
|
|
||||||
edata->tx_lpi_timer = tx_lpi_timer;
|
|
||||||
|
|
||||||
@@ -6972,11 +6982,19 @@ rtl_ethtool_get_eee(struct net_device *n
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+rtl_ethtool_set_eee(struct net_device *net, struct ethtool_keee *edata)
|
|
||||||
+#else
|
|
||||||
rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata)
|
|
||||||
+#endif
|
|
||||||
{
|
|
||||||
struct rtl8126_private *tp = netdev_priv(net);
|
|
||||||
struct ethtool_eee *eee = &tp->eee;
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+ u32 advertising, adv;
|
|
||||||
+#else
|
|
||||||
u32 advertising;
|
|
||||||
+#endif
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp) ||
|
|
||||||
@@ -7008,6 +7026,18 @@ rtl_ethtool_set_eee(struct net_device *n
|
|
||||||
*/
|
|
||||||
|
|
||||||
advertising = tp->advertising;
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+ ethtool_convert_link_mode_to_legacy_u32(&adv, edata->advertised);
|
|
||||||
+ if (linkmode_empty(edata->advertised)) {
|
|
||||||
+ adv = advertising & eee->supported;
|
|
||||||
+ ethtool_convert_legacy_u32_to_link_mode(edata->advertised, adv);
|
|
||||||
+ } else if (!linkmode_empty(edata->advertised) & ~advertising) {
|
|
||||||
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of autoneg advertised speeds %x\n",
|
|
||||||
+ adv, advertising);
|
|
||||||
+ rc = -EINVAL;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+#else
|
|
||||||
if (!edata->advertised) {
|
|
||||||
edata->advertised = advertising & eee->supported;
|
|
||||||
} else if (edata->advertised & ~advertising) {
|
|
||||||
@@ -7016,13 +7046,23 @@ rtl_ethtool_set_eee(struct net_device *n
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+ if (!linkmode_empty(edata->advertised) & ~eee->supported) {
|
|
||||||
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of support %x\n",
|
|
||||||
+ adv, eee->supported);
|
|
||||||
+ rc = -EINVAL;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+#else
|
|
||||||
if (edata->advertised & ~eee->supported) {
|
|
||||||
dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of support %x\n",
|
|
||||||
edata->advertised, eee->supported);
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
//tp->eee.eee_enabled = edata->eee_enabled;
|
|
||||||
//tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
|
|
||||||
@@ -7030,7 +7070,11 @@ rtl_ethtool_set_eee(struct net_device *n
|
|
||||||
dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE tx_lpi_timer %x must be a subset of support %x\n",
|
|
||||||
edata->tx_lpi_timer, eee->tx_lpi_timer);
|
|
||||||
|
|
||||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0)
|
|
||||||
+ ethtool_convert_link_mode_to_legacy_u32(&eee->advertised, edata->advertised);
|
|
||||||
+#else
|
|
||||||
eee->advertised = edata->advertised;
|
|
||||||
+#endif
|
|
||||||
//eee->tx_lpi_enabled = edata->tx_lpi_enabled;
|
|
||||||
//eee->tx_lpi_timer = edata->tx_lpi_timer;
|
|
||||||
eee->eee_enabled = edata->eee_enabled;
|
|
||||||
@@ -7106,8 +7150,10 @@ static const struct ethtool_ops rtl8126_
|
|
||||||
.set_rxnfc = rtl8126_set_rxnfc,
|
|
||||||
.get_rxfh_indir_size = rtl8126_rss_indir_size,
|
|
||||||
.get_rxfh_key_size = rtl8126_get_rxfh_key_size,
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0)
|
|
||||||
.get_rxfh = rtl8126_get_rxfh,
|
|
||||||
.set_rxfh = rtl8126_set_rxfh,
|
|
||||||
+#endif
|
|
||||||
#endif //ENABLE_RSS_SUPPORT
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
|
|
||||||
#ifdef ENABLE_PTP_SUPPORT
|
|
@ -31,6 +31,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
CONFIG_SOC_LAN = n
|
CONFIG_SOC_LAN = n
|
||||||
|
ENABLE_FIBER_SUPPORT = n
|
||||||
ENABLE_REALWOW_SUPPORT = n
|
ENABLE_REALWOW_SUPPORT = n
|
||||||
ENABLE_DASH_SUPPORT = n
|
ENABLE_DASH_SUPPORT = n
|
||||||
ENABLE_DASH_PRINTER_SUPPORT = n
|
ENABLE_DASH_PRINTER_SUPPORT = n
|
||||||
@ -41,7 +42,7 @@ ENABLE_S5_KEEP_CURR_MAC = n
|
|||||||
ENABLE_EEE = y
|
ENABLE_EEE = y
|
||||||
ENABLE_S0_MAGIC_PACKET = n
|
ENABLE_S0_MAGIC_PACKET = n
|
||||||
ENABLE_TX_NO_CLOSE = y
|
ENABLE_TX_NO_CLOSE = y
|
||||||
ENABLE_MULTIPLE_TX_QUEUE = y
|
ENABLE_MULTIPLE_TX_QUEUE = n
|
||||||
ENABLE_PTP_SUPPORT = n
|
ENABLE_PTP_SUPPORT = n
|
||||||
ENABLE_PTP_MASTER_MODE = n
|
ENABLE_PTP_MASTER_MODE = n
|
||||||
ENABLE_RSS_SUPPORT = n
|
ENABLE_RSS_SUPPORT = n
|
||||||
@ -59,6 +60,10 @@ ifneq ($(KERNELRELEASE),)
|
|||||||
ifeq ($(CONFIG_SOC_LAN), y)
|
ifeq ($(CONFIG_SOC_LAN), y)
|
||||||
EXTRA_CFLAGS += -DCONFIG_SOC_LAN
|
EXTRA_CFLAGS += -DCONFIG_SOC_LAN
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(ENABLE_FIBER_SUPPORT), y)
|
||||||
|
r8126-objs += r8126_fiber.o
|
||||||
|
EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT
|
||||||
|
endif
|
||||||
ifeq ($(ENABLE_REALWOW_SUPPORT), y)
|
ifeq ($(ENABLE_REALWOW_SUPPORT), y)
|
||||||
r8126-objs += r8126_realwow.o
|
r8126-objs += r8126_realwow.o
|
||||||
EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT
|
EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT
|
||||||
|
304
src/r8126.h
304
src/r8126.h
@ -41,7 +41,12 @@
|
|||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include "r8126_dash.h"
|
#include "r8126_dash.h"
|
||||||
#include "r8126_realwow.h"
|
#include "r8126_realwow.h"
|
||||||
|
#ifdef ENABLE_FIBER_SUPPORT
|
||||||
|
#include "r8126_fiber.h"
|
||||||
|
#endif /* ENABLE_FIBER_SUPPORT */
|
||||||
|
#ifdef ENABLE_PTP_SUPPORT
|
||||||
#include "r8126_ptp.h"
|
#include "r8126_ptp.h"
|
||||||
|
#endif
|
||||||
#include "r8126_rss.h"
|
#include "r8126_rss.h"
|
||||||
#ifdef ENABLE_LIB_SUPPORT
|
#ifdef ENABLE_LIB_SUPPORT
|
||||||
#include "r8126_lib.h"
|
#include "r8126_lib.h"
|
||||||
@ -51,6 +56,103 @@
|
|||||||
#define fallthrough
|
#define fallthrough
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
|
||||||
|
#define netif_xmit_stopped netif_tx_queue_stopped
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
|
||||||
|
#ifndef MDIO_AN_EEE_ADV_100TX
|
||||||
|
#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */
|
||||||
|
#endif
|
||||||
|
#ifndef MDIO_AN_EEE_ADV_1000T
|
||||||
|
#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
|
||||||
|
#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */
|
||||||
|
#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */
|
||||||
|
#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */
|
||||||
|
#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */
|
||||||
|
#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */
|
||||||
|
#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */
|
||||||
|
|
||||||
|
static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv)
|
||||||
|
{
|
||||||
|
u32 adv = 0;
|
||||||
|
|
||||||
|
if (eee_adv & MDIO_EEE_100TX)
|
||||||
|
adv |= ADVERTISED_100baseT_Full;
|
||||||
|
if (eee_adv & MDIO_EEE_1000T)
|
||||||
|
adv |= ADVERTISED_1000baseT_Full;
|
||||||
|
if (eee_adv & MDIO_EEE_10GT)
|
||||||
|
adv |= ADVERTISED_10000baseT_Full;
|
||||||
|
if (eee_adv & MDIO_EEE_1000KX)
|
||||||
|
adv |= ADVERTISED_1000baseKX_Full;
|
||||||
|
if (eee_adv & MDIO_EEE_10GKX4)
|
||||||
|
adv |= ADVERTISED_10000baseKX4_Full;
|
||||||
|
if (eee_adv & MDIO_EEE_10GKR)
|
||||||
|
adv |= ADVERTISED_10000baseKR_Full;
|
||||||
|
|
||||||
|
return adv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
|
||||||
|
{
|
||||||
|
u16 reg = 0;
|
||||||
|
|
||||||
|
if (adv & ADVERTISED_100baseT_Full)
|
||||||
|
reg |= MDIO_EEE_100TX;
|
||||||
|
if (adv & ADVERTISED_1000baseT_Full)
|
||||||
|
reg |= MDIO_EEE_1000T;
|
||||||
|
if (adv & ADVERTISED_10000baseT_Full)
|
||||||
|
reg |= MDIO_EEE_10GT;
|
||||||
|
if (adv & ADVERTISED_1000baseKX_Full)
|
||||||
|
reg |= MDIO_EEE_1000KX;
|
||||||
|
if (adv & ADVERTISED_10000baseKX4_Full)
|
||||||
|
reg |= MDIO_EEE_10GKX4;
|
||||||
|
if (adv & ADVERTISED_10000baseKR_Full)
|
||||||
|
reg |= MDIO_EEE_10GKR;
|
||||||
|
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)
|
||||||
|
static inline bool skb_transport_header_was_set(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb->transport_header != ~0U;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)
|
||||||
|
static inline void linkmode_set_bit(int nr, volatile unsigned long *addr)
|
||||||
|
{
|
||||||
|
__set_bit(nr, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr)
|
||||||
|
{
|
||||||
|
__clear_bit(nr, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int linkmode_test_bit(int nr, volatile unsigned long *addr)
|
||||||
|
{
|
||||||
|
return test_bit(nr, addr);
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
|
||||||
|
static inline void linkmode_mod_bit(int nr, volatile unsigned long *addr,
|
||||||
|
int set)
|
||||||
|
{
|
||||||
|
if (set)
|
||||||
|
linkmode_set_bit(nr, addr);
|
||||||
|
else
|
||||||
|
linkmode_clear_bit(nr, addr);
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0) */
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
|
||||||
static inline
|
static inline
|
||||||
ssize_t strscpy(char *dest, const char *src, size_t count)
|
ssize_t strscpy(char *dest, const char *src, size_t count)
|
||||||
@ -110,11 +212,25 @@ static inline void netdev_tx_reset_queue(struct netdev_queue *q) {}
|
|||||||
#define netif_testing_off(dev)
|
#define netif_testing_off(dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0)
|
||||||
|
#define netdev_sw_irq_coalesce_default_on(dev)
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0) */
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
|
||||||
typedef int netdev_tx_t;
|
typedef int netdev_tx_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0)
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,9)
|
||||||
|
static inline bool page_is_pfmemalloc(struct page *page)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Page index cannot be this large so this must be
|
||||||
|
* a pfmemalloc page.
|
||||||
|
*/
|
||||||
|
return page->index == -1UL;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,1,9) */
|
||||||
static inline bool dev_page_is_reusable(struct page *page)
|
static inline bool dev_page_is_reusable(struct page *page)
|
||||||
{
|
{
|
||||||
return likely(page_to_nid(page) == numa_mem_id() &&
|
return likely(page_to_nid(page) == numa_mem_id() &&
|
||||||
@ -273,7 +389,7 @@ do { \
|
|||||||
#define ENABLE_R8126_PROCFS
|
#define ENABLE_R8126_PROCFS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
|
||||||
#define ENABLE_R8126_SYSFS
|
#define ENABLE_R8126_SYSFS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -392,6 +508,23 @@ do { \
|
|||||||
#define MDIO_EEE_5GT 0x0002
|
#define MDIO_EEE_5GT 0x0002
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0)
|
||||||
|
#define ethtool_keee ethtool_eee
|
||||||
|
#define rtl8126_ethtool_adv_to_mmd_eee_adv_cap1_t ethtool_adv_to_mmd_eee_adv_t
|
||||||
|
static inline u32 rtl8126_ethtool_adv_to_mmd_eee_adv_cap2_t(u32 adv)
|
||||||
|
{
|
||||||
|
u32 result = 0;
|
||||||
|
|
||||||
|
if (adv & SUPPORTED_2500baseX_Full)
|
||||||
|
result |= MDIO_EEE_2_5GT;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define rtl8126_ethtool_adv_to_mmd_eee_adv_cap1_t linkmode_to_mii_eee_cap1_t
|
||||||
|
#define rtl8126_ethtool_adv_to_mmd_eee_adv_cap2_t linkmode_to_mii_eee_cap2_t
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) */
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
#define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8126_netpoll
|
#define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8126_netpoll
|
||||||
@ -450,6 +583,16 @@ do { \
|
|||||||
#else
|
#else
|
||||||
#define NAPI_SUFFIX ""
|
#define NAPI_SUFFIX ""
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_FIBER_SUPPORT
|
||||||
|
#define FIBER_SUFFIX "-FIBER"
|
||||||
|
#else
|
||||||
|
#define FIBER_SUFFIX ""
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_REALWOW_SUPPORT
|
||||||
|
#define REALWOW_SUFFIX "-REALWOW"
|
||||||
|
#else
|
||||||
|
#define REALWOW_SUFFIX ""
|
||||||
|
#endif
|
||||||
#if defined(ENABLE_DASH_PRINTER_SUPPORT)
|
#if defined(ENABLE_DASH_PRINTER_SUPPORT)
|
||||||
#define DASH_SUFFIX "-PRINTER"
|
#define DASH_SUFFIX "-PRINTER"
|
||||||
#elif defined(ENABLE_DASH_SUPPORT)
|
#elif defined(ENABLE_DASH_SUPPORT)
|
||||||
@ -476,7 +619,7 @@ do { \
|
|||||||
#define RSS_SUFFIX ""
|
#define RSS_SUFFIX ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RTL8126_VERSION "10.013.00" NAPI_SUFFIX DASH_SUFFIX REALWOW_SUFFIX PTP_SUFFIX RSS_SUFFIX
|
#define RTL8126_VERSION "10.014.01" NAPI_SUFFIX DASH_SUFFIX REALWOW_SUFFIX PTP_SUFFIX RSS_SUFFIX
|
||||||
#define MODULENAME "r8126"
|
#define MODULENAME "r8126"
|
||||||
#define PFX MODULENAME ": "
|
#define PFX MODULENAME ": "
|
||||||
|
|
||||||
@ -488,7 +631,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
|||||||
#ifdef RTL8126_DEBUG
|
#ifdef RTL8126_DEBUG
|
||||||
#define assert(expr) \
|
#define assert(expr) \
|
||||||
if(!(expr)) { \
|
if(!(expr)) { \
|
||||||
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
|
printk("Assertion failed! %s,%s,%s,line=%d\n", \
|
||||||
#expr,__FILE__,__FUNCTION__,__LINE__); \
|
#expr,__FILE__,__FUNCTION__,__LINE__); \
|
||||||
}
|
}
|
||||||
#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0)
|
#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0)
|
||||||
@ -597,7 +740,9 @@ This is free software, and you are welcome to redistribute it under certain cond
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define R8126_MAX_TX_QUEUES (2)
|
#define R8126_MAX_TX_QUEUES (2)
|
||||||
#define R8126_MAX_RX_QUEUES (4)
|
#define R8126_MAX_RX_QUEUES_V2 (4)
|
||||||
|
#define R8126_MAX_RX_QUEUES_V3 (16)
|
||||||
|
#define R8126_MAX_RX_QUEUES R8126_MAX_RX_QUEUES_V3
|
||||||
#define R8126_MAX_QUEUES R8126_MAX_RX_QUEUES
|
#define R8126_MAX_QUEUES R8126_MAX_RX_QUEUES
|
||||||
|
|
||||||
#define OCP_STD_PHY_BASE 0xa400
|
#define OCP_STD_PHY_BASE 0xa400
|
||||||
@ -675,10 +820,15 @@ This is free software, and you are welcome to redistribute it under certain cond
|
|||||||
#define ADVERTISE_1000HALF 0x100
|
#define ADVERTISE_1000HALF 0x100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BIT_ULL
|
||||||
|
#define BIT_ULL(nr) (1ULL << (nr))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ADVERTISED_2500baseX_Full
|
#ifndef ADVERTISED_2500baseX_Full
|
||||||
#define ADVERTISED_2500baseX_Full 0x8000
|
#define ADVERTISED_2500baseX_Full 0x8000
|
||||||
#endif
|
#endif
|
||||||
#define RTK_ADVERTISED_5000baseX_Full BIT(48)
|
#define RTK_ADVERTISED_5000baseX_Full BIT_ULL(48)
|
||||||
|
#define RTK_SUPPORTED_5000baseX_Full BIT_ULL(48)
|
||||||
|
|
||||||
#define RTK_ADVERTISE_2500FULL 0x80
|
#define RTK_ADVERTISE_2500FULL 0x80
|
||||||
#define RTK_ADVERTISE_5000FULL 0x100
|
#define RTK_ADVERTISE_5000FULL 0x100
|
||||||
@ -723,12 +873,16 @@ This is free software, and you are welcome to redistribute it under certain cond
|
|||||||
#define SPEED_5000 5000
|
#define SPEED_5000 5000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define R8126_LINK_STATE_OFF 0
|
||||||
|
#define R8126_LINK_STATE_ON 1
|
||||||
|
#define R8126_LINK_STATE_UNKNOWN 2
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
|
//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
|
||||||
#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \
|
#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) || \
|
||||||
(( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \
|
((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && \
|
||||||
( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) )))
|
(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3))))
|
||||||
/* copied from linux kernel 2.6.20 include/linux/netdev.h */
|
/* copied from linux kernel 2.6.20 include/linux/netdev.h */
|
||||||
#define NETDEV_ALIGN 32
|
#define NETDEV_ALIGN 32
|
||||||
#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1)
|
#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1)
|
||||||
@ -864,7 +1018,7 @@ extern void __chk_io_ptr(void __iomem *);
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* 2.5.28 => 2.4.23 */
|
/* 2.5.28 => 2.4.23 */
|
||||||
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28))
|
||||||
|
|
||||||
static inline void _kc_synchronize_irq(void)
|
static inline void _kc_synchronize_irq(void)
|
||||||
{
|
{
|
||||||
@ -885,12 +1039,12 @@ static inline void _kc_synchronize_irq(void)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* 2.6.4 => 2.6.0 */
|
/* 2.6.4 => 2.6.0 */
|
||||||
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4))
|
||||||
#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
|
#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
|
||||||
#endif /* 2.6.4 => 2.6.0 */
|
#endif /* 2.6.4 => 2.6.0 */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* 2.6.0 => 2.5.28 */
|
/* 2.6.0 => 2.5.28 */
|
||||||
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
|
||||||
#define MODULE_INFO(version, _version)
|
#define MODULE_INFO(version, _version)
|
||||||
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
|
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
|
||||||
#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1
|
#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1
|
||||||
@ -921,13 +1075,13 @@ static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* 2.4.22 => 2.4.17 */
|
/* 2.4.22 => 2.4.17 */
|
||||||
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22))
|
||||||
#define pci_name(x) ((x)->slot_name)
|
#define pci_name(x) ((x)->slot_name)
|
||||||
#endif /* 2.4.22 => 2.4.17 */
|
#endif /* 2.4.22 => 2.4.17 */
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* 2.6.5 => 2.6.0 */
|
/* 2.6.5 => 2.6.0 */
|
||||||
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5))
|
||||||
#define pci_dma_sync_single_for_cpu pci_dma_sync_single
|
#define pci_dma_sync_single_for_cpu pci_dma_sync_single
|
||||||
#define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu
|
#define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu
|
||||||
#endif /* 2.6.5 => 2.6.0 */
|
#endif /* 2.6.5 => 2.6.0 */
|
||||||
@ -1411,6 +1565,26 @@ enum RTL8126_registers {
|
|||||||
PPS_RISE_TIME_S_8125 = 0x68A4,
|
PPS_RISE_TIME_S_8125 = 0x68A4,
|
||||||
PTP_EGRESS_TIME_BASE_NS_8125 = 0XCF20,
|
PTP_EGRESS_TIME_BASE_NS_8125 = 0XCF20,
|
||||||
PTP_EGRESS_TIME_BASE_S_8125 = 0XCF24,
|
PTP_EGRESS_TIME_BASE_S_8125 = 0XCF24,
|
||||||
|
PTP_CTL = 0xE400,
|
||||||
|
PTP_INER = 0xE402,
|
||||||
|
PTP_INSR = 0xE404,
|
||||||
|
PTP_SYNCE_CTL = 0xE406,
|
||||||
|
PTP_GEN_CFG = 0xE408,
|
||||||
|
PTP_CLK_CFG_8126 = 0xE410,
|
||||||
|
PTP_CFG_NS_LO_8126 = 0xE412,
|
||||||
|
PTP_CFG_NS_HI_8126 = 0xE414,
|
||||||
|
PTP_CFG_S_LO_8126 = 0xE416,
|
||||||
|
PTP_CFG_S_MI_8126 = 0xE418,
|
||||||
|
PTP_CFG_S_HI_8126 = 0xE41A,
|
||||||
|
PTP_TAI_CFG = 0xE420,
|
||||||
|
PTP_TAI_TS_S_LO = 0xE42A,
|
||||||
|
PTP_TAI_TS_S_HI = 0xE42C,
|
||||||
|
PTP_TRX_TS_STA = 0xE430,
|
||||||
|
PTP_TRX_TS_NS_LO = 0xE446,
|
||||||
|
PTP_TRX_TS_NS_HI = 0xE448,
|
||||||
|
PTP_TRX_TS_S_LO = 0xE44A,
|
||||||
|
PTP_TRX_TS_S_MI = 0xE44C,
|
||||||
|
PTP_TRX_TS_S_HI = 0xE44E,
|
||||||
|
|
||||||
//TCAM
|
//TCAM
|
||||||
TCAM_NOTVALID_ADDR = 0xA000,
|
TCAM_NOTVALID_ADDR = 0xA000,
|
||||||
@ -1451,6 +1625,10 @@ enum RTL8126_register_content {
|
|||||||
RxRUNT_V3 = (1 << 19),
|
RxRUNT_V3 = (1 << 19),
|
||||||
RxCRC_V3 = (1 << 17),
|
RxCRC_V3 = (1 << 17),
|
||||||
|
|
||||||
|
RxRES_V4 = (1 << 22),
|
||||||
|
RxRUNT_V4 = (1 << 21),
|
||||||
|
RxCRC_V4 = (1 << 20),
|
||||||
|
|
||||||
/* ChipCmdBits */
|
/* ChipCmdBits */
|
||||||
StopReq = 0x80,
|
StopReq = 0x80,
|
||||||
CmdReset = 0x10,
|
CmdReset = 0x10,
|
||||||
@ -1485,6 +1663,7 @@ enum RTL8126_register_content {
|
|||||||
Reserved2_shift = 13,
|
Reserved2_shift = 13,
|
||||||
RxCfgDMAShift = 8,
|
RxCfgDMAShift = 8,
|
||||||
EnableRxDescV3 = (1 << 24),
|
EnableRxDescV3 = (1 << 24),
|
||||||
|
EnableRxDescV4_1 = (1 << 24),
|
||||||
EnableOuterVlan = (1 << 23),
|
EnableOuterVlan = (1 << 23),
|
||||||
EnableInnerVlan = (1 << 22),
|
EnableInnerVlan = (1 << 22),
|
||||||
RxCfg_128_int_en = (1 << 15),
|
RxCfg_128_int_en = (1 << 15),
|
||||||
@ -1690,6 +1869,11 @@ enum _DescStatusBit {
|
|||||||
FirstFrag_V3 = (1 << 25), /* First segment of a packet */
|
FirstFrag_V3 = (1 << 25), /* First segment of a packet */
|
||||||
LastFrag_V3 = (1 << 24), /* Final segment of a packet */
|
LastFrag_V3 = (1 << 24), /* Final segment of a packet */
|
||||||
|
|
||||||
|
DescOwn_V4 = (DescOwn), /* Descriptor is owned by NIC */
|
||||||
|
RingEnd_V4 = (RingEnd), /* End of descriptor ring */
|
||||||
|
FirstFrag_V4 = (FirstFrag), /* First segment of a packet */
|
||||||
|
LastFrag_V4 = (LastFrag), /* Final segment of a packet */
|
||||||
|
|
||||||
/* Tx private */
|
/* Tx private */
|
||||||
/*------ offset 0 of tx descriptor ------*/
|
/*------ offset 0 of tx descriptor ------*/
|
||||||
LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
|
LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
|
||||||
@ -1748,7 +1932,7 @@ enum _DescStatusBit {
|
|||||||
RxIPF_v3 = (1 << 26), /* IP checksum failed */
|
RxIPF_v3 = (1 << 26), /* IP checksum failed */
|
||||||
RxUDPF_v3 = (1 << 25), /* UDP/IP checksum failed */
|
RxUDPF_v3 = (1 << 25), /* UDP/IP checksum failed */
|
||||||
RxTCPF_v3 = (1 << 24), /* TCP/IP checksum failed */
|
RxTCPF_v3 = (1 << 24), /* TCP/IP checksum failed */
|
||||||
RxSCTPF_v3 = (1 << 23), /* TCP/IP checksum failed */
|
RxSCTPF_v3 = (1 << 23), /* SCTP checksum failed */
|
||||||
RxVlanTag_v3 = (RxVlanTag), /* VLAN tag available */
|
RxVlanTag_v3 = (RxVlanTag), /* VLAN tag available */
|
||||||
|
|
||||||
/*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/
|
/*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/
|
||||||
@ -1761,6 +1945,23 @@ enum _DescStatusBit {
|
|||||||
RxV6F_v3 = (RxV6F),
|
RxV6F_v3 = (RxV6F),
|
||||||
RxV4F_v3 = (RxV4F),
|
RxV4F_v3 = (RxV4F),
|
||||||
/*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/
|
/*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/
|
||||||
|
|
||||||
|
RxIPF_v4 = (1 << 17), /* IP checksum failed */
|
||||||
|
RxUDPF_v4 = (1 << 16), /* UDP/IP checksum failed */
|
||||||
|
RxTCPF_v4 = (1 << 15), /* TCP/IP checksum failed */
|
||||||
|
RxSCTPF_v4 = (1 << 19), /* SCTP checksum failed */
|
||||||
|
RxVlanTag_v4 = (RxVlanTag), /* VLAN tag available */
|
||||||
|
|
||||||
|
/*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/
|
||||||
|
RxUDPT_v4 = (1 << 19),
|
||||||
|
RxTCPT_v4 = (1 << 18),
|
||||||
|
RxSCTP_v4 = (1 << 19),
|
||||||
|
/*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only end @@@@@@*/
|
||||||
|
|
||||||
|
/*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only begin @@@@@@*/
|
||||||
|
RxV6F_v4 = (RxV6F),
|
||||||
|
RxV4F_v4 = (RxV4F),
|
||||||
|
/*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum features {
|
enum features {
|
||||||
@ -1829,6 +2030,7 @@ enum efuse {
|
|||||||
};
|
};
|
||||||
#define RsvdMask 0x3fffc000
|
#define RsvdMask 0x3fffc000
|
||||||
#define RsvdMaskV3 0x3fff8000
|
#define RsvdMaskV3 0x3fff8000
|
||||||
|
#define RsvdMaskV4 RsvdMaskV3
|
||||||
|
|
||||||
struct TxDesc {
|
struct TxDesc {
|
||||||
u32 opts1;
|
u32 opts1;
|
||||||
@ -1895,6 +2097,22 @@ struct RxDescV3 {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RxDescV4 {
|
||||||
|
union {
|
||||||
|
u64 addr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 RSSInfo;
|
||||||
|
u32 RSSResult;
|
||||||
|
} RxDescNormalDDWord1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 opts2;
|
||||||
|
u32 opts1;
|
||||||
|
} RxDescNormalDDWord2;
|
||||||
|
};
|
||||||
|
|
||||||
enum rxdesc_type {
|
enum rxdesc_type {
|
||||||
RXDESC_TYPE_NORMAL=0,
|
RXDESC_TYPE_NORMAL=0,
|
||||||
RXDESC_TYPE_NEXT,
|
RXDESC_TYPE_NEXT,
|
||||||
@ -1914,7 +2132,8 @@ enum rx_desc_ring_type {
|
|||||||
|
|
||||||
enum rx_desc_len {
|
enum rx_desc_len {
|
||||||
RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)),
|
RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)),
|
||||||
RX_DESC_LEN_TYPE_3 = (sizeof(struct RxDescV3))
|
RX_DESC_LEN_TYPE_3 = (sizeof(struct RxDescV3)),
|
||||||
|
RX_DESC_LEN_TYPE_4 = (sizeof(struct RxDescV4))
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ring_info {
|
struct ring_info {
|
||||||
@ -2245,6 +2464,22 @@ enum rtl8126_state_t {
|
|||||||
__RTL8126_PTP_TX_IN_PROGRESS,
|
__RTL8126_PTP_TX_IN_PROGRESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RTL_FLAG_RX_HWTSTAMP_ENABLED BIT_0
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
|
||||||
|
struct ethtool_eee {
|
||||||
|
__u32 cmd;
|
||||||
|
__u32 supported;
|
||||||
|
__u32 advertised;
|
||||||
|
__u32 lp_advertised;
|
||||||
|
__u32 eee_active;
|
||||||
|
__u32 eee_enabled;
|
||||||
|
__u32 tx_lpi_enabled;
|
||||||
|
__u32 tx_lpi_timer;
|
||||||
|
__u32 reserved[2];
|
||||||
|
};
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */
|
||||||
|
|
||||||
struct rtl8126_private {
|
struct rtl8126_private {
|
||||||
void __iomem *mmio_addr; /* memory map physical address */
|
void __iomem *mmio_addr; /* memory map physical address */
|
||||||
struct pci_dev *pci_dev; /* Index of PCI device */
|
struct pci_dev *pci_dev; /* Index of PCI device */
|
||||||
@ -2258,6 +2493,7 @@ struct rtl8126_private {
|
|||||||
//struct msix_entry msix_entries[R8126_MAX_MSIX_VEC];
|
//struct msix_entry msix_entries[R8126_MAX_MSIX_VEC];
|
||||||
struct net_device_stats stats; /* statistics of net device */
|
struct net_device_stats stats; /* statistics of net device */
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
u32 tx_tcp_csum_cmd;
|
u32 tx_tcp_csum_cmd;
|
||||||
@ -2304,8 +2540,8 @@ struct rtl8126_private {
|
|||||||
u16 cp_cmd;
|
u16 cp_cmd;
|
||||||
u32 intr_mask;
|
u32 intr_mask;
|
||||||
u32 timer_intr_mask;
|
u32 timer_intr_mask;
|
||||||
u16 isr_reg[R8126_MAX_QUEUES];
|
u16 isr_reg[R8126_MAX_MSIX_VEC];
|
||||||
u16 imr_reg[R8126_MAX_QUEUES];
|
u16 imr_reg[R8126_MAX_MSIX_VEC];
|
||||||
int phy_auto_nego_reg;
|
int phy_auto_nego_reg;
|
||||||
int phy_1000_ctrl_reg;
|
int phy_1000_ctrl_reg;
|
||||||
int phy_2500_ctrl_reg;
|
int phy_2500_ctrl_reg;
|
||||||
@ -2389,7 +2625,6 @@ struct rtl8126_private {
|
|||||||
|
|
||||||
u32 HwFiberModeVer;
|
u32 HwFiberModeVer;
|
||||||
u32 HwFiberStat;
|
u32 HwFiberStat;
|
||||||
u8 HwSwitchMdiToFiber;
|
|
||||||
|
|
||||||
u16 NicCustLedValue;
|
u16 NicCustLedValue;
|
||||||
|
|
||||||
@ -2521,7 +2756,7 @@ struct rtl8126_private {
|
|||||||
//Realwow--------------
|
//Realwow--------------
|
||||||
#endif //ENABLE_REALWOW_SUPPORT
|
#endif //ENABLE_REALWOW_SUPPORT
|
||||||
|
|
||||||
struct ethtool_eee eee;
|
struct ethtool_keee eee;
|
||||||
|
|
||||||
#ifdef ENABLE_R8126_PROCFS
|
#ifdef ENABLE_R8126_PROCFS
|
||||||
//Procfs support
|
//Procfs support
|
||||||
@ -2534,9 +2769,12 @@ struct rtl8126_private {
|
|||||||
DECLARE_BITMAP(sysfs_flag, R8126_SYSFS_FLAG_MAX);
|
DECLARE_BITMAP(sysfs_flag, R8126_SYSFS_FLAG_MAX);
|
||||||
u32 testmode;
|
u32 testmode;
|
||||||
#endif
|
#endif
|
||||||
|
u8 HwSuppRxDescType;
|
||||||
u8 InitRxDescType;
|
u8 InitRxDescType;
|
||||||
u16 RxDescLength; //V1 16 Byte V2 32 Bytes
|
u16 RxDescLength; //V1 16 Byte V2 32 Bytes
|
||||||
|
|
||||||
|
spinlock_t phy_lock;
|
||||||
|
|
||||||
u8 HwSuppPtpVer;
|
u8 HwSuppPtpVer;
|
||||||
u8 EnablePtp;
|
u8 EnablePtp;
|
||||||
u8 ptp_master_mode;
|
u8 ptp_master_mode;
|
||||||
@ -2549,6 +2787,9 @@ struct rtl8126_private {
|
|||||||
unsigned long ptp_tx_start;
|
unsigned long ptp_tx_start;
|
||||||
struct ptp_clock_info ptp_clock_info;
|
struct ptp_clock_info ptp_clock_info;
|
||||||
struct ptp_clock *ptp_clock;
|
struct ptp_clock *ptp_clock;
|
||||||
|
u8 syncE_en;
|
||||||
|
u8 pps_enable;
|
||||||
|
struct hrtimer pps_timer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 HwSuppRssVer;
|
u8 HwSuppRssVer;
|
||||||
@ -2672,7 +2913,7 @@ enum mcfg {
|
|||||||
//Ram Code Version
|
//Ram Code Version
|
||||||
#define NIC_RAMCODE_VERSION_CFG_METHOD_1 (0x0023)
|
#define NIC_RAMCODE_VERSION_CFG_METHOD_1 (0x0023)
|
||||||
#define NIC_RAMCODE_VERSION_CFG_METHOD_2 (0x0033)
|
#define NIC_RAMCODE_VERSION_CFG_METHOD_2 (0x0033)
|
||||||
#define NIC_RAMCODE_VERSION_CFG_METHOD_3 (0x0048)
|
#define NIC_RAMCODE_VERSION_CFG_METHOD_3 (0x0060)
|
||||||
|
|
||||||
//hwoptimize
|
//hwoptimize
|
||||||
#define HW_PATCH_SOC_LAN (BIT_0)
|
#define HW_PATCH_SOC_LAN (BIT_0)
|
||||||
@ -2713,17 +2954,25 @@ void rtl8126_dash2_disable_rx(struct rtl8126_private *tp);
|
|||||||
void rtl8126_dash2_enable_rx(struct rtl8126_private *tp);
|
void rtl8126_dash2_enable_rx(struct rtl8126_private *tp);
|
||||||
void rtl8126_hw_disable_mac_mcu_bps(struct net_device *dev);
|
void rtl8126_hw_disable_mac_mcu_bps(struct net_device *dev);
|
||||||
void rtl8126_mark_to_asic(struct rtl8126_private *tp, struct RxDesc *desc, u32 rx_buf_sz);
|
void rtl8126_mark_to_asic(struct rtl8126_private *tp, struct RxDesc *desc, u32 rx_buf_sz);
|
||||||
|
void rtl8126_mark_as_last_descriptor(struct rtl8126_private *tp, struct RxDesc *desc);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rtl8126_make_unusable_by_asic(struct rtl8126_private *tp,
|
rtl8126_make_unusable_by_asic(struct rtl8126_private *tp,
|
||||||
struct RxDesc *desc)
|
struct RxDesc *desc)
|
||||||
{
|
{
|
||||||
if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) {
|
switch (tp->InitRxDescType) {
|
||||||
|
case RX_DESC_RING_TYPE_3:
|
||||||
((struct RxDescV3 *)desc)->addr = RTL8126_MAGIC_NUMBER;
|
((struct RxDescV3 *)desc)->addr = RTL8126_MAGIC_NUMBER;
|
||||||
((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1 &= ~cpu_to_le32(DescOwn | RsvdMaskV3);
|
((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1 &= ~cpu_to_le32(DescOwn | RsvdMaskV3);
|
||||||
} else {
|
break;
|
||||||
|
case RX_DESC_RING_TYPE_4:
|
||||||
|
((struct RxDescV4 *)desc)->addr = RTL8126_MAGIC_NUMBER;
|
||||||
|
((struct RxDescV4 *)desc)->RxDescNormalDDWord2.opts1 &= ~cpu_to_le32(DescOwn | RsvdMaskV4);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
desc->addr = RTL8126_MAGIC_NUMBER;
|
desc->addr = RTL8126_MAGIC_NUMBER;
|
||||||
desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
|
desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2764,12 +3013,21 @@ int rtl8126_dump_tally_counter(struct rtl8126_private *tp, dma_addr_t paddr);
|
|||||||
void rtl8126_enable_napi(struct rtl8126_private *tp);
|
void rtl8126_enable_napi(struct rtl8126_private *tp);
|
||||||
void _rtl8126_wait_for_quiescence(struct net_device *dev);
|
void _rtl8126_wait_for_quiescence(struct net_device *dev);
|
||||||
|
|
||||||
|
void rtl8126_mdio_direct_write_phy_ocp(struct rtl8126_private *tp, u16 RegAddr,u16 value);
|
||||||
|
u32 rtl8126_mdio_direct_read_phy_ocp(struct rtl8126_private *tp, u16 RegAddr);
|
||||||
|
void rtl8126_clear_and_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 clearmask, u16 setmask);
|
||||||
|
void rtl8126_clear_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask);
|
||||||
|
void rtl8126_set_eth_phy_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask);
|
||||||
|
|
||||||
|
void rtl8126_clear_mac_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask);
|
||||||
|
void rtl8126_set_mac_ocp_bit(struct rtl8126_private *tp, u16 addr, u16 mask);
|
||||||
|
|
||||||
#ifndef ENABLE_LIB_SUPPORT
|
#ifndef ENABLE_LIB_SUPPORT
|
||||||
static inline void rtl8126_lib_reset_prepare(struct rtl8126_private *tp) { }
|
static inline void rtl8126_lib_reset_prepare(struct rtl8126_private *tp) { }
|
||||||
static inline void rtl8126_lib_reset_complete(struct rtl8126_private *tp) { }
|
static inline void rtl8126_lib_reset_complete(struct rtl8126_private *tp) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0 )
|
#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0)
|
||||||
#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0)
|
#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0)
|
||||||
#define HW_SUPPORT_D0_SPEED_UP(_M) ((_M)->HwSuppD0SpeedUpVer > 0)
|
#define HW_SUPPORT_D0_SPEED_UP(_M) ((_M)->HwSuppD0SpeedUpVer > 0)
|
||||||
#define HW_SUPPORT_MAC_MCU(_M) ((_M)->HwSuppMacMcuVer > 0)
|
#define HW_SUPPORT_MAC_MCU(_M) ((_M)->HwSuppMacMcuVer > 0)
|
||||||
|
@ -175,10 +175,10 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2;
|
|||||||
#define OCP_REG_CONFIG0_DRV_WAIT_OOB BIT_8
|
#define OCP_REG_CONFIG0_DRV_WAIT_OOB BIT_8
|
||||||
#define OCP_REG_CONFIG0_TLSEN BIT_7
|
#define OCP_REG_CONFIG0_TLSEN BIT_7
|
||||||
|
|
||||||
#define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0 )
|
#define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0)
|
||||||
#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1 )
|
#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1)
|
||||||
#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2 )
|
#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2)
|
||||||
#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3 )
|
#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3)
|
||||||
|
|
||||||
#define RECV_FROM_FW_BUF_SIZE (1520)
|
#define RECV_FROM_FW_BUF_SIZE (1520)
|
||||||
#define SEND_TO_FW_BUF_SIZE (1520)
|
#define SEND_TO_FW_BUF_SIZE (1520)
|
||||||
|
1907
src/r8126_n.c
1907
src/r8126_n.c
File diff suppressed because it is too large
Load Diff
615
src/r8126_ptp.c
615
src/r8126_ptp.c
@ -45,57 +45,90 @@
|
|||||||
#include "r8126.h"
|
#include "r8126.h"
|
||||||
#include "r8126_ptp.h"
|
#include "r8126_ptp.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
|
static void rtl8126_wait_clkadj_ready(struct rtl8126_private *tp)
|
||||||
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
|
|
||||||
{
|
{
|
||||||
return *(const struct timespec *)&ts64;
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++)
|
||||||
|
if (!(rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CLK_CFG_8126) & CLKADJ_MODE_SET))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
|
static void rtl8126_set_clkadj_mode(struct rtl8126_private *tp, u16 cmd)
|
||||||
{
|
{
|
||||||
return *(const struct timespec64 *)&ts;
|
rtl8126_clear_and_set_eth_phy_ocp_bit(tp,
|
||||||
|
PTP_CLK_CFG_8126,
|
||||||
|
BIT_3 | BIT_2 | BIT_1,
|
||||||
|
CLKADJ_MODE_SET | cmd);
|
||||||
|
|
||||||
|
rtl8126_wait_clkadj_ready(tp);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int _rtl8126_phc_gettime(struct rtl8126_private *tp, struct timespec64 *ts64)
|
static int _rtl8126_phc_gettime(struct rtl8126_private *tp, struct timespec64 *ts64)
|
||||||
{
|
{
|
||||||
//get local time
|
unsigned long flags;
|
||||||
RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_LATCHED_LOCAL_TIME | PTP_EXEC_CMD));
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
//Direct Read
|
||||||
|
rtl8126_set_clkadj_mode(tp, DIRECT_READ);
|
||||||
|
|
||||||
/* nanoseconds */
|
/* nanoseconds */
|
||||||
//0x6808[29:0]
|
//Ns[29:16] E414[13:0]
|
||||||
ts64->tv_nsec = (RTL_R32(tp, PTP_SOFT_CONFIG_Time_NS_8125) & 0x3fffffff);
|
ts64->tv_nsec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_NS_HI_8126) & 0x3fff;
|
||||||
|
ts64->tv_nsec <<= 16;
|
||||||
|
//Ns[15:0] E412[15:0]
|
||||||
|
ts64->tv_nsec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_NS_LO_8126);
|
||||||
|
|
||||||
|
|
||||||
/* seconds */
|
/* seconds */
|
||||||
//0x680C[47:0]
|
//S[47:32] E41A[15:0]
|
||||||
ts64->tv_sec = RTL_R16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4);
|
ts64->tv_sec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_HI_8126);
|
||||||
ts64->tv_sec <<= 32;
|
ts64->tv_sec <<= 16;
|
||||||
ts64->tv_sec |= RTL_R32(tp, PTP_SOFT_CONFIG_Time_S_8125);
|
//S[31:16] E418[15:0]
|
||||||
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_MI_8126);
|
||||||
|
ts64->tv_sec <<= 16;
|
||||||
|
//S[15:0] E416[15:0]
|
||||||
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_LO_8126);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl8126_phc_settime(struct rtl8126_private *tp, const struct timespec64 *ts64)
|
static int _rtl8126_phc_settime(struct rtl8126_private *tp, const struct timespec64 *ts64)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
/* nanoseconds */
|
/* nanoseconds */
|
||||||
//0x6808[29:0]
|
//Ns[15:0] E412[15:0]
|
||||||
RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, (ts64->tv_nsec & 0x3fffffff));
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_LO_8126, ts64->tv_nsec);
|
||||||
|
//Ns[29:16] E414[13:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_HI_8126, (ts64->tv_nsec & 0x3fff0000) >> 16);
|
||||||
|
|
||||||
/* seconds */
|
/* seconds */
|
||||||
//0x680C[47:0]
|
//S[15:0] E416[15:0]
|
||||||
RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, ts64->tv_sec);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_LO_8126, ts64->tv_sec);
|
||||||
RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (ts64->tv_sec >> 32));
|
//S[31:16] E418[15:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_MI_8126, (ts64->tv_sec >> 16));
|
||||||
|
//S[47:32] E41A[15:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_HI_8126, (ts64->tv_sec >> 32));
|
||||||
|
|
||||||
//set local time
|
//Direct Write
|
||||||
RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD));
|
rtl8126_set_clkadj_mode(tp, DIRECT_WRITE);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _rtl8126_phc_adjtime(struct rtl8126_private *tp, s64 delta)
|
static int _rtl8126_phc_adjtime(struct rtl8126_private *tp, s64 delta)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
struct timespec64 d;
|
struct timespec64 d;
|
||||||
bool negative = false;
|
bool negative;
|
||||||
u64 tohw;
|
u64 tohw;
|
||||||
u32 nsec;
|
u32 nsec;
|
||||||
u64 sec;
|
u64 sec;
|
||||||
@ -104,6 +137,7 @@ static int _rtl8126_phc_adjtime(struct rtl8126_private *tp, s64 delta)
|
|||||||
negative = true;
|
negative = true;
|
||||||
tohw = -delta;
|
tohw = -delta;
|
||||||
} else {
|
} else {
|
||||||
|
negative = false;
|
||||||
tohw = delta;
|
tohw = delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,31 +146,31 @@ static int _rtl8126_phc_adjtime(struct rtl8126_private *tp, s64 delta)
|
|||||||
nsec = d.tv_nsec;
|
nsec = d.tv_nsec;
|
||||||
sec = d.tv_sec;
|
sec = d.tv_sec;
|
||||||
|
|
||||||
if (negative) {
|
|
||||||
nsec = -nsec;
|
|
||||||
sec = -sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsec &= 0x3fffffff;
|
nsec &= 0x3fffffff;
|
||||||
sec &= 0x0000ffffffffffff;
|
sec &= 0x0000ffffffffffff;
|
||||||
|
|
||||||
if (negative) {
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
nsec |= PTP_SOFT_CONFIG_TIME_NS_NEGATIVE;
|
|
||||||
sec |= PTP_SOFT_CONFIG_TIME_S_NEGATIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nanoseconds */
|
/* nanoseconds */
|
||||||
//0x6808[29:0]
|
//Ns[15:0] E412[15:0]
|
||||||
RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, nsec);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_LO_8126, nsec);
|
||||||
|
//Ns[29:16] E414[13:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_HI_8126, (nsec >> 16));
|
||||||
|
|
||||||
/* seconds */
|
/* seconds */
|
||||||
//0x680C[47:0]
|
//S[15:0] E416[15:0]
|
||||||
RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, sec);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_LO_8126, sec);
|
||||||
RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (sec >> 32));
|
//S[31:16] E418[15:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_MI_8126, (sec >> 16));
|
||||||
|
//S[47:32] E41A[15:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_S_HI_8126, (sec >> 32));
|
||||||
|
|
||||||
//adjust local time
|
if (negative)
|
||||||
//RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD));
|
rtl8126_set_clkadj_mode(tp, DECREMENT_STEP);
|
||||||
RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD));
|
else
|
||||||
|
rtl8126_set_clkadj_mode(tp, INCREMENT_STEP);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -148,57 +182,60 @@ static int rtl8126_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
|||||||
|
|
||||||
//netif_info(tp, drv, tp->dev, "phc adjust time\n");
|
//netif_info(tp, drv, tp->dev, "phc adjust time\n");
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
ret = _rtl8126_phc_adjtime(tp, delta);
|
ret = _rtl8126_phc_adjtime(tp, delta);
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0)
|
|
||||||
/*
|
/*
|
||||||
1ppm means every 125MHz plus 125Hz. It also means every 8ns minus 8ns*10^(-6)
|
* delta = delta * 10^6 ppm = delta * 10^9 ppb (in this equation ppm and ppb are not variable)
|
||||||
|
*
|
||||||
1ns=2^30 sub_ns
|
* in adjfreq ppb is a variable
|
||||||
|
* ppb = delta * 10^9
|
||||||
8ns*10^(-6) = 8 * 2^30 sub_ns * 10^(-6) = 2^33 sub_ns * 10^(-6) = 8590 = 0x218E sub_ns
|
* delta = ppb / 10^9
|
||||||
|
* rate_value = |delta| * 2^32 = |ppb| / 10^9 * 2^32 = (|ppb| << 32) / 10^9
|
||||||
1ppb means every 125MHz plus 0.125Hz. It also means every 8ns minus 8ns*10^(-9)
|
*/
|
||||||
|
|
||||||
1ns=2^30 sub_ns
|
|
||||||
|
|
||||||
8ns*10^(-9) = 8 * 2^30 sub_ns * 10^(-9) = 2^33 sub_ns * 10^(-9) = 8.59 sub_ns = 9 sub_ns
|
|
||||||
*/
|
|
||||||
static int _rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
static int _rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||||
{
|
{
|
||||||
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
||||||
bool negative = false;
|
unsigned long flags;
|
||||||
u32 sub_ns;
|
u32 rate_value;
|
||||||
|
|
||||||
if (ppb < 0) {
|
if (ppb < 0) {
|
||||||
negative = true;
|
rate_value = ((u64)-ppb << 32) / 1000000000;
|
||||||
ppb = -ppb;
|
rate_value = ~rate_value + 1;
|
||||||
}
|
|
||||||
|
|
||||||
sub_ns = ppb * 9;
|
|
||||||
if (negative) {
|
|
||||||
sub_ns = -sub_ns;
|
|
||||||
sub_ns &= 0x3fffffff;
|
|
||||||
sub_ns |= PTP_ADJUST_TIME_NS_NEGATIVE;
|
|
||||||
} else
|
} else
|
||||||
sub_ns &= 0x3fffffff;
|
rate_value = ((u64)ppb << 32) / 1000000000;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
/* nanoseconds */
|
/* nanoseconds */
|
||||||
//0x6808[29:0]
|
//Ns[15:0] E412[15:0]
|
||||||
RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, sub_ns);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_LO_8126, rate_value);
|
||||||
|
//Ns[22:16] E414[13:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CFG_NS_HI_8126, (rate_value & 0x003f0000) >> 16);
|
||||||
|
|
||||||
//adjust local time
|
rtl8126_set_clkadj_mode(tp, RATE_WRITE);
|
||||||
RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD));
|
|
||||||
//RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD));
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
|
||||||
|
static int rtl8126_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||||
|
{
|
||||||
|
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||||
|
|
||||||
|
if (ppb > ptp->max_adj || ppb < -ptp->max_adj)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
_rtl8126_phc_adjfreq(ptp, ppb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
static int rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
|
static int rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
|
||||||
{
|
{
|
||||||
//struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
//struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
||||||
@ -212,8 +249,24 @@ static int rtl8126_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0)
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||||
|
static int rtl8126_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts64,
|
||||||
|
struct ptp_system_timestamp *sts)
|
||||||
|
{
|
||||||
|
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
//netif_info(tp, drv, tp->dev, "phc get ts\n");
|
||||||
|
|
||||||
|
ptp_read_system_prets(sts);
|
||||||
|
ret = _rtl8126_phc_gettime(tp, ts64);
|
||||||
|
ptp_read_system_postts(sts);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static int rtl8126_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts64)
|
static int rtl8126_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts64)
|
||||||
{
|
{
|
||||||
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
||||||
@ -221,12 +274,11 @@ static int rtl8126_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts
|
|||||||
|
|
||||||
//netif_info(tp, drv, tp->dev, "phc get ts\n");
|
//netif_info(tp, drv, tp->dev, "phc get ts\n");
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
ret = _rtl8126_phc_gettime(tp, ts64);
|
ret = _rtl8126_phc_gettime(tp, ts64);
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) */
|
||||||
|
|
||||||
static int rtl8126_phc_settime(struct ptp_clock_info *ptp,
|
static int rtl8126_phc_settime(struct ptp_clock_info *ptp,
|
||||||
const struct timespec64 *ts64)
|
const struct timespec64 *ts64)
|
||||||
@ -236,38 +288,74 @@ static int rtl8126_phc_settime(struct ptp_clock_info *ptp,
|
|||||||
|
|
||||||
//netif_info(tp, drv, tp->dev, "phc set ts\n");
|
//netif_info(tp, drv, tp->dev, "phc set ts\n");
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
ret = _rtl8126_phc_settime(tp, ts64);
|
ret = _rtl8126_phc_settime(tp, ts64);
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _rtl8126_phc_enable(struct ptp_clock_info *ptp,
|
||||||
|
struct ptp_clock_request *rq, int on)
|
||||||
|
{
|
||||||
|
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
||||||
|
unsigned long flags;
|
||||||
|
u16 phy_ocp_data;
|
||||||
|
|
||||||
|
if (on) {
|
||||||
|
tp->pps_enable = 1;
|
||||||
|
rtl8126_clear_mac_ocp_bit(tp, 0xDC00, BIT_6);
|
||||||
|
rtl8126_clear_mac_ocp_bit(tp, 0xDC20, BIT_1);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
/* Set periodic pulse 1pps */
|
||||||
|
/* E432[8:0] = 0x017d */
|
||||||
|
phy_ocp_data = rtl8126_mdio_direct_read_phy_ocp(tp, 0xE432);
|
||||||
|
phy_ocp_data &= 0xFE00;
|
||||||
|
phy_ocp_data |= 0x017d;
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, 0xE432, phy_ocp_data);
|
||||||
|
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, 0xE434, 0x7840);
|
||||||
|
|
||||||
|
/* E436[8:0] = 0xbe */
|
||||||
|
phy_ocp_data = rtl8126_mdio_direct_read_phy_ocp(tp, 0xE436);
|
||||||
|
phy_ocp_data &= 0xFE00;
|
||||||
|
phy_ocp_data |= 0xbe;
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, 0xE436, phy_ocp_data);
|
||||||
|
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, 0xE438, 0xbc20);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
/* start hrtimer */
|
||||||
|
hrtimer_start(&tp->pps_timer, 1000000000, HRTIMER_MODE_REL);
|
||||||
|
} else
|
||||||
|
tp->pps_enable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rtl8126_phc_enable(struct ptp_clock_info *ptp,
|
static int rtl8126_phc_enable(struct ptp_clock_info *ptp,
|
||||||
struct ptp_clock_request *rq, int on)
|
struct ptp_clock_request *rq, int on)
|
||||||
{
|
{
|
||||||
struct rtl8126_private *tp = container_of(ptp, struct rtl8126_private, ptp_clock_info);
|
|
||||||
u16 ptp_ctrl;
|
|
||||||
|
|
||||||
//netif_info(tp, drv, tp->dev, "phc enable type %x on %d\n", rq->type, on);
|
|
||||||
|
|
||||||
switch (rq->type) {
|
switch (rq->type) {
|
||||||
case PTP_CLK_REQ_PPS:
|
case PTP_CLK_REQ_PPS:
|
||||||
rtnl_lock();
|
_rtl8126_phc_enable(ptp, rq, on);
|
||||||
ptp_ctrl = RTL_R16(tp, PTP_CTRL_8125);
|
|
||||||
ptp_ctrl &= ~BIT_15;
|
|
||||||
if (on)
|
|
||||||
ptp_ctrl |= BIT_14;
|
|
||||||
else
|
|
||||||
ptp_ctrl &= ~BIT_14;
|
|
||||||
RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl);
|
|
||||||
rtnl_unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8126_ptp_enable_config(struct rtl8126_private *tp)
|
||||||
|
{
|
||||||
|
if (tp->syncE_en)
|
||||||
|
rtl8126_set_eth_phy_ocp_bit(tp, PTP_SYNCE_CTL, BIT_0);
|
||||||
|
else
|
||||||
|
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_SYNCE_CTL, BIT_0);
|
||||||
|
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_CTL, PTP_CTL_TYPE_3 | BIT_12);
|
||||||
|
|
||||||
|
rtl8126_set_eth_phy_ocp_bit(tp, 0xA640, BIT_15);
|
||||||
|
}
|
||||||
|
|
||||||
int rtl8126_get_ts_info(struct net_device *netdev,
|
int rtl8126_get_ts_info(struct net_device *netdev,
|
||||||
struct ethtool_ts_info *info)
|
struct ethtool_ts_info *info)
|
||||||
{
|
{
|
||||||
@ -311,53 +399,163 @@ static const struct ptp_clock_info rtl_ptp_clock_info = {
|
|||||||
.n_per_out = 0,
|
.n_per_out = 0,
|
||||||
.n_pins = 0,
|
.n_pins = 0,
|
||||||
.pps = 1,
|
.pps = 1,
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
|
||||||
|
.adjfine = rtl8126_ptp_adjfine,
|
||||||
|
#else
|
||||||
.adjfreq = rtl8126_phc_adjfreq,
|
.adjfreq = rtl8126_phc_adjfreq,
|
||||||
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(6,2,0)
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0) */
|
||||||
.adjtime = rtl8126_phc_adjtime,
|
.adjtime = rtl8126_phc_adjtime,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||||
|
.gettimex64 = rtl8126_phc_gettime,
|
||||||
|
#else
|
||||||
.gettime64 = rtl8126_phc_gettime,
|
.gettime64 = rtl8126_phc_gettime,
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) */
|
||||||
|
|
||||||
.settime64 = rtl8126_phc_settime,
|
.settime64 = rtl8126_phc_settime,
|
||||||
.enable = rtl8126_phc_enable,
|
.enable = rtl8126_phc_enable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rtl8126_ptp_egresstime(struct rtl8126_private *tp, struct timespec64 *ts64, u32 regnum)
|
static u16 rtl8126_ptp_get_tx_msgtype(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
|
u16 tx_ts_ready = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) {
|
||||||
|
tx_ts_ready = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_STA) & 0xF000;
|
||||||
|
if (tx_ts_ready)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tx_ts_ready) {
|
||||||
|
case TX_TS_PDLYRSP_RDY:
|
||||||
|
return PTP_MSGTYPE_PDELAY_RESP;
|
||||||
|
case TX_TS_PDLYREQ_RDY:
|
||||||
|
return PTP_MSGTYPE_PDELAY_REQ;
|
||||||
|
case TX_TS_DLYREQ_RDY:
|
||||||
|
return PTP_MSGTYPE_DELAY_REQ;
|
||||||
|
case TX_TS_SYNC_RDY:
|
||||||
|
default:
|
||||||
|
return PTP_MSGTYPE_SYNC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static u16 rtl8126_ptp_get_rx_msgtype(struct rtl8126_private *tp)
|
||||||
|
{
|
||||||
|
u16 rx_ts_ready = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++) {
|
||||||
|
rx_ts_ready = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_STA) & 0x0F00;
|
||||||
|
if (rx_ts_ready)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rx_ts_ready) {
|
||||||
|
case RX_TS_PDLYRSP_RDY:
|
||||||
|
return PTP_MSGTYPE_PDELAY_RESP;
|
||||||
|
case RX_TS_PDLYREQ_RDY:
|
||||||
|
return PTP_MSGTYPE_PDELAY_REQ;
|
||||||
|
case RX_TS_DLYREQ_RDY:
|
||||||
|
return PTP_MSGTYPE_DELAY_REQ;
|
||||||
|
case RX_TS_SYNC_RDY:
|
||||||
|
default:
|
||||||
|
return PTP_MSGTYPE_SYNC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void rtl8126_wait_trx_ts_ready(struct rtl8126_private *tp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < R8126_CHANNEL_WAIT_COUNT; i++)
|
||||||
|
if (!(rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_STA) & TRX_TS_RD))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8126_set_trx_ts_cmd(struct rtl8126_private *tp, u16 cmd)
|
||||||
|
{
|
||||||
|
rtl8126_clear_and_set_eth_phy_ocp_bit(tp,
|
||||||
|
PTP_TRX_TS_STA,
|
||||||
|
TRXTS_SEL | BIT_3 | BIT_2,
|
||||||
|
TRX_TS_RD | cmd);
|
||||||
|
|
||||||
|
rtl8126_wait_trx_ts_ready(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8126_ptp_egresstime(struct rtl8126_private *tp, struct timespec64 *ts64)
|
||||||
|
{
|
||||||
|
u16 msgtype;
|
||||||
|
|
||||||
|
msgtype = rtl8126_ptp_get_tx_msgtype(tp);
|
||||||
|
|
||||||
|
msgtype <<= 2;
|
||||||
|
|
||||||
|
rtl8126_set_trx_ts_cmd(tp, (msgtype | BIT_4));
|
||||||
|
|
||||||
/* nanoseconds */
|
/* nanoseconds */
|
||||||
//[29:0]
|
//Ns[29:16] E448[13:0]
|
||||||
ts64->tv_nsec = rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_NS_8125 + regnum * 16 + 2);
|
ts64->tv_nsec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_NS_HI) & 0x3fff;
|
||||||
ts64->tv_nsec <<= 16;
|
ts64->tv_nsec <<= 16;
|
||||||
ts64->tv_nsec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_NS_8125 + regnum * 16);
|
//Ns[15:0] E446[15:0]
|
||||||
ts64->tv_nsec &= 0x3fffffff;
|
ts64->tv_nsec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_NS_LO);
|
||||||
|
|
||||||
/* seconds */
|
/* seconds */
|
||||||
//[47:0]
|
//S[47:32] E44E[15:0]
|
||||||
ts64->tv_sec = rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16 + 4);
|
ts64->tv_sec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_HI);
|
||||||
ts64->tv_sec <<= 16;
|
ts64->tv_sec <<= 16;
|
||||||
ts64->tv_sec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16 + 2);
|
//S[31:16] E44C[15:0]
|
||||||
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_MI);
|
||||||
ts64->tv_sec <<= 16;
|
ts64->tv_sec <<= 16;
|
||||||
ts64->tv_sec |= rtl8126_mac_ocp_read(tp, PTP_EGRESS_TIME_BASE_S_8125 + regnum * 16);
|
//S[15:0] E44A[15:0]
|
||||||
ts64->tv_sec &= 0x0000ffffffffffff;
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_LO);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
static void rtl8126_ptp_ingresstime(struct rtl8126_private *tp, struct timespec64 *ts64, u8 type)
|
||||||
|
{
|
||||||
|
u16 msgtype;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PTP_MSGTYPE_PDELAY_RESP:
|
||||||
|
case PTP_MSGTYPE_PDELAY_REQ:
|
||||||
|
case PTP_MSGTYPE_DELAY_REQ:
|
||||||
|
case PTP_MSGTYPE_SYNC:
|
||||||
|
msgtype = type << 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtl8126_set_trx_ts_cmd(tp, (TRXTS_SEL | msgtype | BIT_4));
|
||||||
|
|
||||||
|
/* nanoseconds */
|
||||||
|
//Ns[29:16] E448[13:0]
|
||||||
|
ts64->tv_nsec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_NS_HI) & 0x3fff;
|
||||||
|
ts64->tv_nsec <<= 16;
|
||||||
|
//Ns[15:0] E446[15:0]
|
||||||
|
ts64->tv_nsec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_NS_LO);
|
||||||
|
|
||||||
|
/* seconds */
|
||||||
|
//S[47:32] E44E[15:0]
|
||||||
|
ts64->tv_sec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_HI);
|
||||||
|
ts64->tv_sec <<= 16;
|
||||||
|
//S[31:16] E44C[15:0]
|
||||||
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_MI);
|
||||||
|
ts64->tv_sec <<= 16;
|
||||||
|
//S[15:0] E44A[15:0]
|
||||||
|
ts64->tv_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_TRX_TS_S_LO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8126_ptp_tx_hwtstamp(struct rtl8126_private *tp)
|
static void rtl8126_ptp_tx_hwtstamp(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = tp->ptp_tx_skb;
|
struct sk_buff *skb = tp->ptp_tx_skb;
|
||||||
struct skb_shared_hwtstamps shhwtstamps = {0};
|
struct skb_shared_hwtstamps shhwtstamps = { 0 };
|
||||||
struct timespec64 ts64;
|
struct timespec64 ts64;
|
||||||
u32 regnum;
|
|
||||||
|
|
||||||
RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, TX_TX_INTR);
|
||||||
|
|
||||||
//IO 0x2302 bit 10~11 WR_PTR
|
rtl8126_ptp_egresstime(tp, &ts64);
|
||||||
regnum = RTL_R16(tp, 0x2032) & 0x0C00;
|
|
||||||
regnum >>= 10;
|
|
||||||
regnum = (regnum + 3) % 4;
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
rtl8126_ptp_egresstime(tp, &ts64, regnum);
|
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
/* Upper 32 bits contain s, lower 32 bits contain ns. */
|
/* Upper 32 bits contain s, lower 32 bits contain ns. */
|
||||||
shhwtstamps.hwtstamp = ktime_set(ts64.tv_sec,
|
shhwtstamps.hwtstamp = ktime_set(ts64.tv_sec,
|
||||||
@ -381,6 +579,7 @@ static void rtl8126_ptp_tx_work(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct rtl8126_private *tp = container_of(work, struct rtl8126_private,
|
struct rtl8126_private *tp = container_of(work, struct rtl8126_private,
|
||||||
ptp_tx_work);
|
ptp_tx_work);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!tp->ptp_tx_skb)
|
if (!tp->ptp_tx_skb)
|
||||||
return;
|
return;
|
||||||
@ -394,47 +593,66 @@ static void rtl8126_ptp_tx_work(struct work_struct *work)
|
|||||||
/* Clear the tx valid bit in TSYNCTXCTL register to enable
|
/* Clear the tx valid bit in TSYNCTXCTL register to enable
|
||||||
* interrupt
|
* interrupt
|
||||||
*/
|
*/
|
||||||
RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER);
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, TX_TX_INTR);
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RTL_R8(tp, PTP_ISR_8125) & (PTP_ISR_TOK))
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
if (rtl8126_mdio_direct_read_phy_ocp(tp, PTP_INSR) & TX_TX_INTR) {
|
||||||
rtl8126_ptp_tx_hwtstamp(tp);
|
rtl8126_ptp_tx_hwtstamp(tp);
|
||||||
else
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
} else {
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
/* reschedule to check later */
|
/* reschedule to check later */
|
||||||
schedule_work(&tp->ptp_tx_work);
|
schedule_work(&tp->ptp_tx_work);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8126_hwtstamp_enable(struct rtl8126_private *tp, bool enable)
|
static int rtl8126_hwtstamp_enable(struct rtl8126_private *tp, bool enable)
|
||||||
{
|
{
|
||||||
RTL_W16(tp, PTP_CTRL_8125, 0);
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
u16 ptp_ctrl;
|
//trx timestamp interrupt enable
|
||||||
struct timespec64 ts64;
|
rtl8126_set_eth_phy_ocp_bit(tp, PTP_INER, BIT_2 | BIT_3);
|
||||||
|
|
||||||
|
//set isr clear mode
|
||||||
|
rtl8126_set_eth_phy_ocp_bit(tp, PTP_GEN_CFG, BIT_0);
|
||||||
|
|
||||||
//clear ptp isr
|
//clear ptp isr
|
||||||
RTL_W8(tp, PTP_ISR_8125, 0xff);
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_INSR, 0xFFFF);
|
||||||
//ptp source 0:gphy 1:mac
|
|
||||||
rtl8126_mac_ocp_write(tp, 0xDC00, rtl8126_mac_ocp_read(tp, 0xDC00) | BIT_6);
|
|
||||||
//enable ptp
|
|
||||||
ptp_ctrl = (BIT_0 | BIT_3 | BIT_4 | BIT_6 | BIT_10 | BIT_12);
|
|
||||||
if (tp->ptp_master_mode)
|
|
||||||
ptp_ctrl |= BIT_1;
|
|
||||||
RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl);
|
|
||||||
|
|
||||||
//set system time
|
//enable ptp
|
||||||
/*
|
rtl8126_ptp_enable_config(tp);
|
||||||
if (ktime_to_timespec64_cond(ktime_get_real(), &ts64))
|
|
||||||
_rtl8126_phc_settime(tp, timespec64_to_timespec(ts64));
|
//rtl8126_set_local_time(tp);
|
||||||
*/
|
} else {
|
||||||
ktime_get_real_ts64(&ts64);
|
/* trx timestamp interrupt disable */
|
||||||
_rtl8126_phc_settime(tp, &ts64);
|
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_INER, BIT_2 | BIT_3);
|
||||||
|
|
||||||
|
/* disable ptp */
|
||||||
|
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_SYNCE_CTL, BIT_0);
|
||||||
|
rtl8126_clear_eth_phy_ocp_bit(tp, PTP_CTL, BIT_0);
|
||||||
|
rtl8126_set_eth_phy_ocp_bit(tp, 0xA640, BIT_15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtl8126_set_local_time(struct rtl8126_private *tp)
|
||||||
|
{
|
||||||
|
struct timespec64 ts64;
|
||||||
|
//set system time
|
||||||
|
ktime_get_real_ts64(&ts64);
|
||||||
|
_rtl8126_phc_settime(tp, &ts64);
|
||||||
|
}
|
||||||
|
|
||||||
static long rtl8126_ptp_create_clock(struct rtl8126_private *tp)
|
static long rtl8126_ptp_create_clock(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
struct net_device *netdev = tp->dev;
|
struct net_device *netdev = tp->dev;
|
||||||
@ -449,9 +667,10 @@ static long rtl8126_ptp_create_clock(struct rtl8126_private *tp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tp->ptp_clock_info = rtl_ptp_clock_info;
|
tp->ptp_clock_info = rtl_ptp_clock_info;
|
||||||
|
tp->ptp_clock_info.max_adj = 488281;//0x1FFFFF * 10^9 / 2^32
|
||||||
|
|
||||||
snprintf(tp->ptp_clock_info.name, sizeof(tp->ptp_clock_info.name),
|
snprintf(tp->ptp_clock_info.name, sizeof(tp->ptp_clock_info.name),
|
||||||
"%pm", tp->dev->dev_addr);
|
"%pm", tp->dev->dev_addr);
|
||||||
tp->ptp_clock_info.max_adj = 119304647;
|
|
||||||
tp->ptp_clock = ptp_clock_register(&tp->ptp_clock_info, &tp->pci_dev->dev);
|
tp->ptp_clock = ptp_clock_register(&tp->ptp_clock_info, &tp->pci_dev->dev);
|
||||||
if (IS_ERR(tp->ptp_clock)) {
|
if (IS_ERR(tp->ptp_clock)) {
|
||||||
err = PTR_ERR(tp->ptp_clock);
|
err = PTR_ERR(tp->ptp_clock);
|
||||||
@ -464,6 +683,43 @@ static long rtl8126_ptp_create_clock(struct rtl8126_private *tp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum hrtimer_restart
|
||||||
|
rtl8126_hrtimer_for_pps(struct hrtimer *timer) {
|
||||||
|
struct rtl8126_private *tp = container_of(timer, struct rtl8126_private, pps_timer);
|
||||||
|
u16 tai_cfg = BIT_8 | BIT_3 | BIT_1 | BIT_0;
|
||||||
|
s64 pps_sec;
|
||||||
|
|
||||||
|
if (tp->pps_enable)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
//Direct Read
|
||||||
|
rtl8126_set_clkadj_mode(tp, DIRECT_READ);
|
||||||
|
|
||||||
|
pps_sec = rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_HI_8126);
|
||||||
|
pps_sec <<= 16;
|
||||||
|
pps_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_MI_8126);
|
||||||
|
pps_sec <<= 16;
|
||||||
|
pps_sec |= rtl8126_mdio_direct_read_phy_ocp(tp, PTP_CFG_S_LO_8126);
|
||||||
|
pps_sec++;
|
||||||
|
|
||||||
|
//E42A[15:0]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_TAI_TS_S_LO, pps_sec & 0xffff);
|
||||||
|
//E42C[31:16]
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_TAI_TS_S_HI, (pps_sec & 0xffff0000) >> 16);
|
||||||
|
//Periodic Tai start
|
||||||
|
rtl8126_mdio_direct_write_phy_ocp(tp, PTP_TAI_CFG, tai_cfg);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
hrtimer_forward_now(&tp->pps_timer, 1000000000); //rekick
|
||||||
|
return HRTIMER_RESTART;
|
||||||
|
} else
|
||||||
|
return HRTIMER_NORESTART;
|
||||||
|
}
|
||||||
|
|
||||||
void rtl8126_ptp_reset(struct rtl8126_private *tp)
|
void rtl8126_ptp_reset(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
if (!tp->ptp_clock)
|
if (!tp->ptp_clock)
|
||||||
@ -483,6 +739,11 @@ void rtl8126_ptp_init(struct rtl8126_private *tp)
|
|||||||
/* we have a clock so we can initialize work now */
|
/* we have a clock so we can initialize work now */
|
||||||
INIT_WORK(&tp->ptp_tx_work, rtl8126_ptp_tx_work);
|
INIT_WORK(&tp->ptp_tx_work, rtl8126_ptp_tx_work);
|
||||||
|
|
||||||
|
/* init a hrtimer for pps */
|
||||||
|
tp->pps_enable = 0;
|
||||||
|
hrtimer_init(&tp->pps_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||||
|
tp->pps_timer.function = rtl8126_hrtimer_for_pps;
|
||||||
|
|
||||||
/* reset the PTP related hardware bits */
|
/* reset the PTP related hardware bits */
|
||||||
rtl8126_ptp_reset(tp);
|
rtl8126_ptp_reset(tp);
|
||||||
|
|
||||||
@ -500,6 +761,8 @@ void rtl8126_ptp_suspend(struct rtl8126_private *tp)
|
|||||||
|
|
||||||
/* ensure that we cancel any pending PTP Tx work item in progress */
|
/* ensure that we cancel any pending PTP Tx work item in progress */
|
||||||
cancel_work_sync(&tp->ptp_tx_work);
|
cancel_work_sync(&tp->ptp_tx_work);
|
||||||
|
|
||||||
|
hrtimer_cancel(&tp->pps_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl8126_ptp_stop(struct rtl8126_private *tp)
|
void rtl8126_ptp_stop(struct rtl8126_private *tp)
|
||||||
@ -537,6 +800,7 @@ static int rtl8126_set_tstamp(struct net_device *netdev, struct ifreq *ifr)
|
|||||||
switch (config.tx_type) {
|
switch (config.tx_type) {
|
||||||
case HWTSTAMP_TX_ON:
|
case HWTSTAMP_TX_ON:
|
||||||
hwtstamp = 1;
|
hwtstamp = 1;
|
||||||
|
break;
|
||||||
case HWTSTAMP_TX_OFF:
|
case HWTSTAMP_TX_OFF:
|
||||||
break;
|
break;
|
||||||
case HWTSTAMP_TX_ONESTEP_SYNC:
|
case HWTSTAMP_TX_ONESTEP_SYNC:
|
||||||
@ -556,15 +820,20 @@ static int rtl8126_set_tstamp(struct net_device *netdev, struct ifreq *ifr)
|
|||||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||||
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||||
hwtstamp = 1;
|
hwtstamp = 1;
|
||||||
|
tp->flags |= RTL_FLAG_RX_HWTSTAMP_ENABLED;
|
||||||
|
break;
|
||||||
case HWTSTAMP_FILTER_NONE:
|
case HWTSTAMP_FILTER_NONE:
|
||||||
|
tp->flags &= ~RTL_FLAG_RX_HWTSTAMP_ENABLED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
tp->flags &= ~RTL_FLAG_RX_HWTSTAMP_ENABLED;
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tp->hwtstamp_config.tx_type != config.tx_type ||
|
if (tp->hwtstamp_config.tx_type != config.tx_type ||
|
||||||
tp->hwtstamp_config.rx_filter != config.rx_filter) {
|
tp->hwtstamp_config.rx_filter != config.rx_filter) {
|
||||||
tp->hwtstamp_config = config;
|
tp->hwtstamp_config = config;
|
||||||
|
|
||||||
rtl8126_hwtstamp_enable(tp, hwtstamp);
|
rtl8126_hwtstamp_enable(tp, hwtstamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,15 +874,71 @@ int rtl8126_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl8126_rx_ptp_pktstamp(struct rtl8126_private *tp, struct sk_buff *skb,
|
static void rtl8126_rx_ptp_pktstamp(struct rtl8126_private *tp, struct sk_buff *skb, u8 type)
|
||||||
struct RxDescV3 *descv3)
|
|
||||||
{
|
{
|
||||||
time64_t tv_sec;
|
struct timespec64 ts64;
|
||||||
long tv_nsec;
|
unsigned long flags;
|
||||||
|
|
||||||
tv_sec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampHigh) +
|
spin_lock_irqsave(&tp->phy_lock, flags);
|
||||||
((u64)le32_to_cpu(descv3->RxDescPTPDDWord4.TimeStampHHigh) << 32);
|
|
||||||
tv_nsec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampLow);
|
|
||||||
|
|
||||||
skb_hwtstamps(skb)->hwtstamp = ktime_set(tv_sec, tv_nsec);
|
rtl8126_ptp_ingresstime(tp, &ts64, type);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->phy_lock, flags);
|
||||||
|
|
||||||
|
skb_hwtstamps(skb)->hwtstamp = ktime_set(ts64.tv_sec, ts64.tv_nsec);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtl8126_rx_ptp_timestamp(struct rtl8126_private *tp, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
unsigned int ptp_class;
|
||||||
|
struct ptp_header *hdr;
|
||||||
|
u8 msgtype;
|
||||||
|
|
||||||
|
ptp_class = ptp_classify_raw(skb);
|
||||||
|
if (ptp_class == PTP_CLASS_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
|
hdr = ptp_parse_header(skb, ptp_class);
|
||||||
|
if (unlikely(!hdr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
msgtype = ptp_get_msgtype(hdr, ptp_class);
|
||||||
|
rtl8126_rx_ptp_pktstamp(tp, skb, msgtype);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
|
||||||
|
struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type)
|
||||||
|
{
|
||||||
|
u8 *ptr = skb_mac_header(skb);
|
||||||
|
|
||||||
|
if (type & PTP_CLASS_VLAN)
|
||||||
|
//ptr += VLAN_HLEN;
|
||||||
|
ptr += 4;
|
||||||
|
|
||||||
|
switch (type & PTP_CLASS_PMASK) {
|
||||||
|
case PTP_CLASS_IPV4:
|
||||||
|
ptr += IPV4_HLEN(ptr) + UDP_HLEN;
|
||||||
|
break;
|
||||||
|
case PTP_CLASS_IPV6:
|
||||||
|
ptr += IP6_HLEN + UDP_HLEN;
|
||||||
|
break;
|
||||||
|
case PTP_CLASS_L2:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += ETH_HLEN;
|
||||||
|
|
||||||
|
/* Ensure that the entire header is present in this packet. */
|
||||||
|
if (ptr + sizeof(struct ptp_header) > skb->data + skb->len)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (struct ptp_header *)ptr;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0) */
|
||||||
|
125
src/r8126_ptp.h
125
src/r8126_ptp.h
@ -41,6 +41,23 @@
|
|||||||
#include <linux/ptp_clock_kernel.h>
|
#include <linux/ptp_clock_kernel.h>
|
||||||
#include <linux/ptp_classify.h>
|
#include <linux/ptp_classify.h>
|
||||||
|
|
||||||
|
#ifndef PTP_CLASS_NONE
|
||||||
|
#define PTP_CLASS_NONE 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PTP_MSGTYPE_SYNC
|
||||||
|
#define PTP_MSGTYPE_SYNC 0x0
|
||||||
|
#endif
|
||||||
|
#ifndef PTP_MSGTYPE_DELAY_REQ
|
||||||
|
#define PTP_MSGTYPE_DELAY_REQ 0x1
|
||||||
|
#endif
|
||||||
|
#ifndef PTP_MSGTYPE_PDELAY_REQ
|
||||||
|
#define PTP_MSGTYPE_PDELAY_REQ 0x2
|
||||||
|
#endif
|
||||||
|
#ifndef PTP_MSGTYPE_PDELAY_RESP
|
||||||
|
#define PTP_MSGTYPE_PDELAY_RESP 0x3
|
||||||
|
#endif
|
||||||
|
|
||||||
struct rtl8126_ptp_info {
|
struct rtl8126_ptp_info {
|
||||||
s64 time_sec;
|
s64 time_sec;
|
||||||
u32 time_ns;
|
u32 time_ns;
|
||||||
@ -61,6 +78,109 @@ enum PTP_CMD_TYPE {
|
|||||||
PTP_CMD_LATCHED_LOCAL_TIME,
|
PTP_CMD_LATCHED_LOCAL_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PTP_CLKADJ_MOD_TYPE {
|
||||||
|
NO_FUNCTION = 0,
|
||||||
|
CLKADJ_MODE_SET = 1,
|
||||||
|
RESERVED = 2,
|
||||||
|
DIRECT_READ = 4,
|
||||||
|
DIRECT_WRITE = 6,
|
||||||
|
INCREMENT_STEP = 8,
|
||||||
|
DECREMENT_STEP = 10,
|
||||||
|
RATE_READ = 12,
|
||||||
|
RATE_WRITE = 14,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PTP_INSR_TYPE {
|
||||||
|
EVENT_CAP_INTR = (1 << 0),
|
||||||
|
TRIG_GEN_INTR = (1 << 1),
|
||||||
|
RX_TS_INTR = (1 << 2),
|
||||||
|
TX_TX_INTR = (1 << 3),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PTP_TRX_TS_STA_REG {
|
||||||
|
TRX_TS_RD = (1 << 0),
|
||||||
|
TRXTS_SEL = (1 << 1),
|
||||||
|
RX_TS_PDLYRSP_RDY = (1 << 8),
|
||||||
|
RX_TS_PDLYREQ_RDY = (1 << 9),
|
||||||
|
RX_TS_DLYREQ_RDY = (1 << 10),
|
||||||
|
RX_TS_SYNC_RDY = (1 << 11),
|
||||||
|
TX_TS_PDLYRSP_RDY = (1 << 12),
|
||||||
|
TX_TS_PDLYREQ_RDY = (1 << 13),
|
||||||
|
TX_TS_DLYREQ_RDY = (1 << 14),
|
||||||
|
TX_TS_SYNC_RDY = (1 << 15),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PTP_CTL_TYPE_0 (0xF3F)
|
||||||
|
#define PTP_CTL_TYPE_1 (0x2FF)
|
||||||
|
#define PTP_CTL_TYPE_2 (0x0FF)
|
||||||
|
#define PTP_CTL_TYPE_3 (0x03F)
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)
|
||||||
|
struct clock_identity {
|
||||||
|
u8 id[8];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct port_identity {
|
||||||
|
struct clock_identity clock_identity;
|
||||||
|
__be16 port_number;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ptp_header {
|
||||||
|
u8 tsmt; /* transportSpecific | messageType */
|
||||||
|
u8 ver; /* reserved | versionPTP */
|
||||||
|
__be16 message_length;
|
||||||
|
u8 domain_number;
|
||||||
|
u8 reserved1;
|
||||||
|
u8 flag_field[2];
|
||||||
|
__be64 correction;
|
||||||
|
__be32 reserved2;
|
||||||
|
struct port_identity source_port_identity;
|
||||||
|
__be16 sequence_id;
|
||||||
|
u8 control;
|
||||||
|
u8 log_message_interval;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ptp_parse_header - Get pointer to the PTP v2 header
|
||||||
|
* @skb: packet buffer
|
||||||
|
* @type: type of the packet (see ptp_classify_raw())
|
||||||
|
*
|
||||||
|
* This function takes care of the VLAN, UDP, IPv4 and IPv6 headers. The length
|
||||||
|
* is checked.
|
||||||
|
*
|
||||||
|
* Note, internally skb_mac_header() is used. Make sure that the @skb is
|
||||||
|
* initialized accordingly.
|
||||||
|
*
|
||||||
|
* Return: Pointer to the ptp v2 header or NULL if not found
|
||||||
|
*/
|
||||||
|
struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ptp_get_msgtype - Extract ptp message type from given header
|
||||||
|
* @hdr: ptp header
|
||||||
|
* @type: type of the packet (see ptp_classify_raw())
|
||||||
|
*
|
||||||
|
* This function returns the message type for a given ptp header. It takes care
|
||||||
|
* of the different ptp header versions (v1 or v2).
|
||||||
|
*
|
||||||
|
* Return: The message type
|
||||||
|
*/
|
||||||
|
static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
|
||||||
|
unsigned int type)
|
||||||
|
{
|
||||||
|
u8 msgtype;
|
||||||
|
|
||||||
|
if (unlikely(type & PTP_CLASS_V1)) {
|
||||||
|
/* msg type is located at the control field for ptp v1 */
|
||||||
|
msgtype = hdr->control;
|
||||||
|
} else {
|
||||||
|
msgtype = hdr->tsmt & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0) */
|
||||||
|
|
||||||
struct rtl8126_private;
|
struct rtl8126_private;
|
||||||
struct RxDescV3;
|
struct RxDescV3;
|
||||||
@ -75,7 +195,8 @@ void rtl8126_ptp_stop(struct rtl8126_private *tp);
|
|||||||
|
|
||||||
int rtl8126_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
|
int rtl8126_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
|
||||||
|
|
||||||
void rtl8126_rx_ptp_pktstamp(struct rtl8126_private *tp, struct sk_buff *skb,
|
void rtl8126_rx_ptp_timestamp(struct rtl8126_private *tp, struct sk_buff *skb);
|
||||||
struct RxDescV3 *descv3);
|
|
||||||
|
void rtl8126_set_local_time(struct rtl8126_private *tp);
|
||||||
|
|
||||||
#endif /* _LINUX_R8126_PTP_H */
|
#endif /* _LINUX_R8126_PTP_H */
|
||||||
|
172
src/r8126_rss.c
172
src/r8126_rss.c
@ -91,8 +91,6 @@ int rtl8126_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
|||||||
struct rtl8126_private *tp = netdev_priv(dev);
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
int ret = -EOPNOTSUPP;
|
int ret = -EOPNOTSUPP;
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss get rxnfc\n");
|
|
||||||
|
|
||||||
if (!(dev->features & NETIF_F_RXHASH))
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -159,8 +157,6 @@ static int rtl8126_set_rss_hash_opt(struct rtl8126_private *tp,
|
|||||||
{
|
{
|
||||||
u32 rss_flags = tp->rss_flags;
|
u32 rss_flags = tp->rss_flags;
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss set hash\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RSS does not support anything other than hashing
|
* RSS does not support anything other than hashing
|
||||||
* to queues on src and dst IPs and ports
|
* to queues on src and dst IPs and ports
|
||||||
@ -271,8 +267,6 @@ int rtl8126_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
|
|||||||
struct rtl8126_private *tp = netdev_priv(dev);
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
int ret = -EOPNOTSUPP;
|
int ret = -EOPNOTSUPP;
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss set rxnfc\n");
|
|
||||||
|
|
||||||
if (!(dev->features & NETIF_F_RXHASH))
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -296,8 +290,6 @@ u32 rtl8126_get_rxfh_key_size(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct rtl8126_private *tp = netdev_priv(dev);
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss get key size\n");
|
|
||||||
|
|
||||||
if (!(dev->features & NETIF_F_RXHASH))
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -308,8 +300,6 @@ u32 rtl8126_rss_indir_size(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct rtl8126_private *tp = netdev_priv(dev);
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss get indir tbl size\n");
|
|
||||||
|
|
||||||
if (!(dev->features & NETIF_F_RXHASH))
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -324,28 +314,6 @@ static void rtl8126_get_reta(struct rtl8126_private *tp, u32 *indir)
|
|||||||
indir[i] = tp->rss_indir_tbl[i];
|
indir[i] = tp->rss_indir_tbl[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtl8126_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
|
|
||||||
u8 *hfunc)
|
|
||||||
{
|
|
||||||
struct rtl8126_private *tp = netdev_priv(dev);
|
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss get rxfh\n");
|
|
||||||
|
|
||||||
if (!(dev->features & NETIF_F_RXHASH))
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
if (hfunc)
|
|
||||||
*hfunc = ETH_RSS_HASH_TOP;
|
|
||||||
|
|
||||||
if (indir)
|
|
||||||
rtl8126_get_reta(tp, indir);
|
|
||||||
|
|
||||||
if (key)
|
|
||||||
memcpy(key, tp->rss_key, RTL8126_RSS_KEY_SIZE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 rtl8126_rss_key_reg(struct rtl8126_private *tp)
|
static u32 rtl8126_rss_key_reg(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
return RSS_KEY_8125;
|
return RSS_KEY_8125;
|
||||||
@ -386,6 +354,82 @@ static void rtl8126_store_rss_key(struct rtl8126_private *tp)
|
|||||||
RTL_W32(tp, rss_key_reg + i, *rss_key++);
|
RTL_W32(tp, rss_key_reg + i, *rss_key++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
|
||||||
|
int rtl8126_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh)
|
||||||
|
{
|
||||||
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
|
|
||||||
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
rxfh->hfunc = ETH_RSS_HASH_TOP;
|
||||||
|
|
||||||
|
if (rxfh->indir)
|
||||||
|
rtl8126_get_reta(tp, rxfh->indir);
|
||||||
|
|
||||||
|
if (rxfh->key)
|
||||||
|
memcpy(rxfh->key, tp->rss_key, RTL8126_RSS_KEY_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8126_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
|
int i;
|
||||||
|
u32 reta_entries = rtl8126_rss_indir_tbl_entries(tp);
|
||||||
|
|
||||||
|
/* We require at least one supported parameter to be changed and no
|
||||||
|
* change in any of the unsupported parameters
|
||||||
|
*/
|
||||||
|
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* Fill out the redirection table */
|
||||||
|
if (rxfh->indir) {
|
||||||
|
int max_queues = tp->num_rx_rings;
|
||||||
|
|
||||||
|
/* Verify user input. */
|
||||||
|
for (i = 0; i < reta_entries; i++)
|
||||||
|
if (rxfh->indir[i] >= max_queues)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < reta_entries; i++)
|
||||||
|
tp->rss_indir_tbl[i] = rxfh->indir[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the rss hash key */
|
||||||
|
if (rxfh->key)
|
||||||
|
memcpy(tp->rss_key, rxfh->key, RTL8126_RSS_KEY_SIZE);
|
||||||
|
|
||||||
|
rtl8126_store_reta(tp);
|
||||||
|
|
||||||
|
rtl8126_store_rss_key(tp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int rtl8126_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
|
||||||
|
u8 *hfunc)
|
||||||
|
{
|
||||||
|
struct rtl8126_private *tp = netdev_priv(dev);
|
||||||
|
|
||||||
|
if (!(dev->features & NETIF_F_RXHASH))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (hfunc)
|
||||||
|
*hfunc = ETH_RSS_HASH_TOP;
|
||||||
|
|
||||||
|
if (indir)
|
||||||
|
rtl8126_get_reta(tp, indir);
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
memcpy(key, tp->rss_key, RTL8126_RSS_KEY_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int rtl8126_set_rxfh(struct net_device *dev, const u32 *indir,
|
int rtl8126_set_rxfh(struct net_device *dev, const u32 *indir,
|
||||||
const u8 *key, const u8 hfunc)
|
const u8 *key, const u8 hfunc)
|
||||||
{
|
{
|
||||||
@ -393,8 +437,6 @@ int rtl8126_set_rxfh(struct net_device *dev, const u32 *indir,
|
|||||||
int i;
|
int i;
|
||||||
u32 reta_entries = rtl8126_rss_indir_tbl_entries(tp);
|
u32 reta_entries = rtl8126_rss_indir_tbl_entries(tp);
|
||||||
|
|
||||||
netif_info(tp, drv, tp->dev, "rss set rxfh\n");
|
|
||||||
|
|
||||||
/* We require at least one supported parameter to be changed and no
|
/* We require at least one supported parameter to be changed and no
|
||||||
* change in any of the unsupported parameters
|
* change in any of the unsupported parameters
|
||||||
*/
|
*/
|
||||||
@ -424,11 +466,19 @@ int rtl8126_set_rxfh(struct net_device *dev, const u32 *indir,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
|
||||||
|
|
||||||
static u32 rtl8126_get_rx_desc_hash(struct rtl8126_private *tp,
|
static u32 rtl8126_get_rx_desc_hash(struct rtl8126_private *tp,
|
||||||
struct RxDescV3 *descv3)
|
struct RxDesc *desc)
|
||||||
{
|
{
|
||||||
return le32_to_cpu(descv3->RxDescNormalDDWord2.RSSResult);
|
switch (tp->InitRxDescType) {
|
||||||
|
case RX_DESC_RING_TYPE_3:
|
||||||
|
return le32_to_cpu(((struct RxDescV3 *)desc)->RxDescNormalDDWord2.RSSResult);
|
||||||
|
case RX_DESC_RING_TYPE_4:
|
||||||
|
return le32_to_cpu(((struct RxDescV4 *)desc)->RxDescNormalDDWord1.RSSResult);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RXS_8125B_RSS_UDP BIT(9)
|
#define RXS_8125B_RSS_UDP BIT(9)
|
||||||
@ -437,9 +487,16 @@ static u32 rtl8126_get_rx_desc_hash(struct rtl8126_private *tp,
|
|||||||
#define RXS_8125_RSS_TCP BIT(13)
|
#define RXS_8125_RSS_TCP BIT(13)
|
||||||
#define RTL8126_RXS_RSS_L3_TYPE_MASK (RXS_8125_RSS_IPV4 | RXS_8125_RSS_IPV6)
|
#define RTL8126_RXS_RSS_L3_TYPE_MASK (RXS_8125_RSS_IPV4 | RXS_8125_RSS_IPV6)
|
||||||
#define RTL8126_RXS_RSS_L4_TYPE_MASK (RXS_8125_RSS_TCP | RXS_8125B_RSS_UDP)
|
#define RTL8126_RXS_RSS_L4_TYPE_MASK (RXS_8125_RSS_TCP | RXS_8125B_RSS_UDP)
|
||||||
void rtl8126_rx_hash(struct rtl8126_private *tp,
|
|
||||||
struct RxDescV3 *descv3,
|
#define RXS_8125B_RSS_UDP_V4 BIT(27)
|
||||||
struct sk_buff *skb)
|
#define RXS_8125_RSS_IPV4_V4 BIT(28)
|
||||||
|
#define RXS_8125_RSS_IPV6_V4 BIT(29)
|
||||||
|
#define RXS_8125_RSS_TCP_V4 BIT(30)
|
||||||
|
#define RTL8126_RXS_RSS_L3_TYPE_MASK_V4 (RXS_8125_RSS_IPV4_V4 | RXS_8125_RSS_IPV6_V4)
|
||||||
|
#define RTL8126_RXS_RSS_L4_TYPE_MASK_V4 (RXS_8125_RSS_TCP_V4 | RXS_8125B_RSS_UDP_V4)
|
||||||
|
static void rtl8126_rx_hash_v3(struct rtl8126_private *tp,
|
||||||
|
struct RxDescV3 *descv3,
|
||||||
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
u16 rss_header_info;
|
u16 rss_header_info;
|
||||||
|
|
||||||
@ -451,11 +508,46 @@ void rtl8126_rx_hash(struct rtl8126_private *tp,
|
|||||||
if (!(rss_header_info & RTL8126_RXS_RSS_L3_TYPE_MASK))
|
if (!(rss_header_info & RTL8126_RXS_RSS_L3_TYPE_MASK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
skb_set_hash(skb, rtl8126_get_rx_desc_hash(tp, descv3),
|
skb_set_hash(skb, rtl8126_get_rx_desc_hash(tp, (struct RxDesc *)descv3),
|
||||||
(RTL8126_RXS_RSS_L4_TYPE_MASK & rss_header_info) ?
|
(RTL8126_RXS_RSS_L4_TYPE_MASK & rss_header_info) ?
|
||||||
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
|
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8126_rx_hash_v4(struct rtl8126_private *tp,
|
||||||
|
struct RxDescV4 *descv4,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u32 rss_header_info;
|
||||||
|
|
||||||
|
if (!(tp->dev->features & NETIF_F_RXHASH))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rss_header_info = le32_to_cpu(descv4->RxDescNormalDDWord1.RSSInfo);
|
||||||
|
|
||||||
|
if (!(rss_header_info & RTL8126_RXS_RSS_L3_TYPE_MASK_V4))
|
||||||
|
return;
|
||||||
|
|
||||||
|
skb_set_hash(skb, rtl8126_get_rx_desc_hash(tp, (struct RxDesc *)descv4),
|
||||||
|
(RTL8126_RXS_RSS_L4_TYPE_MASK_V4 & rss_header_info) ?
|
||||||
|
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtl8126_rx_hash(struct rtl8126_private *tp,
|
||||||
|
struct RxDesc *desc,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
switch (tp->InitRxDescType) {
|
||||||
|
case RX_DESC_RING_TYPE_3:
|
||||||
|
rtl8126_rx_hash_v3(tp, (struct RxDescV3 *)desc, skb);
|
||||||
|
break;
|
||||||
|
case RX_DESC_RING_TYPE_4:
|
||||||
|
rtl8126_rx_hash_v4(tp, (struct RxDescV4 *)desc, skb);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rtl8126_disable_rss(struct rtl8126_private *tp)
|
void rtl8126_disable_rss(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
RTL_W32(tp, RSS_CTRL_8125, 0x00);
|
RTL_W32(tp, RSS_CTRL_8125, 0x00);
|
||||||
|
@ -47,18 +47,25 @@ enum rtl8126_rss_flag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rtl8126_private;
|
struct rtl8126_private;
|
||||||
|
struct RxDesc;
|
||||||
|
|
||||||
int rtl8126_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
int rtl8126_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||||
u32 *rule_locs);
|
u32 *rule_locs);
|
||||||
int rtl8126_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
|
int rtl8126_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
|
||||||
u32 rtl8126_get_rxfh_key_size(struct net_device *netdev);
|
u32 rtl8126_get_rxfh_key_size(struct net_device *netdev);
|
||||||
u32 rtl8126_rss_indir_size(struct net_device *netdev);
|
u32 rtl8126_rss_indir_size(struct net_device *netdev);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
|
||||||
|
int rtl8126_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh);
|
||||||
|
int rtl8126_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
|
||||||
|
struct netlink_ext_ack *extack);
|
||||||
|
#else
|
||||||
int rtl8126_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
|
int rtl8126_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
|
||||||
u8 *hfunc);
|
u8 *hfunc);
|
||||||
int rtl8126_set_rxfh(struct net_device *netdev, const u32 *indir,
|
int rtl8126_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||||
const u8 *key, const u8 hfunc);
|
const u8 *key, const u8 hfunc);
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
|
||||||
void rtl8126_rx_hash(struct rtl8126_private *tp,
|
void rtl8126_rx_hash(struct rtl8126_private *tp,
|
||||||
struct RxDescV3 *descv3,
|
struct RxDesc *desc,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
void _rtl8126_config_rss(struct rtl8126_private *tp);
|
void _rtl8126_config_rss(struct rtl8126_private *tp);
|
||||||
void rtl8126_config_rss(struct rtl8126_private *tp);
|
void rtl8126_config_rss(struct rtl8126_private *tp);
|
||||||
|
@ -93,7 +93,7 @@ void rtl8126_eeprom_cleanup(struct rtl8126_private *tp)
|
|||||||
rtl8126_lower_clock(tp, &x);
|
rtl8126_lower_clock(tp, &x);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtl8126_eeprom_cmd_done(struct rtl8126_private *tp)
|
static int rtl8126_eeprom_cmd_done(struct rtl8126_private *tp)
|
||||||
{
|
{
|
||||||
u8 x;
|
u8 x;
|
||||||
int i;
|
int i;
|
||||||
@ -123,9 +123,8 @@ u16 rtl8126_eeprom_read_sc(struct rtl8126_private *tp, u16 reg)
|
|||||||
u8 x;
|
u8 x;
|
||||||
u16 data;
|
u16 data;
|
||||||
|
|
||||||
if(tp->eeprom_type == EEPROM_TYPE_NONE) {
|
if(tp->eeprom_type == EEPROM_TYPE_NONE)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->eeprom_type==EEPROM_TYPE_93C46)
|
if (tp->eeprom_type==EEPROM_TYPE_93C46)
|
||||||
addr_sz = 6;
|
addr_sz = 6;
|
||||||
@ -157,9 +156,8 @@ void rtl8126_eeprom_write_sc(struct rtl8126_private *tp, u16 reg, u16 data)
|
|||||||
int addr_sz = 6;
|
int addr_sz = 6;
|
||||||
int w_dummy_addr = 4;
|
int w_dummy_addr = 4;
|
||||||
|
|
||||||
if(tp->eeprom_type == EEPROM_TYPE_NONE) {
|
if(tp->eeprom_type == EEPROM_TYPE_NONE)
|
||||||
return ;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->eeprom_type==EEPROM_TYPE_93C46) {
|
if (tp->eeprom_type==EEPROM_TYPE_93C46) {
|
||||||
addr_sz = 6;
|
addr_sz = 6;
|
||||||
@ -178,17 +176,15 @@ void rtl8126_eeprom_write_sc(struct rtl8126_private *tp, u16 reg, u16 data)
|
|||||||
|
|
||||||
rtl8126_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3);
|
rtl8126_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3);
|
||||||
rtl8126_shift_out_bits(tp, reg, addr_sz);
|
rtl8126_shift_out_bits(tp, reg, addr_sz);
|
||||||
if (rtl8126_eeprom_cmd_done(tp) < 0) {
|
if (rtl8126_eeprom_cmd_done(tp) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
rtl8126_stand_by(tp);
|
rtl8126_stand_by(tp);
|
||||||
|
|
||||||
rtl8126_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3);
|
rtl8126_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3);
|
||||||
rtl8126_shift_out_bits(tp, reg, addr_sz);
|
rtl8126_shift_out_bits(tp, reg, addr_sz);
|
||||||
rtl8126_shift_out_bits(tp, data, 16);
|
rtl8126_shift_out_bits(tp, data, 16);
|
||||||
if (rtl8126_eeprom_cmd_done(tp) < 0) {
|
if (rtl8126_eeprom_cmd_done(tp) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
rtl8126_stand_by(tp);
|
rtl8126_stand_by(tp);
|
||||||
|
|
||||||
rtl8126_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5);
|
rtl8126_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5);
|
||||||
|
@ -251,6 +251,31 @@ int rtl8126_tool_ioctl(struct rtl8126_private *tp, struct ifreq *ifr)
|
|||||||
rtl8126_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data);
|
rtl8126_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef ENABLE_FIBER_SUPPORT
|
||||||
|
case RTL_READ_FIBER_PHY:
|
||||||
|
if (!HW_FIBER_STATUS_CONNECTED(tp)) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_cmd.data = rtl8126_fiber_mdio_read(tp, my_cmd.offset);
|
||||||
|
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTL_WRITE_FIBER_PHY:
|
||||||
|
if (!HW_FIBER_STATUS_CONNECTED(tp)) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtl8126_fiber_mdio_write(tp, my_cmd.offset, my_cmd.data);
|
||||||
|
break;
|
||||||
|
#endif /* ENABLE_FIBER_SUPPORT */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
break;
|
break;
|
||||||
|
@ -63,6 +63,9 @@ enum rtl_cmd {
|
|||||||
RTL_DIRECT_READ_PHY_OCP,
|
RTL_DIRECT_READ_PHY_OCP,
|
||||||
RTL_DIRECT_WRITE_PHY_OCP,
|
RTL_DIRECT_WRITE_PHY_OCP,
|
||||||
|
|
||||||
|
RTL_READ_FIBER_PHY,
|
||||||
|
RTL_WRITE_FIBER_PHY,
|
||||||
|
|
||||||
RTLTOOL_INVALID
|
RTLTOOL_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user