Merge branch 'realtek_5.10_5.15' into 'stable-1.5'

Add Realtek for 5.10, 5.14, 5.15 and 6.1

See merge request etherlab.org/ethercat!78
This commit is contained in:
Florian Pose 2024-01-24 09:45:35 +00:00
commit 0ce07b1fdb
45 changed files with 57516 additions and 1 deletions

View File

@ -614,16 +614,25 @@ if test "x${enable_r8169}" = "x1"; then
AC_MSG_CHECKING([for kernel for r8169 driver])
kernels=`ls -1 ${srcdir}/devices/ | grep -oE "^r8169-.*-" | cut -d "-" -f 2 | uniq`
kernels_subdir=`ls -1 ${srcdir}/devices/r8169/ | grep -oE "^r8169_main-.*-" | cut -d "-" -f 2 | uniq`
found=0
found_subdir=0
for k in $kernels; do
if test "$kernel_r8169" = "$k"; then
found=1
fi
done
for k in $kernels_subdir; do
if test "$kernel_r8169" = "$k"; then
found=1
found_subdir=1
fi
done
if test $found -ne 1; then
AC_MSG_ERROR([kernel $kernel_r8169 not available for r8169 driver!])
fi
AC_SUBST(R8169_IN_SUBDIR, [$found_subdir])
AC_MSG_RESULT([$kernel_r8169])
fi
@ -1222,6 +1231,8 @@ AC_CONFIG_FILES([
devices/igb/Makefile
devices/igc/Kbuild
devices/igc/Makefile
devices/r8169/Kbuild
devices/r8169/Makefile
ethercat.spec
examples/Kbuild
examples/Makefile

View File

@ -83,11 +83,15 @@ ifeq (@ENABLE_IGC@,1)
endif
ifeq (@ENABLE_R8169@,1)
ifeq (@R8169_IN_SUBDIR@,1)
obj-m += r8169/
else
EC_R8169_OBJ := r8169-@KERNEL_R8169@-ethercat.o
obj-m += ec_r8169.o
ec_r8169-objs := $(EC_R8169_OBJ)
CFLAGS_$(EC_R8169_OBJ) = -DREV=$(REV)
endif
endif
KBUILD_EXTRA_SYMBOLS := \
@abs_top_builddir@/$(LINUX_SYMVERS) \

View File

@ -33,7 +33,8 @@ SUBDIRS = \
e1000e \
genet \
igb \
igc
igc \
r8169
# using HEADERS to enable tags target
noinst_HEADERS = \

59
devices/r8169/Kbuild.in Normal file
View File

@ -0,0 +1,59 @@
#------------------------------------------------------------------------------
#
# $Id$
#
# Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT Master.
#
# The IgH EtherCAT Master is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2, as
# published by the Free Software Foundation.
#
# The IgH EtherCAT Master is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with the IgH EtherCAT Master; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ---
#
# The license mentioned above concerns the source code only. Using the
# EtherCAT technology and brand is only permitted in compliance with the
# industrial property and similar rights of Beckhoff Automation GmbH.
#
# ---
#
# vim: syntax=make
#
#------------------------------------------------------------------------------
TOPDIR := $(src)/../..
REV := $(shell if test -s $(TOPDIR)/revision; then \
cat $(TOPDIR)/revision; \
else \
git -C $(TOPDIR) describe 2>/dev/null || echo "unknown"; \
fi)
ifeq (@ENABLE_R8169@,1)
ifeq (@R8169_IN_SUBDIR@,1)
obj-m += ec_r8169.o
ec_r8169-objs := \
r8169_firmware-@KERNEL_R8169@-ethercat.o \
r8169_main-@KERNEL_R8169@-ethercat.o \
r8169_phy_config-@KERNEL_R8169@-ethercat.o
CFLAGS_r8169_main-@KERNEL_R8169@-ethercat.o = -DREV=$(REV)
endif
endif
KBUILD_EXTRA_SYMBOLS := \
@abs_top_builddir@/$(LINUX_SYMVERS) \
@abs_top_builddir@/master/$(LINUX_SYMVERS)

70
devices/r8169/Makefile.am Normal file
View File

@ -0,0 +1,70 @@
#------------------------------------------------------------------------------
#
# Copyright (C) 2006-2021 Florian Pose, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT Master.
#
# The IgH EtherCAT Master is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2, as
# published by the Free Software Foundation.
#
# The IgH EtherCAT Master is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with the IgH EtherCAT Master; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ---
#
# The license mentioned above concerns the source code only. Using the
# EtherCAT technology and brand is only permitted in compliance with the
# industrial property and similar rights of Beckhoff Automation GmbH.
#
#------------------------------------------------------------------------------
include $(top_srcdir)/Makefile.kbuild
EXTRA_DIST = \
r8169-5.10-ethercat.h \
r8169-5.10-orig.h \
r8169-5.14-ethercat.h \
r8169-5.14-orig.h \
r8169-5.15-ethercat.h \
r8169-5.15-orig.h \
r8169-6.1-ethercat.h \
r8169-6.1-orig.h \
r8169_firmware-5.10-ethercat.c \
r8169_firmware-5.10-ethercat.h \
r8169_firmware-5.10-orig.c \
r8169_firmware-5.10-orig.h \
r8169_firmware-5.14-ethercat.c \
r8169_firmware-5.14-ethercat.h \
r8169_firmware-5.14-orig.c \
r8169_firmware-5.14-orig.h \
r8169_firmware-5.15-ethercat.c \
r8169_firmware-5.15-ethercat.h \
r8169_firmware-5.15-orig.c \
r8169_firmware-5.15-orig.h \
r8169_firmware-6.1-ethercat.c \
r8169_firmware-6.1-ethercat.h \
r8169_firmware-6.1-orig.c \
r8169_firmware-6.1-orig.h \
r8169_main-5.10-ethercat.c \
r8169_main-5.10-orig.c \
r8169_main-5.14-ethercat.c \
r8169_main-5.14-orig.c \
r8169_main-5.15-ethercat.c \
r8169_main-5.15-orig.c \
r8169_main-6.1-ethercat.c \
r8169_main-6.1-orig.c \
r8169_phy_config-5.10-ethercat.c \
r8169_phy_config-5.10-orig.c \
r8169_phy_config-5.14-ethercat.c \
r8169_phy_config-5.14-orig.c \
r8169_phy_config-5.15-ethercat.c \
r8169_phy_config-5.15-orig.c \
r8169_phy_config-6.1-ethercat.c \
r8169_phy_config-6.1-orig.c

View File

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
RTL_GIGA_MAC_VER_12,
RTL_GIGA_MAC_VER_13,
RTL_GIGA_MAC_VER_14,
RTL_GIGA_MAC_VER_16,
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
RTL_GIGA_MAC_VER_27,
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_VER_49,
RTL_GIGA_MAC_VER_50,
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
RTL_GIGA_MAC_VER_60,
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
/* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */
/* RTL_GIGA_MAC_VER_13 was merged with VER_10 */
RTL_GIGA_MAC_VER_14,
/* RTL_GIGA_MAC_VER_16 was merged with VER_10 */
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
/* support for RTL_GIGA_MAC_VER_27 has been removed */
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
/* support for RTL_GIGA_MAC_VER_41 has been removed */
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
/* support for RTL_GIGA_MAC_VER_45 has been removed */
RTL_GIGA_MAC_VER_46,
/* support for RTL_GIGA_MAC_VER_47 has been removed */
RTL_GIGA_MAC_VER_48,
/* support for RTL_GIGA_MAC_VER_49 has been removed */
/* support for RTL_GIGA_MAC_VER_50 has been removed */
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
/* support for RTL_GIGA_MAC_VER_60 has been removed */
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/types.h>
#include <linux/phy.h>
enum mac_version {
/* support for ancient RTL_GIGA_MAC_VER_01 has been removed */
RTL_GIGA_MAC_VER_02,
RTL_GIGA_MAC_VER_03,
RTL_GIGA_MAC_VER_04,
RTL_GIGA_MAC_VER_05,
RTL_GIGA_MAC_VER_06,
RTL_GIGA_MAC_VER_07,
RTL_GIGA_MAC_VER_08,
RTL_GIGA_MAC_VER_09,
RTL_GIGA_MAC_VER_10,
RTL_GIGA_MAC_VER_11,
/* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */
/* RTL_GIGA_MAC_VER_13 was merged with VER_10 */
RTL_GIGA_MAC_VER_14,
/* RTL_GIGA_MAC_VER_16 was merged with VER_10 */
RTL_GIGA_MAC_VER_17,
RTL_GIGA_MAC_VER_18,
RTL_GIGA_MAC_VER_19,
RTL_GIGA_MAC_VER_20,
RTL_GIGA_MAC_VER_21,
RTL_GIGA_MAC_VER_22,
RTL_GIGA_MAC_VER_23,
RTL_GIGA_MAC_VER_24,
RTL_GIGA_MAC_VER_25,
RTL_GIGA_MAC_VER_26,
/* support for RTL_GIGA_MAC_VER_27 has been removed */
RTL_GIGA_MAC_VER_28,
RTL_GIGA_MAC_VER_29,
RTL_GIGA_MAC_VER_30,
RTL_GIGA_MAC_VER_31,
RTL_GIGA_MAC_VER_32,
RTL_GIGA_MAC_VER_33,
RTL_GIGA_MAC_VER_34,
RTL_GIGA_MAC_VER_35,
RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
/* support for RTL_GIGA_MAC_VER_41 has been removed */
RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44,
/* support for RTL_GIGA_MAC_VER_45 has been removed */
RTL_GIGA_MAC_VER_46,
/* support for RTL_GIGA_MAC_VER_47 has been removed */
RTL_GIGA_MAC_VER_48,
/* support for RTL_GIGA_MAC_VER_49 has been removed */
/* support for RTL_GIGA_MAC_VER_50 has been removed */
RTL_GIGA_MAC_VER_51,
RTL_GIGA_MAC_VER_52,
RTL_GIGA_MAC_VER_53,
/* support for RTL_GIGA_MAC_VER_60 has been removed */
RTL_GIGA_MAC_VER_61,
RTL_GIGA_MAC_VER_63,
RTL_GIGA_MAC_NONE
};
struct rtl8169_private;
void r8169_apply_firmware(struct rtl8169_private *tp);
u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
enum mac_version ver);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware-5.10-ethercat.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware-5.14-ethercat.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware-5.15-ethercat.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware-6.1-ethercat.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

View File

@ -0,0 +1,236 @@
// SPDX-License-Identifier: GPL-2.0-only
/* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/delay.h>
#include <linux/firmware.h>
#include "r8169_firmware.h"
enum rtl_fw_opcode {
PHY_READ = 0x0,
PHY_DATA_OR = 0x1,
PHY_DATA_AND = 0x2,
PHY_BJMPN = 0x3,
PHY_MDIO_CHG = 0x4,
PHY_CLEAR_READCOUNT = 0x7,
PHY_WRITE = 0x8,
PHY_READCOUNT_EQ_SKIP = 0x9,
PHY_COMP_EQ_SKIPN = 0xa,
PHY_COMP_NEQ_SKIPN = 0xb,
PHY_WRITE_PREVIOUS = 0xc,
PHY_SKIPN = 0xd,
PHY_DELAY_MS = 0xe,
};
struct fw_info {
u32 magic;
char version[RTL_VER_SIZE];
__le32 fw_start;
__le32 fw_len;
u8 chksum;
} __packed;
#define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
{
const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
if (fw->size < FW_OPCODE_SIZE)
return false;
if (!fw_info->magic) {
size_t i, size, start;
u8 checksum = 0;
if (fw->size < sizeof(*fw_info))
return false;
for (i = 0; i < fw->size; i++)
checksum += fw->data[i];
if (checksum != 0)
return false;
start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size)
return false;
size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
pa->code = (__le32 *)(fw->data + start);
pa->size = size;
} else {
if (fw->size % FW_OPCODE_SIZE)
return false;
strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
pa->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE;
}
return true;
}
static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 val = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
switch (action >> 28) {
case PHY_READ:
case PHY_DATA_OR:
case PHY_DATA_AND:
case PHY_CLEAR_READCOUNT:
case PHY_WRITE:
case PHY_WRITE_PREVIOUS:
case PHY_DELAY_MS:
break;
case PHY_MDIO_CHG:
if (val > 1)
goto out;
break;
case PHY_BJMPN:
if (regno > index)
goto out;
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size)
goto out;
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size)
goto out;
break;
default:
dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
return false;
}
}
return true;
out:
dev_err(rtl_fw->dev, "Out of range of firmware\n");
return false;
}
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
rtl_fw_write_t fw_write = rtl_fw->phy_write;
rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index;
for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
enum rtl_fw_opcode opcode = action >> 28;
if (!action)
break;
switch (opcode) {
case PHY_READ:
predata = fw_read(tp, regno);
count++;
break;
case PHY_DATA_OR:
predata |= data;
break;
case PHY_DATA_AND:
predata &= data;
break;
case PHY_BJMPN:
index -= (regno + 1);
break;
case PHY_MDIO_CHG:
if (data) {
fw_write = rtl_fw->mac_mcu_write;
fw_read = rtl_fw->mac_mcu_read;
} else {
fw_write = rtl_fw->phy_write;
fw_read = rtl_fw->phy_read;
}
break;
case PHY_CLEAR_READCOUNT:
count = 0;
break;
case PHY_WRITE:
fw_write(tp, regno, data);
break;
case PHY_READCOUNT_EQ_SKIP:
if (count == data)
index++;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
index += regno;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
index += regno;
break;
case PHY_WRITE_PREVIOUS:
fw_write(tp, regno, predata);
break;
case PHY_SKIPN:
index += regno;
break;
case PHY_DELAY_MS:
msleep(data);
break;
}
}
}
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
{
release_firmware(rtl_fw->fw);
}
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
{
int rc;
rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
if (rc < 0)
goto out;
if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
release_firmware(rtl_fw->fw);
rc = -EINVAL;
goto out;
}
return 0;
out:
dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
rtl_fw->fw_name, rc);
return rc;
}

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* r8169_firmware.h: RealTek 8169/8168/8101 ethernet driver.
*
* Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* Copyright (c) a lot of people too. Please respect their work.
*
* See MAINTAINERS file for support contact information.
*/
#include <linux/device.h>
#include <linux/firmware.h>
struct rtl8169_private;
typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val);
typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg);
#define RTL_VER_SIZE 32
struct rtl_fw {
rtl_fw_write_t phy_write;
rtl_fw_read_t phy_read;
rtl_fw_write_t mac_mcu_write;
rtl_fw_read_t mac_mcu_read;
const struct firmware *fw;
const char *fw_name;
struct device *dev;
char version[RTL_VER_SIZE];
struct rtl_fw_phy_action {
__le32 *code;
size_t size;
} phy_action;
};
int rtl_fw_request_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_release_firmware(struct rtl_fw *rtl_fw);
void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff